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
相關文章
相關標籤/搜索