Django--权限信息操作

一 . 权限控制

  表结构的设计

    rbca(Role Based Access Control)  基于角色的权限控制

    3个model  5张表

class User(models.Model):
    # 用户表
    username = models.CharField(max_length=16)
    password = models.CharField(max_length=16)
    # 多对多的外键一般写在查询方便的那一边
    roles = models.ManyToManyField('Role', verbose_name='用户和角色关系表',blank=True)

class Role(models.Model):
    # 角色表
    username = models.CharField('角色',max_length=16)
    permissions = models.ManyToManyField('Permission', verbose_name='角色和权限关系表', blank=True)

class Permission(models.Model):
    # 权限表
    url = models.CharField('权限', max_length=64)
    title = models.CharField('标题', max_length=16)

 

      

# 权限表里面的url一定要加上 / / , 这样用正则的时候才能匹配成功

  

 

二 . 在admin中对表进行操作

   

# 创建超级用户的命令
python manage.py createsuperuser

# 然后在admin文件中创建表
from django.contrib import admin
admin.site.register(models.Permission)
admin.site.register(models.User)
admin.site.register(models.Role

 

 

  登录admin,样式不是我们想要的,我们需要进行一下操作

  

 

 然后在admin中写上:

  

  修改之后的结果

  

  还可以在展示页面上直接对字段进行编辑

  

  展示结果

  

 

三 . 权限控制的流程

  其实我们控制权限的实质就是让某些人能访问特定的url

   我们需要把权限控制的验证写到中间件中去

# 视图函数
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        obj = models.User.objects.filter(username=username, password=password).first()
        if not obj:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
        # 跨表查询用双下划线  ORM获取到权限信息 过滤掉权限为空的 去重  
        permission_query = obj.roles.filter(permissions__url__isnull=False).values('permissions__url', 'permissions__title').distinct()

        # session的值需要是可序列化的, 需要把QuerySet变成列表
        request.session['permission'] = list(permission_query)
        request.session['is_login'] = True
        return redirect('index')
    return render(request,'login.html')

 

 

 1 from django.utils.deprecation import MiddlewareMixin
 2 from django.shortcuts import HttpResponse, redirect
 3 from django.conf import settings
 4 import re
 5 class RbacMiddleWare(MiddlewareMixin):
 6     def process_request(self,request):
 7         # 获取当前访问的页面
 8         url = request.path
 9 
10         # 白名单
11         for i in settings.WHITE_LIST:
12             # match 匹配上得到一个对象,匹配不上返回None
13             if re.match(i, url):
14                 return
15         # 获取登录状态
16         is_login = request.session['is_login']
17         # 没有登录跳转登录页面
18         if not is_login:
19             return redirect('login')
20 
21         # 免认证
22         for i in settings.NO_PERMISSION_LIST:
23             # match 匹配上得到一个对象,匹配不上返回None
24             if re.match(i, url):
25                 return
26 
27         # 获取当前用户的权限, 要用get去拿,没有显示None,[]就会报错
28         permission_list = request.session.get('permission')
29         # print(permission_list)
30         # 权限的校验
31         for permission in permission_list:
32             # print('>>>>',permission)
33             if re.match(f'^{permission["permissions__url"]}$', url):
34                 return
35         # 没有匹配成功
36         return HttpResponse('你的level不够!!')
权限认证中间件

 

 

  

 

 我们在其他py文件中引入settings的时候,要用以下方式

from django.conf import settings

 

posted @ 2019-03-19 23:02  一个很善良的抱爱  阅读(296)  评论(0编辑  收藏  举报