Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
9493fb07
Commit
9493fb07
authored
Aug 14, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add user list view
parent
9303415b
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
256 additions
and
18 deletions
+256
-18
_pagination.html
apps/templates/_pagination.html
+57
-0
0002_auto_20160814_1237.py
apps/users/migrations/0002_auto_20160814_1237.py
+57
-0
models.py
apps/users/models.py
+33
-12
example.html
apps/users/templates/example.html
+0
-0
example.html
apps/users/templates/users/example.html
+0
-0
user_list.html
apps/users/templates/users/user_list.html
+84
-0
urls.py
apps/users/urls.py
+6
-2
views.py
apps/users/views.py
+16
-4
requirements.txt
requirements.txt
+3
-0
No files found.
apps/templates/_pagination.html
0 → 100644
View file @
9493fb07
{% 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>
apps/users/migrations/0002_auto_20160814_1237.py
0 → 100644
View file @
9493fb07
# -*- 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
'
),
),
]
apps/users/models.py
View file @
9493fb07
...
...
@@ -2,8 +2,10 @@
from
__future__
import
unicode_literals
import
datetime
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
...
...
@@ -16,10 +18,28 @@ class Role(AbstractGroup):
class
Meta
:
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
):
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
'组名称'
,
help_text
=
'请输入组名称'
)
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
'描述'
,
help_text
=
'请输入用户组描述'
)
name
=
models
.
CharField
(
max_length
=
100
,
unique
=
True
,
verbose_name
=
'组名称'
)
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
'描述'
)
date_added
=
models
.
DateTimeField
(
auto_now_add
=
True
)
created_by
=
models
.
CharField
(
max_length
=
100
)
...
...
@@ -32,16 +52,17 @@ class UserGroup(models.Model):
class
User
(
AbstractUser
):
groups
=
models
.
ManyToManyField
(
UserGroup
)
avatar
=
models
.
ImageField
(
verbose_name
=
'头像'
,
default
=
''
)
wechat
=
models
.
CharField
(
max_length
=
30
,
verbose_name
=
'微信'
)
phone
=
models
.
CharField
(
max_length
=
20
,
verbose_name
=
'手机
'
)
avatar
=
models
.
ImageField
(
verbose_name
=
'头像'
,
blank
=
True
)
wechat
=
models
.
CharField
(
max_length
=
30
,
blank
=
True
,
verbose_name
=
'微信'
)
phone
=
models
.
CharField
(
max_length
=
20
,
blank
=
True
,
verbose_name
=
'手机号
'
)
enable_2FA
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'启用二次验证'
)
secret_key_2FA
=
models
.
CharField
(
max_length
=
16
)
role
=
models
.
ForeignKey
(
Role
,
on_delete
=
models
.
PROTECT
)
private_key
=
models
.
CharField
(
max_length
=
5000
)
# ssh key max length 4096 bit
public_key
=
models
.
CharField
(
max_length
=
1000
)
created_by
=
models
.
CharField
(
max_length
=
30
)
date_expired
=
models
.
DateTimeField
()
secret_key_2FA
=
models
.
CharField
(
max_length
=
16
,
blank
=
True
)
role
=
models
.
ForeignKey
(
Role
,
on_delete
=
models
.
PROTECT
,
verbose_name
=
'角色'
)
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
,
blank
=
True
,
verbose_name
=
'公钥'
)
comment
=
models
.
CharField
(
max_length
=
200
,
blank
=
True
,
verbose_name
=
'描述'
)
created_by
=
models
.
CharField
(
max_length
=
30
,
default
=
''
)
date_expired
=
models
.
DateTimeField
(
default
=
datetime
.
datetime
.
max
)
@property
def
name
(
self
):
...
...
apps/users/templates/example.html
deleted
100644 → 0
View file @
9303415b
apps/users/templates/users/example.html
deleted
100644 → 0
View file @
9303415b
apps/users/templates/users/user_list.html
0 → 100644
View file @
9493fb07
{% 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 %}
apps/users/urls.py
View file @
9493fb07
from
django.conf.urls
import
url
from
.
import
views
from
.views
import
UserListView
app_name
=
'users'
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'
),
]
apps/users/views.py
View file @
9493fb07
from
django.shortcuts
import
render
from
django.views.generic.base
import
TemplateView
# ~*~ coding: utf-8 ~*~
from
django.views.generic.list
import
ListView
from
.models
import
User
,
UserGroup
class
UserListView
(
ListView
):
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
def
hello
(
request
):
return
render
(
request
,
'base.html'
)
requirements.txt
View file @
9493fb07
django
==1.10
pillow
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment