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模型和权限之间的管理,可以通过以下几种方式来管理:

  1. myuser.user_permissions.set(permission_list) # 直接给定一个权限的列表
  2. myuser.user_permissions.add(permission, permission, ...) # 一个个添加权限
  3. myuser.user_permissions.remover(permission, permission,...) # 一个个删除权限
  4. myuser.user_permissions.clear() # 清除权限
  5. myuser.has_perm(‘<app_name>.<codename>‘) # 判断是否拥有某个权限。权限参数是一个字符串。 格式是 app_name.codename
  6. myuser.has_perms([<app_name.<codename>, ...]) # 判断用户是否拥有某些权限
  7. 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 模型,每个分组拥有 idname 两个字段, 该模型在数据库被映射为 auth_group 数据表。

分组操作:

  1. Group.objects.create(group_name) : # 创建分组
  2. group.permissions: 某个分组上的权限。多对多的联系
    * group.permissions.add : 添加权限
    * group.permissions.remover : 移除权限
    * group.permissions.clear : 清除所有权限
    * user.get_group_permissions() : 获取用户所属级的权限
  3. 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_权限和分组的主要内容,如果未能解决你的问题,请参考以下文章

19_权限修饰符

19_权限修饰符

Cg入门19:Fragment shader - 片段级模型动态变色

活动在片段上出现的权限对话框中被破坏

19 01 11 javascript ?????????????????????(???????????????) ??????????????????????????????(代码片段

Django之权限和分组