Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
24e31a69
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
24e31a69
编写于
9月 20, 2016
作者:
baltery
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
finish asset
上级
d323c9df
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
180 addition
and
77 deletion
+180
-77
apps/assets/forms.py
apps/assets/forms.py
+10
-8
apps/assets/models.py
apps/assets/models.py
+21
-13
apps/assets/templates/assets/asset_create.html
apps/assets/templates/assets/asset_create.html
+0
-0
apps/assets/templates/assets/asset_detail.html
apps/assets/templates/assets/asset_detail.html
+27
-43
apps/assets/templates/assets/asset_list.html
apps/assets/templates/assets/asset_list.html
+4
-4
apps/assets/templates/assets/asset_update.html
apps/assets/templates/assets/asset_update.html
+81
-0
apps/assets/views.py
apps/assets/views.py
+37
-9
未找到文件。
apps/assets/forms.py
浏览文件 @
24e31a69
...
...
@@ -24,16 +24,16 @@ from django.utils.translation import gettext_lazy as _
class
AssetCreateForm
(
forms
.
ModelForm
):
tags
=
forms
.
CharField
(
label
=
_
(
'Tags'
),
widget
=
forms
.
TextInput
(
attrs
=
{
'id'
:
'tags'
}),
help_text
=
'Use `,` split'
)
required
=
False
,
help_text
=
'Use `,` split'
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
instance
=
kwargs
.
get
(
'instance'
)
instance
=
kwargs
.
get
(
'instance'
,
None
)
if
instance
:
initial
=
kwargs
.
get
(
'initial'
,
{})
tags
=
Tag
.
objects
.
filter
(
asset
=
instance
)
tags_value
=
','
.
join
([
tag
.
value
for
tag
in
tags
])
initial
[
'tags'
]
=
tags_value
tags
=
instance
.
tags
.
all
(
)
initial
[
'tags'
]
=
","
.
join
([
tag
.
value
for
tag
in
tags
])
print
(
kwargs
.
get
(
'initial'
))
super
(
AssetCreateForm
,
self
).
__init__
(
*
args
,
**
kwargs
)
def
_save_m2m
(
self
):
...
...
@@ -43,14 +43,16 @@ class AssetCreateForm(forms.ModelForm):
value_list
=
tags
.
split
(
','
)
self
.
instance
.
tags
.
all
().
delete
()
Tag
.
objects
.
bulk_create
(
[
Tag
(
value
=
value
)
for
value
in
value_list
]
[
Tag
(
value
=
value
,
asset
=
self
.
instance
)
for
value
in
value_list
]
)
class
Meta
:
model
=
Asset
fields
=
[
'hostname'
,
'ip'
,
'port'
,
'type'
,
'comment'
,
'admin_user'
,
'system_users'
,
'idc'
,
'groups'
'hostname'
,
'ip'
,
'port'
,
'type'
,
'comment'
,
'admin_user'
,
'system_users'
,
'idc'
,
'groups'
,
'other_ip'
,
'remote_card_ip'
,
'mac_address'
,
'brand'
,
'cpu'
,
'memory'
,
'disk'
,
'os'
,
'cabinet_no'
,
'cabinet_pos'
,
'number'
,
'status'
,
'env'
,
'sn'
,
]
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
...
...
@@ -75,7 +77,7 @@ class AssetGroupForm(forms.ModelForm):
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
if
kwargs
.
get
(
'instance'
):
if
kwargs
.
get
(
'instance'
,
None
):
initial
=
kwargs
.
get
(
'initial'
,
{})
initial
[
'assets'
]
=
kwargs
[
'instance'
].
assets
.
all
()
super
(
AssetGroupForm
,
self
).
__init__
(
*
args
,
**
kwargs
)
...
...
apps/assets/models.py
浏览文件 @
24e31a69
...
...
@@ -277,7 +277,10 @@ class AssetGroup(models.Model):
def
get_default_extend
(
key
,
value
):
return
AssetExtend
.
objects
.
get_or_create
(
key
=
key
,
value
=
value
)[
0
]
try
:
return
AssetExtend
.
objects
.
get_or_create
(
key
=
key
,
value
=
value
)[
0
]
except
:
return
None
def
get_default_idc
():
...
...
@@ -295,8 +298,8 @@ class Asset(models.Model):
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
"Admin user"
))
system_users
=
models
.
ManyToManyField
(
SystemUser
,
blank
=
True
,
related_name
=
'assets'
,
verbose_name
=
_
(
"System User"
))
idc
=
models
.
ForeignKey
(
IDC
,
null
=
True
,
related_name
=
'assets'
,
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
),
default
=
get_default_idc
)
on_delete
=
models
.
SET_NULL
,
verbose_name
=
_
(
'IDC'
),
)
#
default=get_default_idc)
mac_address
=
models
.
CharField
(
max_length
=
20
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
"Mac address"
))
brand
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Brand'
))
cpu
=
models
.
CharField
(
max_length
=
64
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'CPU'
))
...
...
@@ -307,14 +310,14 @@ class Asset(models.Model):
cabinet_pos
=
models
.
IntegerField
(
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Cabinet position'
))
number
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Asset number'
))
status
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
blank
=
True
,
related_name
=
"status_asset"
,
verbose_name
=
_
(
'Asset status'
),
default
=
functools
.
partial
(
get_default_extend
,
'status'
,
'In use'
))
related_name
=
"status_asset"
,
verbose_name
=
_
(
'Asset status'
),
)
#
default=functools.partial(get_default_extend, 'status', 'In use'))
type
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
limit_choices_to
=
{
'key'
:
'type'
},
related_name
=
"type_asset"
,
verbose_name
=
_
(
'Asset type'
),
default
=
functools
.
partial
(
get_default_extend
,
'type'
,
'Server'
))
env
=
models
.
ForeignKey
(
AssetExtend
,
null
=
True
,
limit_choices_to
=
{
'key'
:
'env'
},
related_name
=
"env_asset"
,
verbose_name
=
_
(
'Asset environment'
),
default
=
functools
.
partial
(
get_default_extend
,
'env'
,
'Production'
))
related_name
=
"type_asset"
,
verbose_name
=
_
(
'Asset type'
),
)
#
default=functools.partial(get_default_extend, 'type','Server'))
env
=
models
.
ForeignKey
(
AssetExtend
,
blank
=
True
,
null
=
True
,
limit_choices_to
=
{
'key'
:
'env'
},
related_name
=
"env_asset"
,
verbose_name
=
_
(
'Asset environment'
),
)
#
default=functools.partial(get_default_extend, 'env', 'Production'))
sn
=
models
.
CharField
(
max_length
=
128
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Serial number'
))
created_by
=
models
.
CharField
(
max_length
=
32
,
null
=
True
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Is active'
))
...
...
@@ -324,8 +327,13 @@ class Asset(models.Model):
def
__unicode__
(
self
):
return
'%(ip)s:%(port)s'
%
{
'ip'
:
self
.
ip
,
'port'
:
self
.
port
}
def
initial
(
self
):
pass
def
is_valid
(
self
):
warning
=
''
if
not
self
.
is_active
:
warning
+=
' inactive'
else
:
return
True
,
''
return
False
,
warning
class
Meta
:
db_table
=
'asset'
...
...
@@ -367,7 +375,7 @@ class Tag(models.Model):
unique_together
=
(
'value'
,
'asset'
)
def
init
ial
():
def
init
_all_models
():
for
cls
in
(
AssetExtend
,
AssetGroup
):
cls
.
initial
()
...
...
apps/assets/templates/assets/asset_create
_update
.html
→
apps/assets/templates/assets/asset_create.html
浏览文件 @
24e31a69
文件已移动
apps/assets/templates/assets/asset_detail.html
浏览文件 @
24e31a69
...
...
@@ -16,10 +16,12 @@
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
><a
href=
""
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Asset detail' %}
</a>
<li
class=
"active"
>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Asset detail' %}
</a>
</li>
<li>
<a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset login log' %}
</a>
</li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset users' %}
</a></li>
<li><a
href=
""
class=
"text-center"
><i
class=
"fa fa-bar-chart-o"
></i>
{% trans 'Asset login log' %}
</a></li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
@@ -45,11 +47,6 @@
<table
class=
"table"
>
<tbody>
<tr
class=
"no-borders-tr"
>
{#
<td
colspan=
"2"
>
#}
{#
<img
src=
"{{ asset | user_avatar_url }}"
class=
"img-circle"
width=
"64"
height=
"64"
>
#}
{#
</td>
#}
</tr>
<tr>
<td
width=
"20%"
>
{% trans 'Hostname' %}:
</td>
<td><b>
{{ asset.hostname }}
</b></td>
</tr>
...
...
@@ -85,20 +82,10 @@
<td>
{% trans 'Disk' %}:
</td>
<td><b>
{{ asset.disk }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Label' %}:
</td>
{% for label in asset.label_set.all %}
<td><b>
{{ label.key }} - {{ label.value }}
</b></td>
{% endfor %}
</tr>
<tr>
<td>
{% trans 'OS' %}:
</td>
<td><b>
{{ asset.os }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Mac address' %}:
</td>
<td><b>
{{ asset.mac_addr }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Asset status' %}:
</td>
<td><b>
{{ asset.status }}
</b></td>
...
...
@@ -163,44 +150,38 @@
</span></td>
</tr>
<tr>
<td>
{% trans 'Enable OTP' %}:
</td>
<td><span
class=
"pull-right"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
class=
"onoffswitch-checkbox"
{%
if
asset.enable_otp
%}
checked
{%
endif
%}
id=
"enable_otp"
>
<label
class=
"onoffswitch-label"
for=
"enable_otp"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-switch"
></span>
</label>
</div>
</div>
</span></td>
<td>
{% trans 'Rrefresh hardware' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
style=
"width: 54px"
>
{% trans 'Refresh' %}
</button>
</span>
</td>
</tr>
<tr>
<td>
{% trans '
Reset password
' %}:
</td>
<td>
{% trans '
Test admin user
' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn_reset_p
assword"
style=
"width: 54px"
>
{% trans 'Rese
t' %}
</button>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn_reset_p
k"
style=
"width: 54px;"
>
{% trans 'Tes
t' %}
</button>
</span>
</td>
</tr>
<tr>
<td>
{% trans '
Reset ssh key
' %}:
</td>
<td>
{% trans '
Test system users
' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn_reset_pk"
style=
"width: 54px;"
>
{% trans '
Rese
t' %}
</button>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn_reset_pk"
style=
"width: 54px;"
>
{% trans '
Tes
t' %}
</button>
</span>
</td>
</tr>
</tbody>
</tbody>
</table>
</div>
</div>
<div
class=
"panel panel-info"
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Asset group' %}
<i
class=
"fa fa-info-circle"
></i>
{% trans 'Asset group
s
' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table group_edit"
>
...
...
@@ -208,25 +189,25 @@
<form>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<select
data-placeholder=
"{% trans 'Join
user groups' %}"
id=
"slct_groups
"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for
group in groups
%}
<option
value=
"{{
group.id }}"
id=
"opt_{{ group.id }}"
>
{{
group.name }}
</option>
<select
data-placeholder=
"{% trans 'Join
asset groups' %}
"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for
asset_group in asset_groups_remain
%}
<option
value=
"{{
asset_group.id }}"
>
{{ asset_
group.name }}
</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<button
type=
"button"
class=
"btn btn-info btn-sm
all
"
id=
"btn_add_user_group"
>
{% trans 'Join' %}
</button>
<button
type=
"button"
class=
"btn btn-info btn-sm"
id=
"btn_add_user_group"
>
{% trans 'Join' %}
</button>
</td>
</tr>
</form>
{% for
group in asset.groups.all
%}
{% for
asset_group in asset_groups
%}
<tr>
<td
><b
class=
"bdg_user_group"
data-gid=
{{
group.id
}}
>
{{
group.name }}
</b></td>
<td
><b
data-gid=
{{
asset_group.id
}}
>
{{ asset_
group.name }}
</b></td>
<td>
<button
class=
"btn btn-danger pull-right btn-
sm btn_delete_user_group
"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
<button
class=
"btn btn-danger pull-right btn-
xs
"
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
...
...
@@ -243,5 +224,8 @@
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
$
(
'
.select2
'
).
select2
();
})
</script>
{% endblock %}
apps/assets/templates/assets/asset_list.html
浏览文件 @
24e31a69
...
...
@@ -25,7 +25,7 @@
<input
type=
"checkbox"
name=
"checked"
value=
"{{ asset.id }}"
>
</td>
<td
class=
"text-center"
>
<a
href=
"{% url '
users:user
-detail' pk=user.id %}"
>
<a
href=
"{% url '
assets:asset
-detail' pk=user.id %}"
>
{{ asset.hostname }}
</a>
</td>
...
...
@@ -34,10 +34,10 @@
<td
class=
"text-center"
>
{{ asset.type }}
</td>
<td
class=
"text-center"
>
{{ asset.cpu }} {{ asset.memory }} {{ asset.disk }}
</td>
<td
class=
"text-center"
>
{% if asset.is_expired %}
<i
class=
"fa fa-times text-danger"
></i>
{% else %}
{% if asset.is_valid.0 %}
<i
class=
"fa fa-check text-navy"
></i>
{% else %}
<i
class=
"fa fa-times text-danger"
></i>
{% endif %}
</td>
<td
class=
"text-center"
>
...
...
apps/assets/templates/assets/asset_update.html
0 → 100644
浏览文件 @
24e31a69
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap %}
{% load i18n %}
{% block custom_head_css_js_create %}
<link
href=
"{% static "
css
/
plugins
/
inputTags.css
"
%}"
rel=
"stylesheet"
>
<script
src=
"{% static "
js
/
plugins
/
inputTags.jquery.min.js
"
%}"
></script>
{% endblock %}
{% block form %}
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
<h3>
{% trans 'Basic' %}
</h3>
{{ form.hostname|bootstrap_horizontal }}
{{ form.ip|bootstrap_horizontal }}
{{ form.port|bootstrap_horizontal }}
{{ form.type|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Group' %}
</h3>
{{ form.idc|bootstrap_horizontal }}
{{ form.groups|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Asset user' %}
</h3>
{{ form.admin_user|bootstrap_horizontal }}
{{ form.system_users|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Hardware' %}
</h3>
{{ form.sn|bootstrap_horizontal }}
{{ form.brand|bootstrap_horizontal }}
{{ form.cpu|bootstrap_horizontal }}
{{ form.memory|bootstrap_horizontal }}
{{ form.disk|bootstrap_horizontal }}
{{ form.mac_address|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Configuration' %}
</h3>
{{ form.number|bootstrap_horizontal }}
{{ form.other_ip|bootstrap_horizontal }}
{{ form.remote_card_ip|bootstrap_horizontal }}
{{ form.os|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Location' %}
</h3>
{{ form.cabinet_no|bootstrap_horizontal }}
{{ form.cabinet_pos|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
{{ form.status|bootstrap_horizontal }}
{{ form.env|bootstrap_horizontal }}
{{ form.tags|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-white"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
$
(
'
.select2
'
).
select2
();
{
#
$
(
'
#tags
'
).
inputTags
({
#
}
{
#
tags
:
[{
%
for
tag
in
form
.
tags
.
value
%
}
{{
tag
|
safe
}},
{
%
endfor
%
}]
#
}
{
#
});
#
}
$
(
'
#tags
'
).
inputTags
(
);
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/views.py
浏览文件 @
24e31a69
...
...
@@ -17,7 +17,7 @@ from .forms import AssetCreateForm, AssetGroupForm, IDCForm, AdminUserForm, Syst
from
.hands
import
AdminUserRequiredMixin
class
AssetListView
(
ListView
):
class
AssetListView
(
AdminUserRequiredMixin
,
ListView
):
paginate_by
=
settings
.
CONFIG
.
DISPLAY_PER_PAGE
model
=
Asset
context_object_name
=
'asset_list'
...
...
@@ -25,9 +25,15 @@ class AssetListView(ListView):
def
get_queryset
(
self
):
queryset
=
super
(
AssetListView
,
self
).
get_queryset
()
queryset
=
sorted
(
queryset
,
key
=
lambda
asset
:
int_seq
(
asset
.
ip
.
split
(
'.'
))
)
queryset
=
sorted
(
queryset
,
key
=
self
.
sorted_by_valid_and_ip
)
return
queryset
@
staticmethod
def
sorted_by_valid_and_ip
(
asset
):
ip_list
=
int_seq
(
asset
.
ip
.
split
(
'.'
))
ip_list
.
insert
(
0
,
asset
.
is_valid
()[
0
])
return
ip_list
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Assets'
,
...
...
@@ -40,13 +46,12 @@ class AssetListView(ListView):
class
AssetCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
Asset
form_class
=
AssetCreateForm
template_name
=
'assets/asset_create
_update
.html'
template_name
=
'assets/asset_create.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
# def form_valid(self, form):
# asset = form.save()
# print(self.request.POST.get('tags'))
# return super(AssetCreateView, self).form_valid(form)
def
form_invalid
(
self
,
form
):
print
(
form
.
errors
)
return
super
(
AssetCreateView
,
self
).
form_invalid
(
form
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
...
...
@@ -57,8 +62,19 @@ class AssetCreateView(AdminUserRequiredMixin, CreateView):
return
super
(
AssetCreateView
,
self
).
get_context_data
(
**
kwargs
)
class
AssetUpdateView
(
UpdateView
):
pass
class
AssetUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
Asset
form_class
=
AssetCreateForm
template_name
=
'assets/asset_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'Assets'
,
'action'
:
'Update asset'
,
}
kwargs
.
update
(
context
)
return
super
(
AssetUpdateView
,
self
).
get_context_data
(
**
kwargs
)
class
AssetDeleteView
(
DeleteView
):
...
...
@@ -72,6 +88,18 @@ class AssetDetailView(DetailView):
context_object_name
=
'asset'
template_name
=
'assets/asset_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
asset_groups
=
self
.
object
.
groups
.
all
()
context
=
{
'app'
:
'Assets'
,
'action'
:
'Asset detail'
,
'asset_groups_remain'
:
[
asset_group
for
asset_group
in
AssetGroup
.
objects
.
all
()
if
asset_group
not
in
asset_groups
],
'asset_groups'
:
asset_groups
,
}
kwargs
.
update
(
context
)
return
super
(
AssetDetailView
,
self
).
get_context_data
(
**
kwargs
)
class
AssetGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
AssetGroup
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录