Add user list view

pull/530/head
ibuler 2016-08-14 17:21:04 +08:00
parent 9303415b89
commit 9493fb07cb
9 changed files with 255 additions and 18 deletions

View File

@ -0,0 +1,57 @@
{% if is_paginated %}
<div class="row">
<div class="col-sm-6">
<div class="dataTables_info" id="editable_info" role="status" aria-live="polite">
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ paginator.count }} entries
</div>
</div>
<div class="col-sm-6">
<div class="dataTables_paginate paging_simple_numbers" id="editable_paginate">
<ul class="pagination" style="margin-top: 0; float: right">
{% if page_obj.has_previous %}
<li class="paginate_button previous" aria-controls="editable" tabindex="0"
id="editable_previous">
<a class="page" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="paginate_button active" aria-controls="editable" tabindex="0">
<a class="page" href="?page={{ page_obj.number }}" title="第{{ page_obj.number }}页">{{ page_obj.number }}</a>
</li>
{% if page_obj.has_next %}
<li class="paginate_button next" aria-controls="editable" tabindex="0" id="editable_next">
<a class="page" href="?page={{ page_obj.next_page_number }}">Next</a>
</li>
{% endif %}
</ul>
</div>
</div>
</div>
{% endif %}
<script>
function sleep(n) { //n表示的毫秒数
var start = new Date().getTime();
while (true) if (new Date().getTime() - start > n) break;
}
$(document).ready(function () {
$('.page').click(function () {
var searchStr = location.search;
var old_href = $(this).attr('href').replace('?', '');
var searchArray = searchStr.split('&');
if (searchStr == '') {
searchStr = '?page=1'
}
if (searchStr.indexOf('page') >= 0) {
searchArray.pop();
}
searchArray.push(old_href);
if (searchArray.length > 1) {
$(this).attr('href', searchArray.join('&'));
}
})
});
</script>

View File

@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-14 04:37
from __future__ import unicode_literals
import datetime
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='comment',
field=models.CharField(blank=True, max_length=200, verbose_name='\u63cf\u8ff0'),
),
migrations.AlterField(
model_name='user',
name='date_expired',
field=models.DateTimeField(default=datetime.datetime(9999, 12, 31, 23, 59, 59, 999999)),
),
migrations.AlterField(
model_name='user',
name='phone',
field=models.CharField(max_length=20, verbose_name='\u624b\u673a\u53f7'),
),
migrations.AlterField(
model_name='user',
name='private_key',
field=models.CharField(max_length=5000, verbose_name='ssh\u79c1\u94a5'),
),
migrations.AlterField(
model_name='user',
name='public_key',
field=models.CharField(max_length=1000, verbose_name='\u516c\u94a5'),
),
migrations.AlterField(
model_name='user',
name='role',
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='users.Role', verbose_name='\u89d2\u8272'),
),
migrations.AlterField(
model_name='usergroup',
name='comment',
field=models.TextField(blank=True, verbose_name='\u63cf\u8ff0'),
),
migrations.AlterField(
model_name='usergroup',
name='name',
field=models.CharField(max_length=100, unique=True, verbose_name='\u7ec4\u540d\u79f0'),
),
]

View File

@ -2,8 +2,10 @@
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser 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
@ -16,10 +18,28 @@ class Role(AbstractGroup):
class Meta: class Meta:
db_table = 'role' db_table = 'role'
@classmethod
def init(cls):
roles = {
'Administrator': {'permissions': Permission.objects.all(), 'comment': '管理员'},
'User': {'permissions': [], 'comment': '用户'},
'Auditor': {'permissions': Permission.objects.filter(content_type__app_label='audits'),
'comment': '审计员'},
}
for role in cls.objects.all():
role.permissions.clear()
cls.objects.all().delete()
for role_name, props in roles.items():
role = cls.objects.create(name=role_name, comment=props.get('comment', ''))
role.permissions = props.get('permissions', [])
class UserGroup(models.Model): class UserGroup(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name='组名称', help_text='请输入组名称') name = models.CharField(max_length=100, unique=True, verbose_name='组名称')
comment = models.TextField(blank=True, verbose_name='描述', help_text='请输入用户组描述') comment = models.TextField(blank=True, verbose_name='描述')
date_added = models.DateTimeField(auto_now_add=True) date_added = models.DateTimeField(auto_now_add=True)
created_by = models.CharField(max_length=100) created_by = models.CharField(max_length=100)
@ -32,16 +52,17 @@ class UserGroup(models.Model):
class User(AbstractUser): class User(AbstractUser):
groups = models.ManyToManyField(UserGroup) groups = models.ManyToManyField(UserGroup)
avatar = models.ImageField(verbose_name='头像', default='') avatar = models.ImageField(verbose_name='头像', blank=True)
wechat = models.CharField(max_length=30, verbose_name='微信') wechat = models.CharField(max_length=30, blank=True, verbose_name='微信')
phone = models.CharField(max_length=20, verbose_name='手机') phone = models.CharField(max_length=20, blank=True, verbose_name='手机')
enable_2FA = models.BooleanField(default=False, verbose_name='启用二次验证') enable_2FA = models.BooleanField(default=False, verbose_name='启用二次验证')
secret_key_2FA = models.CharField(max_length=16) secret_key_2FA = models.CharField(max_length=16, blank=True)
role = models.ForeignKey(Role, on_delete=models.PROTECT) role = models.ForeignKey(Role, on_delete=models.PROTECT, verbose_name='角色')
private_key = models.CharField(max_length=5000) # ssh key max length 4096 bit private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit
public_key = models.CharField(max_length=1000) public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥')
created_by = models.CharField(max_length=30) comment = models.CharField(max_length=200, blank=True, verbose_name='描述')
date_expired = models.DateTimeField() created_by = models.CharField(max_length=30, default='')
date_expired = models.DateTimeField(default=datetime.datetime.max)
@property @property
def name(self): def name(self):

View File

@ -0,0 +1,84 @@
{% extends 'base.html' %}
{% 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="#" 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="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" id="search_input" name="keyword" placeholder="Search">
<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">姓名</th>
<th class="text-center">用户名</th>
<th class="text-center">角色</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 user in user_list %}
<tr class="gradeX">
<td class="text-center">
<input type="checkbox" name="checked" value="{{ user.id }}">
</td>
<td class="text-center">
<a href="{% url 'users:user-detail' pk=user.id %}?id={{ user.id }}">
{{ user.name }}
</a>
</td>
<td class="text-center">{{ user.username }}</td>
<td class="text-center">{{ user.role.name }}</td>
<td class="text-center" title="{% for user_group in user.group.all %} {{ user_group.name }} {% endfor %}"> {{ user.group.all }} </td>
<th class="text-center">{{ user.name }}</th>
<td class="text-center">{{ user.name }}</td>
<td class="text-center">
<a href="{% url 'users:user-edit' pk=user.id %}?id={{ user.id }}" class="btn btn-xs btn-info">编辑</a>
<a href="{% url 'users:user-delete' pk=user.id %}?id={{ user.id }}" class="btn btn-xs btn-danger del {% if user.username == 'admin' %} disabled {% endif %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include '_pagination.html' %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -1,8 +1,12 @@
from django.conf.urls import url from django.conf.urls import url
from . import views
from .views import UserListView
app_name = 'users' app_name = 'users'
urlpatterns = [ urlpatterns = [
url(r'hello/$', views.hello, name='hello'), url(r'^$', UserListView.as_view(), name='user-list'),
url(r'^(?P<pk>[0-9]+)/$', UserListView.as_view(), name='user-detail'),
url(r'^(?P<pk>[0-9]+)/edit/$', UserListView.as_view(), name='user-edit'),
url(r'^(?P<pk>[0-9]+)/delete/$', UserListView.as_view(), name='user-delete'),
] ]

View File

@ -1,6 +1,18 @@
from django.shortcuts import render # ~*~ coding: utf-8 ~*~
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from .models import User, UserGroup
def hello(request): class UserListView(ListView):
return render(request, 'base.html') model = User
paginate_by = 10
context_object_name = 'user_list'
template_name = 'users/user_list.html'
def get_context_data(self, **kwargs):
context = super(UserListView, self).get_context_data(**kwargs)
context.update({'path1': '用户管理', 'path2': '用户列表', 'title': '用户列表'})
return context

View File

@ -0,0 +1,2 @@
django==1.10
pillow