• 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 %}
    
    
  • 相关阅读:
    mock数据
    Vuex
    React生命周期
    Vue基础知识
    前端面试题
    NodeJS巅峰之作
    Oracle数据库
    CSS Bootstrap jsp开发 前端遇到的一些问题。
    如何寻找node.js 与win7兼容的版本?eclipse中引入bootstrap。
    Window 常用命令
  • 原文地址:https://www.cnblogs.com/nichengshishaonian/p/11523564.html
Copyright © 2020-2023  润新知