关于 Django 的权限管理
Django
的权限管理都是基于 admin
的用户 user
的,admin 的 user 模型有以下几个字段应该子解:
字段名 | 说明 |
---|---|
username | 必选。少于等于 30 个字符。 用户名可以包含字母、数字、_、@、+、.和- 字符。 |
first_name | 可选。 少于等于 30 个字符。 |
last_name | 可选。少于 30 个字符。 |
可选。邮箱地址。 | |
password | 必选。 密码的哈希及元数据。(Django 不保存原始密码)。原始密码可以无限长而且可以包含任意字符。参见密码相关的文档。 |
groups | 与 Group 之间的多对多关系。 |
user_permissions | 与 Permission 之间的多对多关系。 |
is_staff | 布尔值。指示用户是否可以访问 Admin 站点。 |
is_active | 布尔值。指示用户的账号是否激活。 |
is_superuser | 布尔值。指定这个用户拥有所有的权限而不需要给他们分配明确的权限。 |
last_login | 用户最后一次登录的时间。 |
date_joined | 账户创建的时间。当账号创建时,默认设置为当前的 date/time。 |
在一些视图里我们需要做一些限制,
- 如一些操作必须是后台用户,那么我们需要检测是否已做后台登录;
- 又如一些操作需要有操作相应表的权限(修改或删除)我们需要检测当前用户是否有相应权限
- 再如一些操作需要检查是否是系统管理员操作的
这些都是基于 Django
的权限认证管理的
权限装饰器
在 Django
视图里我们也可很方便的应用装饰器来对视图权限进行限制
1. 限制必须后台登录用户才可以操作
from django.contrib.auth.decorators import login_required
@login_required
def my_view(request):
...
2. 限制后台用户必须有指定的权限才可以操作
from django.contrib.auth.decorators import permission_required
@permission_required('polls.can_vote')
def my_view(request):
...
或者一个元组
@permission_required(('polls.can_open', 'polls.can_edit'))
def my_view(request):
...
3. 限制针对 User 的指定验证通过才可以操作
from django.contrib.auth.decorators import user_passes_test
def email_check(user):
return user.email.endswith('@example.com')
@user_passes_test(email_check)
def my_view(request):
...
自己做的一个系统管理员认证
from django.contrib.auth.decorators import user_passes_test
def superuser_check(user):
return user.is_superuser
@user_passes_test(superuser_check)
def my_view(request):
...
4. 权限认证装饰器从属关系
事实上上述的三种认证方式里 login_required
、 permission_required
都是基于 user_passes_test
的
- user_passes_test
- login_required
- permission_required
5. 关于 user_passes_test
下面我们重点来说说 user_passes_test
来看一下 user_passes_test
的装饰器原型
def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
...
这里边几个参数说明一下:
test_func
: 是自定义的验证函数,参数为后台用户的 user
,在实际调用时会传递给它 request.user
,
因此我们在验证函数里只要基于 user
来进行即可。
如:
def superuser_check(user):
return user.is_superuser
login_url
: 是后台登录页面的地址,未指定时其值是 settings.py
里的 LOGIN_URL
值,
而 LOGIN_URL
未设置时,其值是: /account/loing/
。所以我们需要按实际设置一下 LOGIN_URL
值
文件: settings.py
LOGIN_URL = '/admin/login/'
redirect_field_name
:转向链接的变量名,默认为 next
,
形式如: http://127.0.0.1:8000/admin/login/?next=/log/restore_history/15/
表示后台登录后要跳转的路径。
上面这个例子甚至可以更进一步简化为:
@user_passes_test(lambda u: u.is_superuser)
def my_view(request):
...
这是很好玩的一种方式。
6. 新建 superuser_required
装饰器
对于 superuser
认证的装饰器,我们还可以参考 login_required
进一步修改,新建一个自己的 superuser_required
装饰器。
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import REDIRECT_FIELD_NAME
def superuser_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
actual_decorator = user_passes_test(
lambda u: u.is_superuser,
login_url=login_url,
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
@superuser_required
def my_view(request):
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论