19_权限和分组
Posted nichengshishaonian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了19_权限和分组相关的知识,希望对你有一定的参考价值。
权限
登录、注销和登录限制:
登录
在使用authenticate
进行验证后,如果验证通过了。那么会返回一个 user 对象,拿到 user 对象后,可以使用 django.contrib.auth.login
进行登录。示例代码如下:
# 1. 登录
from django.contrib.auth import login
from django.contrib.auth import authenticate
# 切记: 这里一定不要定义视图函数名字为 login
def my_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponse('登录成功')
else:
return HttpResponse('用户名或密码错误')
return render(request, 'blog/my_login.html')
# 增加记住我, 这个勾选, 设置登录过期时间
from django.contrib.auth import login
# 切记: 这里一定不要定义视图函数名字为 login
def my_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
remember = request.POST.get('remember') # 记住我
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
if remember: # 如果勾选上了记住我, 我就让他的登录时间保持久一点
request.session.set_expiry(None)
else:
request.session.set_expiry(0) # 浏览器关闭, 登录就过期,因为设置了这个session 浏览器关闭就过期
return HttpResponse('登录成功')
else:
return HttpResponse('用户名或密码错误')
return render(request, 'blog/my_login.html')
注销
注销,或者说是退出登录,我们可以通过 django.contrib.auth.logout
。他会清理掉这个用户的 session
数据。示例代码如下:
from django.contrib.auth import logout
def my_logout(request):
logout(request)
return HttpResponse('成功退出登录')
登录限制
有时候,某个视图函数需要经过登录后才能访问。那么我们可以通过 django.contrib.auth.decorators.login_required
装饰器来实现。示例代码如下:
# 登录限制
from django.contrib.auth.decorators import login_required
@login_required(login_url='/blog/my_login/')
def my_limit_view(request):
return HttpResponse('这是个人中心,只有登录后才能访问我')
# settings.py
# 或者不指定 login_url 参数, 在settings.py 中配置 LOGIN_URL 变量
from django.urls import reverse_lazy, reverse
# LOGIN_URL = reverse_lazy('app_name:name')
LOGIN_URL = reverse_lazy('my_login')
权限
Django
中内置了权限的功能。他的权限都是针对表或者说是模型级别的。比如对某个模型的的数据是否可以进行增删改查操作。他不能针对数据级别的。比如对某个表中的某条数据能否进行增删改查操作(如果要实现数据级别的,考虑使用django-guardian
)。创建完一个模型后,针对这个模型默认就有三种权限,分别是增、删、改
。可以在执行完 migrate
命令后,查看数据库中的 auth_permission
表中的所有权限(select * from auth_permission;
)。
mysql> select * from auth_permission;
+----+---------------------------+-----------------+----------------------+
| id | name | content_type_id | codename |
+----+---------------------------+-----------------+----------------------+
| 1 | Can add log entry | 1 | add_logentry |
| 2 | Can change log entry | 1 | change_logentry |
| 3 | Can delete log entry | 1 | delete_logentry |
| 4 | Can view log entry | 1 | view_logentry |
| 5 | Can add permission | 2 | add_permission |
| 6 | Can change permission | 2 | change_permission |
| 7 | Can delete permission | 2 | delete_permission |
| 8 | Can view permission | 2 | view_permission |
| 9 | Can add group | 3 | add_group |
| 10 | Can change group | 3 | change_group |
| 11 | Can delete group | 3 | delete_group |
| 12 | Can view group | 3 | view_group |
| 13 | Can add user | 4 | add_user |
| 14 | Can change user | 4 | change_user |
| 15 | Can delete user | 4 | delete_user |
| 16 | Can view user | 4 | view_user |
| 17 | Can add content type | 5 | add_contenttype |
| 18 | Can change content type | 5 | change_contenttype |
| 19 | Can delete content type | 5 | delete_contenttype |
| 20 | Can view content type | 5 | view_contenttype |
| 21 | Can add session | 6 | add_session |
......
+----+---------------------------+-----------------+----------------------+
其中 codename
表示的是权限的名字,name
表示的是这个权限的作用。
通过定义模型添加权限
如果我们想要增加新的权限,比如查看某个模型的权限,那么我们可以在定义模型的时候在 Meta
中定义好。示例代码如下:
# 1. 通过定义模型添加权限 models.py
from django.db import models
from django.contrib.auth.models import User
class Article(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
author = models.ForeignKey(get_user_models(), on_delete=models.CASCADE)
# author = models.ForeignKey(User, on_delete=models.CASCADE)
class Meta:
permissions = [
('view_article', '看文章的权限')
]
通过代码添加权限
权限都是 django.contrib.auth.Permission
的实例。这个模型包含三个字段,name/codename/content_type(# content_type_id)
其中的content_type
表示这个 permission
是属于哪个 app 下的models。用 Permission
模型创建权限的代码如下:
# views.py
from django.contrib.auth.models import Permission, ContentType
from .models import Article
def add_permission(request):
content_type = ContentType.objects.get_for_model(Article)
permission = Permission.objects.create(name='可以编辑的权限', codename='edit_article', content_type=content_type)
return HttpResponse('添加权限成功')
然后在数据库中select * from auth_permission
就可以看到
114 | Can change article | 28 | change_article |
| 115 | Can delete article | 28 | delete_article |
| 116 | Can view article | 28 | view_article |
| 117 | 看文章的权限 | 28 | view2_article |
| 118 | 可以编辑的权限 | 28 | edit_article |
+-----+----------------------------+-----------------+-----------------------+
用户与权限管理
权限本身只是一个数据,必须和用户进行绑定,才能起到作用。 User
模型和权限之间的管理,可以通过以下几种方式来管理:
myuser.user_permissions.set(permission_list)
# 直接给定一个权限的列表myuser.user_permissions.add(permission, permission, ...)
# 一个个添加权限myuser.user_permissions.remover(permission, permission,...)
# 一个个删除权限myuser.user_permissions.clear()
# 清除权限myuser.has_perm(‘<app_name>.<codename>‘)
# 判断是否拥有某个权限。权限参数是一个字符串。 格式是app_name.codename
。myuser.has_perms([<app_name.<codename>, ...])
# 判断用户是否拥有某些权限myuser.get_all_permissions()
# 获取该用户所有的权限
示例代码如下:
# 用户与权限管理
def operate_permission(request):
user = User.objects.get(pk=4) # 拿到第一个用户
print(user)
content_type = ContentType.objects.get_for_model(Article) # Article 的所有权限
permissions = Permission.objects.filter(content_type=content_type) # 提取与与 文章相关的所有权限
for permission in permissions:
print(permission)
"""
blog | article | Can add article
blog | article | Can change article
blog | article | Can delete article
blog | article | 可以编辑的权限
blog | article | 看文章的权限
blog | article | Can view article"""
# user.user_permissions.set([])
user.user_permissions.set(permissions) # 给这个用户添加所有有关于 文章的权限
# user.user_permissions.add(permissions[0]) # 添加一个权限
# user.user_permissions.add(permissions[1], permissions[2])
# user.user_permissions.add(*permissions) # 也是添加permissions 的所有权限, 把他打散
user_p_all = user.get_all_permissions()
print(user_p_all)
for i in user_p_all:
print(i)
# user.user_permissions.clear() # 清除该用户的所有权限
# user.user_permissions.remove(permissions[0], permissions[2])
# user.user_permissions.remove(*permissions) # 删除permissions 中的所有权限
has_perm = user.has_perm('blog.view_article')
if has_perm:
print('这个用户有view_article权限')
else:
print('这个用户没有view_article权限')
return HttpResponse('用户与权限管理, 操作权限的视图函数')
权限限定装饰器
使用 django.contrib.auth.decorators.permission_required
可以非常方便的检查用户是否拥有这个权限,如果拥有,那么就可以进入到指定的视图函数中,如果不拥有,那么就会报一个 400 错误。 示例代码如下:
# 权限限定装饰器
from django.contrib.auth.decorators import permission_required
# @permission_required('blog.view_article', login_url='/blog/my_login/') # 要登录,并且有 该权限, 如果登录了没有该权限, 也会返回登录页面
@permission_required('blog.view_article', login_url='/blog/my_login/', raise_exception=True) # 没有登录和没有该权限 就会返回一个403 (403 forbidden 页面) 页面
def my_view(request):
return HttpResponse('只有拥有 view_article 权限才能看到我')
def create_user_test(request):
"""创建一个普通用户, 和添加几个权限"""
# User.objects.create_user(username='cheng', password='5201314yanyan', email='1599962587@qq.com')
user = User.objects.get(username='cheng')
# print(user.username)
# content_type = ContentType.objects.get_for_model(Article)
# permissions = Permission.objects.filter(content_type=content_type)
# user.user_permissions.add(*permissions)
user.user_permissions.clear()
print(user.has_perm('blog.view_article'))
return HttpResponse('创建用户成功, 并为这个用户添加几个权限')
def add_article(request):
# 1. 判断用户是否登录了
if request.user.is_authenticated:
print('已经登录了')
if request.user.has_perm('blog.add_article'):
return HttpResponse('这是添加文章的页面')
else:
return HttpResponse('你没有访问该页面的权限')
# return HttpResponse('你没有登录,请先登录后再访问')
print('你没有登录,请先登录后再访问')
return redirect(reverse('my_login'))
分组:
权限有很多,一个模型就有最少三个权限,如果一些用户拥有相同的权限,那么每次都要重复添加。这时候分组就可以帮我们解决这个问题,我们可以把一些权限归类,然后添加到某个分组中,之后两把和需要赋予这些权限的用户添加到这个分组中,那么就比较好管理了。分组我们使用的是 django.contrib.auth.models.Group
模型,每个分组拥有 id
和 name
两个字段, 该模型在数据库被映射为 auth_group
数据表。
分组操作:
Group.objects.create(group_name)
: # 创建分组group.permissions
: 某个分组上的权限。多对多的联系
*group.permissions.add
: 添加权限
*group.permissions.remover
: 移除权限
*group.permissions.clear
: 清除所有权限
*user.get_group_permissions()
: 获取用户所属级的权限user.groups
: 某个用户上的所有分组。多对多的关系
# 分组
from django.contrib.auth.models import Group
def operate_group(request):
# 添加一个分组 并赋予权限
"""
article_group = Group.objects.create(name='文章管理组')
content_type = ContentType.objects.get_for_model(Article)
permissions = Permission.objects.filter(content_type=content_type)
article_group.permissions.set(permissions)
article_group.save()
"""
# 给这个分组添加 用户
# """
group = Group.objects.filter(name='文章管理组').first() #
user = User.objects.last()
# user.groups.add(group) # 把user 添加到 group 这个分组中去
# user.save()
permissions = user.get_all_permissions() # 获取该用户的所有权限
permissions = user.get_group_permissions() # 该用户所属分组的所有权限
for i in permissions:
print(i)
user_groups = user.groups
print(user_groups)
# """
# 判断用户权限 user.has_perm
# 1. 首先判断user.permissions下有没有这个权限,如果有则返回True,
# 如果没有, 那么就会判断他的分组下有没有这个权限
return HttpResponse('分组操作')
在模板中使用权限:
在 settings.TEMPLATES.OPTIONS.context_processors
下, 因为添加了 django.contrib.auth.context_processors.auth
上下文处理器,因此在模板中可以直接通过 perms
来获取用户的所有权限。示例代码如下:
# perms.app名称.权限名称
{% if perms.blog.add_article %}
<a href='/blog/article/add/'>添加文章</a>
{% endif %}
{% if perms.blog %}说明有blog app 只要其模型下的某一个权限就能看到我 的权限{% endif %}
{% if permis.blog.add_student %}说明有 blog app 的 student模型 add 权限{% endif %}
以上是关于19_权限和分组的主要内容,如果未能解决你的问题,请参考以下文章
Cg入门19:Fragment shader - 片段级模型动态变色
19 01 11 javascript ?????????????????????(???????????????) ??????????????????????????????(代码片段