Commit cf15b7ea authored by ibuler's avatar ibuler

Add UserGroup some View

parent 651e8999
This diff is collapsed.
...@@ -4600,4 +4600,6 @@ body.skin-3 { ...@@ -4600,4 +4600,6 @@ body.skin-3 {
border-width: 1px border-width: 1px
} }
th a {
color: #676a6c;
}
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li class="group"><a href="{% url 'users:user-list' %}">用户列表</a></li> <li class="group"><a href="{% url 'users:user-list' %}">用户列表</a></li>
<li class="user"><a href="#">用户组列表</a></li> <li class="user"><a href="{% url 'users:usergroup-list' %}">用户组列表</a></li>
</ul> </ul>
</li> </li>
<li id=""> <li id="">
......
...@@ -26,3 +26,10 @@ class UserUpdateForm(ModelForm): ...@@ -26,3 +26,10 @@ class UserUpdateForm(ModelForm):
'phone', 'enable_2FA', 'role', 'date_expired', 'comment', 'phone', 'enable_2FA', 'role', 'date_expired', 'comment',
] ]
class UserGroupForm(ModelForm):
class Meta:
model = UserGroup
fields = [
'name', 'comment',
]
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime import datetime
from django.utils import timezone
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser, Permission from django.contrib.auth.models import AbstractUser, Permission
from django.contrib.auth.models import Group as AbstractGroup from django.contrib.auth.models import Group as AbstractGroup
...@@ -55,6 +55,24 @@ class UserGroup(models.Model): ...@@ -55,6 +55,24 @@ class UserGroup(models.Model):
group = cls(name='所有人', comment='所有人默认都在用户组', created_by='System') group = cls(name='所有人', comment='所有人默认都在用户组', created_by='System')
group.save() group.save()
@classmethod
def generate_fake(cls, count=100):
from random import seed, randint, choice
import forgery_py
from django.db import IntegrityError
seed()
for i in range(count):
group = cls(name=forgery_py.name.full_name(),
comment=forgery_py.lorem_ipsum.sentence(),
created_by=choice(User.objects.all()).username
)
try:
group.save()
except IntegrityError:
print('Error continue')
continue
class User(AbstractUser): class User(AbstractUser):
username = models.CharField(max_length=20, unique=True, verbose_name='用户名', help_text='* required') username = models.CharField(max_length=20, unique=True, verbose_name='用户名', help_text='* required')
...@@ -71,7 +89,37 @@ class User(AbstractUser): ...@@ -71,7 +89,37 @@ class User(AbstractUser):
public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥') public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥')
comment = models.TextField(max_length=200, blank=True, verbose_name='描述') comment = models.TextField(max_length=200, blank=True, verbose_name='描述')
created_by = models.CharField(max_length=30, default='') created_by = models.CharField(max_length=30, default='')
date_expired = models.DateTimeField(default=datetime.datetime.max, verbose_name='有效期') date_expired = models.DateTimeField(default=timezone.now()+timezone.timedelta(days=365*70), verbose_name='有效期')
class Meta: class Meta:
db_table = 'user' db_table = 'user'
@classmethod
def generate_fake(cls, count=100):
from random import seed, randint, choice
import forgery_py
from django.contrib.auth.hashers import make_password
from django.db import IntegrityError
seed()
for i in range(count):
user = cls(username=forgery_py.internet.user_name(True),
email=forgery_py.internet.email_address(),
name=forgery_py.name.full_name(),
password=make_password(forgery_py.lorem_ipsum.word()),
role=choice(Role.objects.all()),
wechat=forgery_py.internet.user_name(True),
comment=forgery_py.lorem_ipsum.sentence(),
created_by=choice(cls.objects.all()).username,
)
try:
user.save()
except IntegrityError:
print('Error continue')
continue
user.groups.add(choice(UserGroup.objects.all()))
user.save()
{% extends 'base.html' %}
{% load static %}
{% load bootstrap %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/chosen/chosen.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/chosen/chosen.jquery.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>填写用户组信息</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" id="userForm" class="form-horizontal" action="" >
{% csrf_token %}
{{ form.name|bootstrap_horizontal }}
<div class="form-group">
<label for="users" class="col-sm-2 control-label">用户</label>
<div class="col-sm-8">
<select name="users" id="users" data-placeholder="选择用户" class="chosen-select form-control m-b" multiple tabindex="2">
{% for user in users %}
<option value="{{ user.id }}">{{ user.name }}</option>
{% endfor %}
</select>
<span class="help-block m-b-none">用户和用户组必选一个</span>
</div>
</div>
{{ form.comment|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">取消</button>
<button id="submit_button" class="btn btn-primary" type="submit">确认保存</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$(document).ready(function () {
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : {allow_single_deselect:true},
'.chosen-select-no-single' : {disable_search_threshold:10},
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
'.chosen-select-width' : {width:"95%"}
};
for (var selector in config) {
$(selector).chosen(config[selector]);
}
})
</script>
{% endblock %}
\ No newline at end of file
{% extends 'base.html' %}
{% load common_tags %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5> 查看用户组 </h5>
<div class="ibox-tools">
<a class="collapise-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="">
<a href="{% url 'users:usergroup-add' %}" class="btn btn-sm btn-primary "> 添加用户组 </a>
<a id="del_btn" class="btn btn-sm btn-danger "> 删除所选 </a>
<form id="search_form" method="get" action="{% url 'users:user-list' %}" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="名称" value="{{ keyword }}">
<div class="input-group-btn">
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
</div>
<table class="table table-striped table-bordered table-hover " id="editable" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th>
<th class="text-center"><a href="{% url 'users:usergroup-list' %}?sort=name">名称</a></th>
<th class="text-center">用户数量</th>
<th class="text-center">资产数量</th>
<th class="text-center">描述</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
{% for usergroup in usergroup_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="checked" value="{{ usergroup.id }}">
</td>
<td class="text-center">
<a href="{% url 'users:usergroup-detail' pk=usergroup.id %}">
{{ usergroup.name }}
</a>
</td>
<td class="text-center">{{ usergroup.user_set.all|length }}</td>
<td class="text-center">数量</td>
<th class="text-center">{{ usergroup.comment|truncatewords:8 }}</th>
<td class="text-center">
<a href="{% url 'users:usergroup-edit' pk=usergroup.id %}?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'users:usergroup-delete' pk=usergroup.id %}?id={{ user.id }}" class="btn btn-xs btn-danger del">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include '_pagination.html' %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
from django.conf.urls import url from django.conf.urls import url
from .views import UserListView, UserAddView, UserUpdateView, UserDeleteView, UserDetailView from .views import UserListView, UserAddView, UserUpdateView, UserDeleteView, UserDetailView
from .views import UserGroupListView, UserGroupAddView, UserGroupUpdateView, UserGroupDeleteView, UserGroupDetailView
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
url(r'^$', UserListView.as_view(), name='user-list'), url(r'^user/$', UserListView.as_view(), name='user-list'),
url(r'^(?P<pk>[0-9]+)/$', UserDetailView.as_view(), name='user-detail'), url(r'^user/(?P<pk>[0-9]+)/$', UserDetailView.as_view(), name='user-detail'),
url(r'^add/$', UserAddView.as_view(), name='user-add'), url(r'^user/add/$', UserAddView.as_view(), name='user-add'),
url(r'^(?P<pk>[0-9]+)/edit/$', UserUpdateView.as_view(), name='user-edit'), url(r'^user/(?P<pk>[0-9]+)/edit/$', UserUpdateView.as_view(), name='user-edit'),
url(r'^(?P<pk>[0-9]+)/delete/$', UserDeleteView.as_view(), name='user-delete'), url(r'^user/(?P<pk>[0-9]+)/delete/$', UserDeleteView.as_view(), name='user-delete'),
url(r'^usergroup/$', UserGroupListView.as_view(), name='usergroup-list'),
url(r'^usergroup/(?P<pk>[0-9]+)/$', UserGroupDetailView.as_view(), name='usergroup-detail'),
url(r'^usergroup/add/$', UserGroupAddView.as_view(), name='usergroup-add'),
url(r'^usergroup/(?P<pk>[0-9]+)/edit/$', UserGroupUpdateView.as_view(), name='usergroup-edit'),
url(r'^usergroup/(?P<pk>[0-9]+)/delete/$', UserGroupDeleteView.as_view(), name='usergroup-delete'),
] ]
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.db.models import Q from django.db.models import Q
from django.views.generic.list import ListView from django.views.generic.list import ListView
...@@ -7,7 +8,7 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView ...@@ -7,7 +8,7 @@ from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from .models import User, UserGroup, Role from .models import User, UserGroup, Role
from .forms import UserAddForm, UserUpdateForm from .forms import UserAddForm, UserUpdateForm, UserGroupForm
class UserListView(ListView): class UserListView(ListView):
...@@ -71,12 +72,6 @@ class UserUpdateView(UpdateView): ...@@ -71,12 +72,6 @@ class UserUpdateView(UpdateView):
user.set_password(password) user.set_password(password)
return super(UserUpdateView, self).form_valid(form) return super(UserUpdateView, self).form_valid(form)
def form_invalid(self, form):
print(self.request.FILES)
print(form['avatar'].value())
print(form.errors)
return super(UserUpdateView, self).form_invalid(form)
class UserDeleteView(DeleteView): class UserDeleteView(DeleteView):
model = User model = User
...@@ -94,3 +89,61 @@ class UserDetailView(DetailView): ...@@ -94,3 +89,61 @@ class UserDetailView(DetailView):
groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()] groups = [group for group in UserGroup.objects.iterator() if group not in self.object.groups.iterator()]
context.update({'path1': '用户管理', 'path2': '用户详情', 'title': '用户详情', 'groups': groups}) context.update({'path1': '用户管理', 'path2': '用户详情', 'title': '用户详情', 'groups': groups})
return context return context
class UserGroupListView(ListView):
model = UserGroup
paginate_by = 20
context_object_name = 'usergroup_list'
template_name = 'users/usergroup_list.html'
ordering = '-date_added'
def get_queryset(self):
self.queryset = super(UserGroupListView, self).get_queryset()
self.keyword = keyword = self.request.GET.get('keyword', '')
self.sort = sort = self.request.GET.get('sort')
if keyword:
self.queryset = self.queryset.filter(name__icontains=keyword)
if sort:
self.queryset = self.queryset.order_by(sort)
return self.queryset
def get_context_data(self, **kwargs):
context = super(UserGroupListView, self).get_context_data(**kwargs)
context.update({'path1': '用户管理', 'path2': '用户组列表', 'title': '用户组列表', 'keyword': self.keyword})
return context
class UserGroupAddView(CreateView):
model = UserGroup
form_class = UserGroupForm
template_name = 'users/usergroup_add.html'
success_url = reverse_lazy('users:usergroup-list')
def get_context_data(self, **kwargs):
context = super(UserGroupAddView, self).get_context_data(**kwargs)
users = User.objects.all()
context.update({'path1': '用户管理', 'path2': '用户组添加', 'title': '用户组添加', 'users': users})
return context
def form_valid(self, form):
usergroup = form.save()
users_id_list = self.request.POST.getlist('users', [])
users = [get_object_or_404(User, id=user_id) for user_id in users_id_list]
usergroup.created_by = self.request.user.username or 'Admin'
usergroup.user_set.add(*tuple(users))
usergroup.save()
return super(UserGroupAddView, self).form_valid(form)
class UserGroupUpdateView(UpdateView):
pass
class UserGroupDetailView(DetailView):
pass
class UserGroupDeleteView(DeleteView):
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment