mirror of https://github.com/jumpserver/jumpserver
[Fixture] 完成批量更新
parent
2aa9aafdf6
commit
695e4da85e
|
@ -13,19 +13,24 @@ class AssetCreateForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
fields = [
|
fields = [
|
||||||
'hostname', 'ip', 'public_ip', 'port', 'type', 'comment', 'admin_user',
|
'hostname', 'ip', 'public_ip', 'port', 'type', 'comment',
|
||||||
'idc', 'groups', 'status', 'env', 'is_active'
|
'admin_user', 'idc', 'groups', 'status', 'env', 'is_active'
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
'groups': forms.SelectMultiple(
|
||||||
'data-placeholder': _('Select asset groups')}),
|
attrs={'class': 'select2',
|
||||||
'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}),
|
'data-placeholder': _('Select asset groups')}),
|
||||||
|
'admin_user': forms.Select(
|
||||||
|
attrs={'class': 'select2',
|
||||||
|
'data-placeholder': _('Select asset admin user')}),
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'hostname': '* required',
|
'hostname': '* required',
|
||||||
'ip': '* required',
|
'ip': '* required',
|
||||||
'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'),
|
'system_users': _('System user will be granted for user to login '
|
||||||
'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'),
|
'assets (using ansible create automatic)'),
|
||||||
|
'admin_user': _('Admin user should be exist on asset already, '
|
||||||
|
'And have sudo ALL permission'),
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean_admin_user(self):
|
def clean_admin_user(self):
|
||||||
|
@ -43,23 +48,43 @@ class AssetUpdateForm(forms.ModelForm):
|
||||||
'cabinet_pos', 'number', 'comment'
|
'cabinet_pos', 'number', 'comment'
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
'groups': forms.SelectMultiple(
|
||||||
'data-placeholder': _('Select asset groups')}),
|
attrs={'class': 'select2',
|
||||||
'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}),
|
'data-placeholder': _('Select asset groups')}),
|
||||||
|
'admin_user': forms.Select(
|
||||||
|
attrs={'class': 'select2',
|
||||||
|
'data-placeholder': _('Select asset admin user')}),
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'hostname': '* required',
|
'hostname': '* required',
|
||||||
'ip': '* required',
|
'ip': '* required',
|
||||||
'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'),
|
'system_users': _('System user will be granted for user '
|
||||||
'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'),
|
'to login assets (using ansible create automatic)'),
|
||||||
|
'admin_user': _('Admin user should be exist on asset '
|
||||||
|
'already, And have sudo ALL permission'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AssetBulkUpdateForm(forms.ModelForm):
|
class AssetBulkUpdateForm(forms.ModelForm):
|
||||||
|
assets = forms.MultipleChoiceField(
|
||||||
|
required=True,
|
||||||
|
help_text='* required',
|
||||||
|
label=_('Select assets'),
|
||||||
|
choices=[(asset.id, asset.hostname) for asset in Asset.objects.all()],
|
||||||
|
widget=forms.SelectMultiple(
|
||||||
|
attrs={
|
||||||
|
'class': 'select2',
|
||||||
|
'data-placeholder': _('Select assets')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
port = forms.IntegerField(min_value=1, max_value=65535,
|
||||||
|
required=False, label=_('Port'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
fields = [
|
fields = [
|
||||||
'port', 'groups', 'admin_user', 'idc',
|
'assets', 'port', 'groups', 'admin_user', 'idc',
|
||||||
'type', 'env', 'status',
|
'type', 'env', 'status',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
|
@ -71,6 +96,17 @@ class AssetBulkUpdateForm(forms.ModelForm):
|
||||||
'data-placeholder': _('Select asset admin user')}),
|
'data-placeholder': _('Select asset admin user')}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
cleaned_data = {k: v for k, v in self.cleaned_data.items() if v is not None}
|
||||||
|
assets_id = cleaned_data.pop('assets')
|
||||||
|
groups = cleaned_data.pop('groups')
|
||||||
|
assets = Asset.objects.filter(id__in=assets_id)
|
||||||
|
assets.update(**cleaned_data)
|
||||||
|
if groups:
|
||||||
|
for asset in assets:
|
||||||
|
asset.groups.set(groups)
|
||||||
|
return assets
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupForm(forms.ModelForm):
|
class AssetGroupForm(forms.ModelForm):
|
||||||
# See AdminUserForm comment same it
|
# See AdminUserForm comment same it
|
||||||
|
|
|
@ -41,10 +41,13 @@ class Asset(models.Model):
|
||||||
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
|
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
|
||||||
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
|
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
|
||||||
port = models.IntegerField(default=22, verbose_name=_('Port'))
|
port = models.IntegerField(default=22, verbose_name=_('Port'))
|
||||||
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets', verbose_name=_('Asset groups'))
|
groups = models.ManyToManyField(AssetGroup, blank=True, related_name='assets',
|
||||||
|
verbose_name=_('Asset groups'))
|
||||||
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
|
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
|
||||||
on_delete=models.SET_NULL, verbose_name=_("Admin user"))
|
on_delete=models.SET_NULL, verbose_name=_("Admin user"))
|
||||||
system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
|
system_users = models.ManyToManyField(SystemUser, blank=True,
|
||||||
|
related_name='assets',
|
||||||
|
verbose_name=_("System User"))
|
||||||
idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets',
|
idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets',
|
||||||
on_delete=models.SET_NULL, verbose_name=_('IDC'),)
|
on_delete=models.SET_NULL, verbose_name=_('IDC'),)
|
||||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
||||||
|
@ -52,12 +55,14 @@ class Asset(models.Model):
|
||||||
default='Server', verbose_name=_('Asset type'),)
|
default='Server', verbose_name=_('Asset type'),)
|
||||||
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True,
|
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True,
|
||||||
default='Prod', verbose_name=_('Asset environment'),)
|
default='Prod', verbose_name=_('Asset environment'),)
|
||||||
status = models.CharField(choices=STATUS_CHOICES, max_length=8, null=True, blank=True,
|
status = models.CharField(choices=STATUS_CHOICES, max_length=12, null=True, blank=True,
|
||||||
default='In use', verbose_name=_('Asset status'))
|
default='In use', verbose_name=_('Asset status'))
|
||||||
|
|
||||||
# Some information
|
# Some information
|
||||||
public_ip = models.GenericIPAddressField(max_length=32, blank=True, null=True, verbose_name=_('Public IP'))
|
public_ip = models.GenericIPAddressField(max_length=32, blank=True,
|
||||||
remote_card_ip = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('Remote control card IP'))
|
null=True, verbose_name=_('Public IP'))
|
||||||
|
remote_card_ip = models.CharField(max_length=16, null=True, blank=True,
|
||||||
|
verbose_name=_('Remote control card IP'))
|
||||||
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
|
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
|
||||||
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
|
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'))
|
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
|
||||||
|
|
|
@ -9,32 +9,14 @@
|
||||||
<div class="tagBtnList">
|
<div class="tagBtnList">
|
||||||
<a class="label label-primary" id="change_all" value="1">全选</a>
|
<a class="label label-primary" id="change_all" value="1">全选</a>
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
|
{% if field.name != 'assets' %}
|
||||||
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
|
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if errors %}
|
|
||||||
<div class="alert alert-danger">
|
|
||||||
{{ errors }}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<form method="post" class="form-horizontal" id="add_form">
|
<form method="post" class="form-horizontal" id="add_form">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group abc">
|
|
||||||
<label class="control-label col-sm-2 col-lg-2 " id="asset_on_count">{% trans 'Asset' %}</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select class="form-control select2" multiple="multiple" name="assets">
|
|
||||||
{% for asset in assets %}
|
|
||||||
{% if asset.id in assets_selected %}
|
|
||||||
<option selected="selected" value="{{ asset.id }}">{{ asset.hostname }}</option>
|
|
||||||
{% else %}
|
|
||||||
<option value="{{ asset.id }}">{{ asset.hostname }}</option>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
<span class="help-block">* required</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% bootstrap_form form layout="horizontal" %}
|
{% bootstrap_form form layout="horizontal" %}
|
||||||
<div class="form-group abc">
|
<div class="form-group abc">
|
||||||
<div class="col-sm-4 col-sm-offset-2">
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
|
@ -83,33 +65,5 @@
|
||||||
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fsubmit(){
|
|
||||||
var assets_id = document.getElementsByName("assets");
|
|
||||||
var oForm = document.getElementById('add_form');
|
|
||||||
var parentElem = document.getElementById("add_form");
|
|
||||||
var aDiv = parentElem.getElementsByClassName('form-group');
|
|
||||||
if (assets_id.length === 0) {
|
|
||||||
swal({
|
|
||||||
title: "未选择需要修改的主机",
|
|
||||||
text: "请点击选择"
|
|
||||||
});
|
|
||||||
}else if (aDiv.length === 1) {
|
|
||||||
swal({
|
|
||||||
title: "未选需要修改的属性",
|
|
||||||
text: "请点击选择"
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
var m = document.getElementsByName('assets_ids');
|
|
||||||
alert(m.length);
|
|
||||||
for(var i=0;i<m.length;i++){
|
|
||||||
alert(m[0].value);
|
|
||||||
oForm.appendChild(m[0]);
|
|
||||||
}
|
|
||||||
action="/assets/asset/"+assets_id[0].value+"/update";
|
|
||||||
oForm.action=action;
|
|
||||||
oForm.submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -88,6 +88,7 @@ function tagShow() {
|
||||||
} //onload;
|
} //onload;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
var options = {
|
var options = {
|
||||||
ele: $('#asset_list_table'),
|
ele: $('#asset_list_table'),
|
||||||
|
@ -125,6 +126,7 @@ $(document).ready(function(){
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
var table = jumpserver.initDataTable(options);
|
var table = jumpserver.initDataTable(options);
|
||||||
|
|
||||||
$('.btn_export').click(function () {
|
$('.btn_export').click(function () {
|
||||||
var assets = [];
|
var assets = [];
|
||||||
var rows = table.rows('.selected').data();
|
var rows = table.rows('.selected').data();
|
||||||
|
@ -178,20 +180,18 @@ $(document).ready(function(){
|
||||||
$data_table.ajax.reload();
|
$data_table.ajax.reload();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
})
|
})
|
||||||
|
|
||||||
.on('click', '#btn_bulk_update', function () {
|
.on('click', '#btn_bulk_update', function () {
|
||||||
var action = $('#slct_bulk_update').val();
|
var action = $('#slct_bulk_update').val();
|
||||||
var $data_table = $('#asset_list_table').DataTable();
|
var $data_table = $('#asset_list_table').DataTable();
|
||||||
var id_list = [];
|
var id_list = [];
|
||||||
var plain_id_list = [];
|
|
||||||
$data_table.rows({selected: true}).every(function(){
|
$data_table.rows({selected: true}).every(function(){
|
||||||
id_list.push({id: this.data().id});
|
id_list.push(this.data().id);
|
||||||
plain_id_list.push(this.data().id);
|
|
||||||
});
|
});
|
||||||
if (plain_id_list.length == 0) {
|
if (id_list.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var the_url = "{% url 'api-assets:asset-list' %}";
|
var the_url = "{% url 'api-assets:asset-list' %}";
|
||||||
|
|
||||||
function doDeactive() {
|
function doDeactive() {
|
||||||
var body = $.each(id_list, function(index, asset_object) {
|
var body = $.each(id_list, function(index, asset_object) {
|
||||||
asset_object['is_active'] = false;
|
asset_object['is_active'] = false;
|
||||||
|
@ -234,7 +234,9 @@ $(document).ready(function(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function doUpdate() {
|
function doUpdate() {
|
||||||
$('#asset_bulk_update_modal').modal('show');
|
var id_list_string = id_list.join(',');
|
||||||
|
var url = "{% url 'assets:asset-bulk-update' %}?assets_id=" + id_list_string;
|
||||||
|
location.href = url
|
||||||
}
|
}
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case 'deactive':
|
case 'deactive':
|
||||||
|
@ -252,66 +254,66 @@ $(document).ready(function(){
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
.on('click', '#btn_asset_bulk_update', function () {
|
|
||||||
var json_data = $("#fm_asset_bulk_update").serializeObject();
|
|
||||||
var body = {};
|
|
||||||
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
|
|
||||||
if (json_data.type != '') {
|
|
||||||
body.type = json_data.type;
|
|
||||||
}
|
|
||||||
if (json_data.groups != undefined) {
|
|
||||||
body.groups = json_data.groups;
|
|
||||||
}
|
|
||||||
if (typeof body.groups === 'string') {
|
|
||||||
body.groups = [parseInt(body.groups)]
|
|
||||||
} else if(typeof body.groups === 'array') {
|
|
||||||
var new_groups = body.groups.map(Number);
|
|
||||||
body.groups = new_groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json_data.system_users != undefined) {
|
|
||||||
body.system_users = json_data.system_users;
|
|
||||||
}
|
|
||||||
if (typeof body.system_users === 'string') {
|
|
||||||
body.system_users = [parseInt(body.system_users)]
|
|
||||||
} else if(typeof body.system_users === 'array') {
|
|
||||||
var new_users = body.system_users.map(Number);
|
|
||||||
body.system_users = new_users;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json_data.tags != undefined) {
|
|
||||||
body.tags = json_data.tags;
|
|
||||||
}
|
|
||||||
if (typeof body.tags == 'string') {
|
|
||||||
body.tags = [parseInt(body.tags)];
|
|
||||||
} else if (typeof body.tags === 'array') {
|
|
||||||
var new_tags = body.tags.map(Number);
|
|
||||||
body.tags = new_tags;
|
|
||||||
}
|
|
||||||
|
|
||||||
var $data_table = $('#asset_list_table').DataTable();
|
|
||||||
var post_list = [];
|
|
||||||
$data_table.rows({selected: true}).every(function(){
|
|
||||||
var content = Object.assign({id: this.data().id}, body);
|
|
||||||
post_list.push(content);
|
|
||||||
});
|
|
||||||
if (post_list === []) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
var the_url = "{% url 'api-assets:asset-list' %}";
|
|
||||||
var success = function() {
|
|
||||||
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
|
|
||||||
swal("{% trans 'Asset Updated' %}", msg, "success");
|
|
||||||
$('#asset_list_table').DataTable().ajax.reload();
|
|
||||||
jumpserver.checked = false;
|
|
||||||
};
|
|
||||||
console.log(JSON.stringify(post_list));
|
|
||||||
console.log(the_url);
|
|
||||||
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
|
|
||||||
$('#asset_bulk_update_modal').modal('hide');
|
|
||||||
});
|
});
|
||||||
|
{##}
|
||||||
|
{#.on('click', '#btn_asset_bulk_update', function () {#}
|
||||||
|
{# var json_data = $("#fm_asset_bulk_update").serializeObject();#}
|
||||||
|
{# var body = {};#}
|
||||||
|
{# body.enable_otp = (json_data.enable_otp === 'on')? true: false;#}
|
||||||
|
{# if (json_data.type != '') {#}
|
||||||
|
{# body.type = json_data.type;#}
|
||||||
|
{# }#}
|
||||||
|
{# if (json_data.groups != undefined) {#}
|
||||||
|
{# body.groups = json_data.groups;#}
|
||||||
|
{# }#}
|
||||||
|
{# if (typeof body.groups === 'string') {#}
|
||||||
|
{# body.groups = [parseInt(body.groups)]#}
|
||||||
|
{# } else if(typeof body.groups === 'array') {#}
|
||||||
|
{# var new_groups = body.groups.map(Number);#}
|
||||||
|
{# body.groups = new_groups;#}
|
||||||
|
{# }#}
|
||||||
|
{##}
|
||||||
|
{# if (json_data.system_users != undefined) {#}
|
||||||
|
{# body.system_users = json_data.system_users;#}
|
||||||
|
{# }#}
|
||||||
|
{# if (typeof body.system_users === 'string') {#}
|
||||||
|
{# body.system_users = [parseInt(body.system_users)]#}
|
||||||
|
{# } else if(typeof body.system_users === 'array') {#}
|
||||||
|
{# var new_users = body.system_users.map(Number);#}
|
||||||
|
{# body.system_users = new_users;#}
|
||||||
|
{# }#}
|
||||||
|
{##}
|
||||||
|
{# if (json_data.tags != undefined) {#}
|
||||||
|
{# body.tags = json_data.tags;#}
|
||||||
|
{# }#}
|
||||||
|
{# if (typeof body.tags == 'string') {#}
|
||||||
|
{# body.tags = [parseInt(body.tags)];#}
|
||||||
|
{# } else if (typeof body.tags === 'array') {#}
|
||||||
|
{# var new_tags = body.tags.map(Number);#}
|
||||||
|
{# body.tags = new_tags;#}
|
||||||
|
{# }#}
|
||||||
|
{##}
|
||||||
|
{# var $data_table = $('#asset_list_table').DataTable();#}
|
||||||
|
{# var post_list = [];#}
|
||||||
|
{# $data_table.rows({selected: true}).every(function(){#}
|
||||||
|
{# var content = Object.assign({id: this.data().id}, body);#}
|
||||||
|
{# post_list.push(content);#}
|
||||||
|
{# });#}
|
||||||
|
{# if (post_list === []) {#}
|
||||||
|
{# return false#}
|
||||||
|
{# }#}
|
||||||
|
{# var the_url = "{% url 'api-assets:asset-list' %}";#}
|
||||||
|
{# var success = function() {#}
|
||||||
|
{# var msg = "{% trans 'The selected assets has been updated successfully.' %}";#}
|
||||||
|
{# swal("{% trans 'Asset Updated' %}", msg, "success");#}
|
||||||
|
{# $('#asset_list_table').DataTable().ajax.reload();#}
|
||||||
|
{# jumpserver.checked = false;#}
|
||||||
|
{# };#}
|
||||||
|
{# console.log(JSON.stringify(post_list));#}
|
||||||
|
{# console.log(the_url);#}
|
||||||
|
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
|
||||||
|
{# $('#asset_bulk_update_modal').modal('hide');#}
|
||||||
|
{#})#}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -20,7 +20,7 @@ from django.utils.decorators import method_decorator
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.shortcuts import get_object_or_404, redirect
|
from django.shortcuts import get_object_or_404, redirect, reverse
|
||||||
|
|
||||||
from common.mixins import JSONResponseMixin
|
from common.mixins import JSONResponseMixin
|
||||||
from common.utils import get_object_or_none
|
from common.utils import get_object_or_none
|
||||||
|
@ -43,7 +43,7 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
'app': 'Assets',
|
'app': 'Assets',
|
||||||
'action': 'asset list',
|
'action': 'Asset list',
|
||||||
'groups': AssetGroup.objects.all(),
|
'groups': AssetGroup.objects.all(),
|
||||||
'system_users': SystemUser.objects.all(),
|
'system_users': SystemUser.objects.all(),
|
||||||
# 'form': forms.AssetBulkUpdateForm(),
|
# 'form': forms.AssetBulkUpdateForm(),
|
||||||
|
@ -58,7 +58,7 @@ class UserAssetListView(LoginRequiredMixin, TemplateView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = {
|
context = {
|
||||||
'app': 'Assets',
|
'app': 'Assets',
|
||||||
'action': 'asset list',
|
'action': 'Asset list',
|
||||||
'system_users': SystemUser.objects.all(),
|
'system_users': SystemUser.objects.all(),
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
|
@ -118,62 +118,24 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
assets_id = self.request.GET.get('assets_id', '')
|
assets_id = self.request.GET.get('assets_id', '')
|
||||||
self.assets_id_list = [int(i) for i in assets_id.split(',') if i.isdigit()]
|
self.assets_id_list = [int(i) for i in assets_id.split(',') if i.isdigit()]
|
||||||
self.form = self.form_class()
|
|
||||||
self.errors = kwargs.get('errors')
|
if kwargs.get('form'):
|
||||||
|
self.form = kwargs['form']
|
||||||
|
elif assets_id:
|
||||||
|
self.form = self.form_class(
|
||||||
|
initial={'assets': self.assets_id_list}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.form = self.form_class()
|
||||||
return super(AssetBulkUpdateView, self).get(request, *args, **kwargs)
|
return super(AssetBulkUpdateView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
raw_data = request.POST
|
form = self.form_class(request.POST)
|
||||||
data = {}
|
if form.is_valid():
|
||||||
errors = defaultdict(list)
|
form.save()
|
||||||
for k in raw_data:
|
return redirect(self.success_url)
|
||||||
if not hasattr(Asset, k) or raw_data.get(k) == '':
|
|
||||||
if k not in ['assets']:
|
|
||||||
continue
|
|
||||||
if k == 'assets':
|
|
||||||
v = Asset.objects.filter(id__in=raw_data.getlist(k))
|
|
||||||
if not v:
|
|
||||||
errors['assets'].append(_('Required'))
|
|
||||||
elif k == 'port':
|
|
||||||
try:
|
|
||||||
v = int(raw_data.get(k))
|
|
||||||
except ValueError:
|
|
||||||
v = None
|
|
||||||
errors['port'].append(_('Integer required'))
|
|
||||||
elif k == 'admin_user':
|
|
||||||
admin_user_id = raw_data.get(k)
|
|
||||||
try:
|
|
||||||
v = int(admin_user_id)
|
|
||||||
except ValueError:
|
|
||||||
v = None
|
|
||||||
errors['admin_user'].append(_('Invalid admin user'))
|
|
||||||
v = get_object_or_none(AdminUser, id=v)
|
|
||||||
elif k == 'groups':
|
|
||||||
groups_id = raw_data.getlist(k)
|
|
||||||
v = [AssetGroup.objects.filter(id__in=groups_id)]
|
|
||||||
elif k == 'idc':
|
|
||||||
idc_id = raw_data.get(k)
|
|
||||||
try:
|
|
||||||
v = int(idc_id)
|
|
||||||
except ValueError:
|
|
||||||
v = None
|
|
||||||
errors['idc'].append(_('Integer required'))
|
|
||||||
v = get_object_or_none(IDC, id=v)
|
|
||||||
else:
|
|
||||||
v = raw_data.get(k)
|
|
||||||
data[k] = v
|
|
||||||
|
|
||||||
if not errors:
|
|
||||||
for asset in data['assets']:
|
|
||||||
for k, v in data.items():
|
|
||||||
if k == 'groups':
|
|
||||||
asset.groups.set(data['groups'])
|
|
||||||
else:
|
|
||||||
setattr(asset, k, v)
|
|
||||||
asset.save()
|
|
||||||
return redirect(reverse_lazy('assets:asset-list'))
|
|
||||||
else:
|
else:
|
||||||
return self.get(request, errors=errors, *args, **kwargs)
|
return self.get(request, form=form, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
# assets_list = Asset.objects.filter(id__in=self.assets_id_list)
|
# assets_list = Asset.objects.filter(id__in=self.assets_id_list)
|
||||||
|
@ -181,7 +143,6 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||||
'app': 'Assets',
|
'app': 'Assets',
|
||||||
'action': 'Bulk update asset',
|
'action': 'Bulk update asset',
|
||||||
'form': self.form,
|
'form': self.form,
|
||||||
'errors': self.errors,
|
|
||||||
'assets_selected': self.assets_id_list,
|
'assets_selected': self.assets_id_list,
|
||||||
'assets': Asset.objects.all(),
|
'assets': Asset.objects.all(),
|
||||||
}
|
}
|
||||||
|
@ -236,9 +197,6 @@ class AssetDetailView(DetailView):
|
||||||
return super(AssetDetailView, self).get_context_data(**kwargs)
|
return super(AssetDetailView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(csrf_exempt, name='dispatch')
|
@method_decorator(csrf_exempt, name='dispatch')
|
||||||
class AssetExportView(View):
|
class AssetExportView(View):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -114,15 +114,44 @@ class UserPublicKeyForm(forms.Form):
|
||||||
return self.instance
|
return self.instance
|
||||||
|
|
||||||
|
|
||||||
# class UserBulkImportForm(forms.ModelForm):
|
|
||||||
# class Meta:
|
|
||||||
# model = User
|
|
||||||
# fields = ['username', 'email', 'enable_otp', 'role']
|
|
||||||
|
|
||||||
class UserBulkUpdateForm(forms.ModelForm):
|
class UserBulkUpdateForm(forms.ModelForm):
|
||||||
|
role = forms.ChoiceField(
|
||||||
|
label=_('Role'),
|
||||||
|
choices=[('Admin', 'Administrator'), ('User', 'User')],
|
||||||
|
)
|
||||||
|
users = forms.MultipleChoiceField(
|
||||||
|
required=True,
|
||||||
|
help_text='* required',
|
||||||
|
label=_('Select users'),
|
||||||
|
choices=[(user.id, user.name ) for user in User.objects.all()],
|
||||||
|
widget=forms.SelectMultiple(
|
||||||
|
attrs={
|
||||||
|
'class': 'select2',
|
||||||
|
'data-placeholder': _('Select users')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['role', 'groups', 'date_expired', 'is_active', 'enable_otp']
|
fields = ['users', 'role', 'groups', 'date_expired', 'is_active', 'enable_otp']
|
||||||
|
widgets = {
|
||||||
|
'groups': forms.SelectMultiple(
|
||||||
|
attrs={'class': 'select2',
|
||||||
|
'data-placeholder': _('Select user groups')}),
|
||||||
|
}
|
||||||
|
|
||||||
|
def save(self, commit=True):
|
||||||
|
cleaned_data = {k: v for k, v in self.cleaned_data.items() if
|
||||||
|
v is not None}
|
||||||
|
users_id = cleaned_data.pop('users')
|
||||||
|
groups = cleaned_data.pop('groups')
|
||||||
|
users = User.objects.filter(id__in=users_id)
|
||||||
|
users.update(**cleaned_data)
|
||||||
|
if groups:
|
||||||
|
for user in users:
|
||||||
|
user.groups.set(groups)
|
||||||
|
return users
|
||||||
|
|
||||||
|
|
||||||
class UserGroupForm(forms.ModelForm):
|
class UserGroupForm(forms.ModelForm):
|
||||||
|
|
|
@ -5,33 +5,68 @@
|
||||||
{% block modal_class %}modal-lg{% endblock %}
|
{% block modal_class %}modal-lg{% endblock %}
|
||||||
{% block modal_title%}{% trans "Update selected user" %}{% endblock %}
|
{% block modal_title%}{% trans "Update selected user" %}{% endblock %}
|
||||||
{% block modal_body %}
|
{% block modal_body %}
|
||||||
<div class="ydxbd" id="ydxbd" style="display: block;">
|
{% block form %}
|
||||||
<div>
|
<div class="ydxbd" id="formlists" style="display: block;">
|
||||||
<p id="tags_p">
|
<p id="tags_p" class="mgl-5 c02">选择需要修改属性</p>
|
||||||
<a href="/assets/asset-by-tag/5">
|
<div class="tagBtnList">
|
||||||
<span class="label label-default">三年质保(0)</span>
|
<a class="label label-primary" id="change_all" value="1">全选</a>
|
||||||
</a>
|
{% for field in form %}
|
||||||
<a href="/assets/asset-by-tag/5">
|
{# {% if field.name != 'assets' %}#}
|
||||||
<span class="label label-default">三年质保(0)</span>
|
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
|
||||||
</a>
|
{# {% endif %}#}
|
||||||
</p>
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" class="form-horizontal" action="" id="fm_user_bulk_update">
|
<form method="post" class="form-horizontal" id="add_form">
|
||||||
{# {% for field in form %}#}
|
{% csrf_token %}
|
||||||
{# <input type="checkbox">#}
|
{% bootstrap_form form layout="horizontal" %}
|
||||||
{# {% bootstrap_field field layout='horizontal' %}#}
|
<div class="form-group abc">
|
||||||
{# {% endfor %}#}
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
{% bootstrap_form form layout='horizontal' %}
|
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||||
{# <div class="form-group">#}
|
</div>
|
||||||
{# <div class="col-sm-9 col-lg-9 col-sm-offset-2">#}
|
</div>
|
||||||
{# <div class="checkbox">#}
|
|
||||||
{# <input type="checkbox" name="enable_otp" checked id="id_enable_otp" disabled><label for="id_enable_otp">{% trans 'Enable-OTP' %}</label>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
{# </div>#}
|
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block modal_confirm_id %}btn_user_bulk_update{% endblock %}
|
{% endblock %}
|
||||||
|
{#{% block custom_foot_js %}#}
|
||||||
|
{#<script>#}
|
||||||
|
{# $(document).ready(function () {#}
|
||||||
|
{# $('.select2').select2();#}
|
||||||
|
{# }).on('click', '.field-tag', function() {#}
|
||||||
|
{# changeField(this);#}
|
||||||
|
{# }).on('click', '#change_all', function () {#}
|
||||||
|
{# var tag_fields = $('.field-tag');#}
|
||||||
|
{# var $this = $(this);#}
|
||||||
|
{# var active = '1';#}
|
||||||
|
{# if ($this.attr('value') == '0'){#}
|
||||||
|
{# active = '0';#}
|
||||||
|
{# $this.attr('value', '1').addClass('label-primary')#}
|
||||||
|
{# } else {#}
|
||||||
|
{# active = '1';#}
|
||||||
|
{# $this.attr('value', '0').removeClass('label-primary')#}
|
||||||
|
{# }#}
|
||||||
|
{# $.each(tag_fields, function (k, v) {#}
|
||||||
|
{# changeField(v, active)#}
|
||||||
|
{# })#}
|
||||||
|
{# });#}
|
||||||
|
{##}
|
||||||
|
{# function changeField(obj, active) {#}
|
||||||
|
{# var $this = $(obj);#}
|
||||||
|
{# var field_id = $this.data('id');#}
|
||||||
|
{# if (!active) {#}
|
||||||
|
{# active = $this.attr('value');#}
|
||||||
|
{# }#}
|
||||||
|
{# if (active == '0') {#}
|
||||||
|
{# $this.attr('value', '1').addClass('label-primary');#}
|
||||||
|
{# var form_groups = $('#add_form .form-group:not(.abc)');#}
|
||||||
|
{# form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)#}
|
||||||
|
{# } else {#}
|
||||||
|
{# $this.attr('value', '0').removeClass('label-primary');#}
|
||||||
|
{# var form_groups = $('#add_form .form-group:not(.abc)');#}
|
||||||
|
{# form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)#}
|
||||||
|
{# }#}
|
||||||
|
{# }#}
|
||||||
|
{#</script>#}
|
||||||
|
{#{% endblock %}#}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
{% extends '_base_create_update.html' %}
|
||||||
|
{% load static %}
|
||||||
|
{% load bootstrap3 %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block form %}
|
||||||
|
<div class="ydxbd" id="formlists" style="display: block;">
|
||||||
|
<p id="tags_p" class="mgl-5 c02">选择需要修改属性</p>
|
||||||
|
<div class="tagBtnList">
|
||||||
|
<a class="label label-primary" id="change_all" value="1">全选</a>
|
||||||
|
{% for field in form %}
|
||||||
|
{% if field.name != 'users' %}
|
||||||
|
<a data-id="{{ field.id_for_label }}" class="label label-default label-primary field-tag" value="1">{{ field.label }}</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form method="post" class="form-horizontal" id="add_form">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% bootstrap_form form layout="horizontal" %}
|
||||||
|
<div class="form-group abc">
|
||||||
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
|
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
|
||||||
|
<button class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block custom_foot_js %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2();
|
||||||
|
}).on('click', '.field-tag', function() {
|
||||||
|
changeField(this);
|
||||||
|
}).on('click', '#change_all', function () {
|
||||||
|
var tag_fields = $('.field-tag');
|
||||||
|
var $this = $(this);
|
||||||
|
var active = '1';
|
||||||
|
if ($this.attr('value') == '0'){
|
||||||
|
active = '0';
|
||||||
|
$this.attr('value', '1').addClass('label-primary')
|
||||||
|
} else {
|
||||||
|
active = '1';
|
||||||
|
$this.attr('value', '0').removeClass('label-primary')
|
||||||
|
}
|
||||||
|
$.each(tag_fields, function (k, v) {
|
||||||
|
changeField(v, active)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
function changeField(obj, active) {
|
||||||
|
var $this = $(obj);
|
||||||
|
var field_id = $this.data('id');
|
||||||
|
if (!active) {
|
||||||
|
active = $this.attr('value');
|
||||||
|
}
|
||||||
|
if (active == '0') {
|
||||||
|
$this.attr('value', '1').addClass('label-primary');
|
||||||
|
var form_groups = $('#add_form .form-group');
|
||||||
|
form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)
|
||||||
|
} else {
|
||||||
|
$this.attr('value', '0').removeClass('label-primary');
|
||||||
|
var form_groups = $('#add_form .form-group');
|
||||||
|
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -55,6 +55,22 @@
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||||
<script>
|
<script>
|
||||||
|
function changeField(obj, active) {
|
||||||
|
var $this = $(obj);
|
||||||
|
var field_id = $this.data('id');
|
||||||
|
if (!active) {
|
||||||
|
active = $this.attr('value');
|
||||||
|
}
|
||||||
|
if (active == '0') {
|
||||||
|
$this.attr('value', '1').addClass('label-primary');
|
||||||
|
var form_groups = $('#add_form .form-group:not(.abc)');
|
||||||
|
form_groups.filter(':has(#' + field_id + ')').show().find('select,input').prop('disabled', false)
|
||||||
|
} else {
|
||||||
|
$this.attr('value', '0').removeClass('label-primary');
|
||||||
|
var form_groups = $('#add_form .form-group:not(.abc)');
|
||||||
|
form_groups.filter(':has(#' + field_id + ')').hide().find('select,input').prop('disabled', true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function renderTable() {
|
function renderTable() {
|
||||||
var options = {
|
var options = {
|
||||||
|
@ -193,7 +209,9 @@ $(document).ready(function(){
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function doUpdate() {
|
function doUpdate() {
|
||||||
$('#user_bulk_update_modal').modal('show');
|
var users_id = plain_id_list.join(',');
|
||||||
|
var url = "{% url 'users:user-bulk-update' %}?users_id=" + users_id;
|
||||||
|
location.href = url
|
||||||
}
|
}
|
||||||
switch(action) {
|
switch(action) {
|
||||||
case 'deactive':
|
case 'deactive':
|
||||||
|
@ -249,10 +267,9 @@ $(document).ready(function(){
|
||||||
$('#user_list_table').DataTable().ajax.reload();
|
$('#user_list_table').DataTable().ajax.reload();
|
||||||
jumpserver.checked = false;
|
jumpserver.checked = false;
|
||||||
};
|
};
|
||||||
console.log(body);
|
|
||||||
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
|
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
|
||||||
$('#user_bulk_update_modal').modal('hide');
|
$('#user_bulk_update_modal').modal('hide');
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,11 @@ urlpatterns = [
|
||||||
name='reset-password-success'),
|
name='reset-password-success'),
|
||||||
|
|
||||||
# Profile
|
# Profile
|
||||||
url(r'^profile/$',
|
url(r'^profile/$', views.UserProfileView.as_view(),
|
||||||
views.UserProfileView.as_view(),
|
|
||||||
name='user-profile'),
|
name='user-profile'),
|
||||||
url(r'^profile/update/$',
|
url(r'^profile/update/$', views.UserProfileUpdateView.as_view(),
|
||||||
views.UserProfileUpdateView.as_view(),
|
|
||||||
name='user-profile-update'),
|
name='user-profile-update'),
|
||||||
url(r'^profile/password/update/$',
|
url(r'^profile/password/update/$', views.UserPasswordUpdateView.as_view(),
|
||||||
views.UserPasswordUpdateView.as_view(),
|
|
||||||
name='user-password-update'),
|
name='user-password-update'),
|
||||||
url(r'^profile/pubkey/update/$',
|
url(r'^profile/pubkey/update/$',
|
||||||
views.UserPublicKeyUpdateView.as_view(),
|
views.UserPublicKeyUpdateView.as_view(),
|
||||||
|
@ -48,37 +45,29 @@ urlpatterns = [
|
||||||
url(r'^user/(?P<pk>[0-9]+)/assets',
|
url(r'^user/(?P<pk>[0-9]+)/assets',
|
||||||
views.UserGrantedAssetView.as_view(),
|
views.UserGrantedAssetView.as_view(),
|
||||||
name='user-granted-asset'),
|
name='user-granted-asset'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/login-history',
|
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(),
|
||||||
views.UserDetailView.as_view(),
|
|
||||||
name='user-login-history'),
|
name='user-login-history'),
|
||||||
url(r'^user/export/',
|
url(r'^user/export/', views.UserExportView.as_view(),
|
||||||
views.UserExportView.as_view(),
|
|
||||||
name='user-export'),
|
name='user-export'),
|
||||||
url(r'^first-login/$',
|
url(r'^first-login/$', views.UserFirstLoginView.as_view(),
|
||||||
views.UserFirstLoginView.as_view(),
|
|
||||||
name='user-first-login'),
|
name='user-first-login'),
|
||||||
url(r'^user/import/$',
|
url(r'^user/import/$', views.UserBulkImportView.as_view(),
|
||||||
views.UserBulkImportView.as_view(),
|
|
||||||
name='user-import'),
|
name='user-import'),
|
||||||
url(r'^user/create$',
|
url(r'^user/create$', views.UserCreateView.as_view(),
|
||||||
views.UserCreateView.as_view(),
|
|
||||||
name='user-create'),
|
name='user-create'),
|
||||||
url(r'^user/(?P<pk>[0-9]+)/update$',
|
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(),
|
||||||
views.UserUpdateView.as_view(),
|
|
||||||
name='user-update'),
|
name='user-update'),
|
||||||
|
url(r'^user/update$', views.UserBulkUpdateView.as_view(),
|
||||||
|
name='user-bulk-update'),
|
||||||
|
|
||||||
# User group view
|
# User group view
|
||||||
url(r'^user-group$',
|
url(r'^user-group$', views.UserGroupListView.as_view(),
|
||||||
views.UserGroupListView.as_view(),
|
|
||||||
name='user-group-list'),
|
name='user-group-list'),
|
||||||
url(r'^user-group/(?P<pk>[0-9]+)$',
|
url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(),
|
||||||
views.UserGroupDetailView.as_view(),
|
|
||||||
name='user-group-detail'),
|
name='user-group-detail'),
|
||||||
url(r'^user-group/create$',
|
url(r'^user-group/create$', views.UserGroupCreateView.as_view(),
|
||||||
views.UserGroupCreateView.as_view(),
|
|
||||||
name='user-group-create'),
|
name='user-group-create'),
|
||||||
url(r'^user-group/(?P<pk>[0-9]+)/update$',
|
url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(),
|
||||||
views.UserGroupUpdateView.as_view(),
|
|
||||||
name='user-group-update'),
|
name='user-group-update'),
|
||||||
url(r'^user-group/(?P<pk>[0-9]+)/asset-permission$',
|
url(r'^user-group/(?P<pk>[0-9]+)/asset-permission$',
|
||||||
views.UserGroupAssetPermissionView.as_view(),
|
views.UserGroupAssetPermissionView.as_view(),
|
||||||
|
|
|
@ -38,7 +38,7 @@ __all__ = ['UserListView', 'UserCreateView', 'UserDetailView',
|
||||||
'UserAssetPermissionView', 'UserGrantedAssetView',
|
'UserAssetPermissionView', 'UserGrantedAssetView',
|
||||||
'UserExportView', 'UserBulkImportView', 'UserProfileView',
|
'UserExportView', 'UserBulkImportView', 'UserProfileView',
|
||||||
'UserProfileUpdateView', 'UserPasswordUpdateView',
|
'UserProfileUpdateView', 'UserPasswordUpdateView',
|
||||||
'UserPublicKeyUpdateView',
|
'UserPublicKeyUpdateView', 'UserBulkUpdateView',
|
||||||
]
|
]
|
||||||
|
|
||||||
logger = get_logger(__name__)
|
logger = get_logger(__name__)
|
||||||
|
@ -107,6 +107,46 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
class UserBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||||
|
model = User
|
||||||
|
form_class = forms.UserBulkUpdateForm
|
||||||
|
template_name = 'users/user_bulk_update.html'
|
||||||
|
success_url = reverse_lazy('users:user-list')
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
users_id = self.request.GET.get('users_id', '')
|
||||||
|
self.id_list = [int(i) for i in users_id.split(',') if i.isdigit()]
|
||||||
|
|
||||||
|
if kwargs.get('form'):
|
||||||
|
self.form = kwargs['form']
|
||||||
|
elif users_id:
|
||||||
|
self.form = self.form_class(
|
||||||
|
initial={'users': self.id_list}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.form = self.form_class()
|
||||||
|
return super(UserBulkUpdateView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
form = self.form_class(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
form.save()
|
||||||
|
return redirect(self.success_url)
|
||||||
|
else:
|
||||||
|
return self.get(request, form=form, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = {
|
||||||
|
'app': 'Assets',
|
||||||
|
'action': 'Bulk update asset',
|
||||||
|
'form': self.form,
|
||||||
|
'users_selected': self.id_list,
|
||||||
|
'users': User.objects.all(),
|
||||||
|
}
|
||||||
|
kwargs.update(context)
|
||||||
|
return super(UserBulkUpdateView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class UserDetailView(AdminUserRequiredMixin, DetailView):
|
class UserDetailView(AdminUserRequiredMixin, DetailView):
|
||||||
model = User
|
model = User
|
||||||
template_name = 'users/user_detail.html'
|
template_name = 'users/user_detail.html'
|
||||||
|
|
Loading…
Reference in New Issue