django--权限(1)初识

1、权限表结构设计

一、认识权限

  生活中到处有权限,好比,腾讯视频开会员才有观看某个最新电影的权限,你有房间钥匙就有了进入这个房间的权限,等等。一样,程序开发过程当中也有权限,咱们今天说的权限指的是web网站权限,对于不一样用户访问web服务时应该有不一样的功能,如,一个公司有CEO、销售主管、销售等等,不一样的用户能访问的服务也不是彻底相同的,因此这个时候就须要权限控制了。html

二、为何要开发权限组件

  组件能够减小重复开发,一次开发,在之后的项目中能够一直使用,避免重复写一样的代码。程序员

三、web开发中权限是指什么?

  web程序是经过 url 的切换来查看不一样的页面(功能),因此权限指的其实就是一个含有正则表达式的URL,对url控制就是对权限的控制。web

  结论:一我的有多少个权限就取决于他有多少个URL的访问权限。正则表达式

四、权限表结构设计(简单版)

  根据实际状况,通常一个用户能够有多个权限,一个权限也能够分配给多个用户,因此表结构能够按照以下设计:数据库

用户表                          权限表         
id      name                   id    user_id       url                     title
     alex                    1       1       /customer/add              添加客户
     egon                    2       1       /customers/list/           查看客户
      1       /consult_records/add/      添加跟进记录
      1       /consult_records/          查看跟进记录

分析:设计完以后思考一下这样作有什么问题?假设又新增了10个用户,每一个用户都有右表中的4个权限,那就要在权限表中新增40条记录,这仍是只有4个url的状况,现实生活中一个web网站确定不止4个url,这意味着每增长一个用户,你就要在权限表中增长若干条记录,加剧了程序员的工做不说,这样形成了数据库空间的严重浪费,那么思考一下如何改进!django

五、权限表设计(第二版)

  聪明的你必定有想法了,没错,若是对用户进行划分角色,而后对角色进行权限的分配,问题就解决了。session

  分析:app

    一我的能够有多个角色函数

    一个角色能够有多我的网站

    一个角色能够有多个权限

    一个权限能够分配给多个角色

  表结构设计:

用户表:user                        user2role表
id   name                          id      user_id    role_id
   alex                           1          1         3
   egon                           2          2         3


角色表:role                      role2permission
id     title                     id        role_id            permission_id
     CEO                       1            3                  1
     销售总监                  2            3                  2
     销售                    3            3                  3
           3                  4

权限表:permission
id          url                     title
       /customer/add              添加客户
       /customers/list/           查看客户
       /consult_records/add/      添加跟进记录
       /consult_records/          查看跟进记录

通过调整以后,由原来的【基于用户的权限控制】转换成【基于角色的权限控制】,之后再进行分配权限时只须要给指定角色分配一次权限,给众多用户再次分配指定角色便可。

  models.py中代码以下:

from django.db import models

# Create your models here.
class User(models.Model):
    """
    用户表
    """
    name = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=32)
    roles = models.ManyToManyField(verbose_name='拥有的全部角色', to='Role')
    def __str__(self):
        return self.name

class Role(models.Model):
    """
    角色表
    """
    title = models.CharField(verbose_name='角色名称', max_length=32)
    permissions = models.ManyToManyField(verbose_name='拥有的全部权限', to='Permission')
    def __str__(self):
        return self.title

class Permission(models.Model):
    """
    权限表
    """
    url = models.CharField(verbose_name='含正则的URL', max_length=32)
    title = models.CharField(verbose_name='标题', max_length=32)
    
    def __str__(self):
        return self.title

 不经意间,咱们竟然设计出了一个经典的权限访问控制系统:rbac(Role-Based Access Control)基于角色的权限访问控制。

  注意:如今的设计还不是最终版,但以后的设计都是在此版本基础上扩增的,为了可以更好的理解,咱们暂且在此基础上继续开发,直到遇到没法知足的状况,再进行整改。

2、客户管理之权限控制

一、首先按照上面model示例代码建表,进行数据库迁移,在admin.py中注册表,而后再建立一个超级用户,登陆admin录入数据,以下:

二、修改admin的显示格式,以permission表为例:

  在admin.py中,permission表的注册方法admin.site.register(Permission)改成以下代码:

# 自定义类,类名本身定,但必须继承ModelAdmin
class PermissionConfig(admin.ModelAdmin):  
    list_display = ['pk', 'title', 'url']
    ordering = ['pk']  # 按照主键从低到高

admin.site.register(Permission, PermissionConfig)

Permission表显示效果以下,有没有更直观:

   注意:使用django的admin添加数据时,必定要记得在admin.py中注册你本身的表,不然登陆admin只能看见django自带的表,看不见你本身在model中定义的表。

三、登陆视图函数

def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        user_obj = User.objects.filter(name=user, password=pwd).first()
        if user_obj:
            request.session['user_id'] = user_obj.pk  # 将用户id注入session
            # 查询当前登陆人的全部权限列表
            ret = Role.objects.filter(user=user_obj).values('permissions__url').distinct()

            permission_list = []
            for item in ret:
                permission_list.append(item['permissions__url'])
            print('权限列表', permission_list)
            # 将当前登陆人的权限列表注入session中
            request.session['permission_list'] =  permission_list

            return HttpResponse('登陆成功')
        
    return render(request, 'login.html')

四、控制权限的中间件

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect, HttpResponse
import re

class PermissionMiddleWare(MiddlewareMixin):
    def process_request(self, request):

        # 设置白名单放行
        for reg in ["/login/", "/admin/*"]:
            ret = re.search(reg, request.path)
            if ret:
                return None

        # 检验是否登陆
        user_id = request.session.get('user_id')
        if not user_id:
            return redirect('/login/')

        # 检验权限
        permission_list = request.session.get('permission_list')
        for reg in permission_list:
            reg = '^%s$' % reg
            ret = re.search(reg, request.path)
            if ret:
                return None
        return HttpResponse('无权访问')

3、补充

一、django的配置文件相关

  django中其实有两个配置文件,一个是咱们项目中能够看见的settings.py文件,也就是用户的配置文件,另外一个是django默认的配置文件global_settings.py,你有没有注意到虽然有些参数咱们在本身的配置文件settings.py中虽然没有定义,但其实他是有值的,没错,django是在默认的配置文件中为咱们写好了,同时容许咱们在本身的setting.py中从新定义覆盖掉django默认值,由此得出用户的配置文件优先级比django默认的高,所以,咱们知道了项目的配置参数由django和咱们本身定义的配置文件共同决定的,且django的默认配置文件包含咱们本身定义的配置文件,因此,当咱们导入配置文件时,应以以下方式:

from django.conf import settings
相关文章
相关标签/搜索