22-1 rbac權限設計

一 表結構設計html

 1 from django.db import models
 2 
 3 # Create your models here.
 4 from django.db import models
 5 
 6 # Create your models here.
 7 
 8 
 9 # 用戶表
10 class UserInfo(models.Model):
11     username = models.CharField(max_length=16, verbose_name="用戶名")
12     password = models.CharField(max_length=32, verbose_name="密碼")
13     roles = models.ManyToManyField(to="Role", null=True, blank=True)
14     # null=TRUE是告訴數據庫這個字段能夠爲空,blank=True告訴djangoadmin能夠不填
15 
16     # 顯示具體的內容
17     def __str__(self):
18         return self.username
19 
20     # 讓字段顯示中文
21     class Meta:
22         verbose_name = "用戶表"
23         verbose_name_plural = verbose_name
24 
25 
26 # 角色
27 class Role(models.Model):
28     title = models.CharField(max_length=32, verbose_name="角色名稱")
29     permissions = models.ManyToManyField(to="Permission")
30 
31     def __str__(self):
32         return self.title
33 
34     class Meta:
35         verbose_name = "角色表"
36         verbose_name_plural = verbose_name
37 
38 
39 # 權限表
40 class Permission(models.Model):
41     title = models.CharField(max_length=16, verbose_name="權限名稱")
42     url = models.CharField(max_length=255, verbose_name="URL")
43     is_menu = models.BooleanField(default=False, verbose_name="可做爲菜單展現")
44     icon = models.CharField(max_length=16, verbose_name="菜單圖標", null=True, blank=True)
45 
46     def __str__(self):
47         return self.title
48 
49     class Meta:
50         verbose_name = "權限表"
51         verbose_name_plural = verbose_name
View Code

二 建立rbac權限管理項目python

1. 爲了實現項目結構的解耦,把權限系統單獨寫成一個app
  1. 建立APP
            Django中建立app的步驟
           1. python manage.py startapp rbac 在terminal終端裏面運行
           2. 在settings.py中註冊app
    rbac.apps.RbacConfig
2. 執行兩條命令,把表結構同步到數據庫把建立數據庫的語句寫在rbac的models文件裏
  1. python manage.py makemigrations
  2. python manage.py migrate
3. 錄入數據
  藉助Django Admin
  Django admin的用法
  1. 建立超級用戶,用來登錄admin管理後臺
  python manage.py createsuperuser
  2. 將咱們本身寫的表註冊到Django admin中
  在app/admin.py中按照固定的格式註冊model數據庫

       以下:django

   

 1 from django.contrib import admin
 2 from rbac import models
 3 # 註冊用戶表
 4 admin.site.register(models.UserInfo)
 5 #註冊角色表
 6 admin.site.register(models.Role)
 7 
 8 
 9 # 自定義一個權限管理類
10 class PermissionAdmin(admin.ModelAdmin):
11     # 告訴django admin在頁面上展現我這張表的那些字段
12     list_display = ["title","url","is_menu","icon"]
13     # 在列表頁面能夠編輯url
14     list_editable = ["url","icon","is_menu"]
15 
16 
17 admin.site.register(models.Permission,PermissionAdmin)

三 權限的查詢session

權限查詢的代碼最好能拿出來單獨封裝一個函數,這樣方便你之後能夠直接用你寫的rbac這個權限管理app

1 在rbac目錄下面新建一個python package 名字能夠隨便叫,而後新建一個py文件,名字也能夠隨便叫我這裏叫:permission.pyide

 1 from django.conf import settings
 2 
 3 
 4 def init_permission(request, user_obj):
 5     '''
 6 在session中初始化權限信息和菜單信息的函數
 7     :param request: 請求對象
 8     :param user_obj:當前登陸用戶
 9     :return:
10     '''
11 
12     # user_obj.roles.all()那到當前用戶的全部角色
13     ret = user_obj.roles.all().values("permissions__url",
14                                       "permissions__icon",
15                                       "permissions__is_menu",
16                                       "permissions__title"
17                                       ).distinct()  # 取到去重以後的權限
18     # 定義一個權限列表
19     permission_list = []
20     # 定義一個專門用來存放當前用戶菜單的列表
21     menu_list = []
22     for item in ret:
23         print(item)  # item是個大列表
24         permission_list.append({"permissions__url": item["permissions__url"]})  # 添加到權限列表
25         if item["permissions__is_menu"]:  # 若是爲真
26             menu_list.append({
27                 "title": item["permissions__title"],
28                 "icon": item["permissions__icon"],
29                 "url": item["permissions__url"]
30             })
31 
32     # 將用戶權限列表信息,存到session中
33     request.session[settings.PERMISSION_SESSION_KEY] = permission_list
34     # 把當前用戶的全部菜單存放到sessioin
35     request.session[settings.MENU_SESSION_KEY] = menu_list
View Code

2 setting.py文件配置函數

# 設置白名單
PERMISSION_WHITE_URL=[
    "/login/",
    "/admin/.*",
]
#權限列表
PERMISSION_SESSION_KEY="permission_list"

#菜單列表
MENU_SESSION_KEY="menu_list"

四 權限校驗url

應該將權限的校驗功能放在中間件中的process_request()方法spa

1 在rbac目錄下面新建一個python package包 middleware ,而後建一個rbac.py文件,名字能夠隨便取

 1 '''
 2 自定義rbac中間件
 3 '''
 4 from django.utils.deprecation import  MiddlewareMixin
 5 from django.shortcuts import redirect,HttpResponse,render
 6 import re
 7 from django.conf import settings
 8 
 9 class RBACMiddleware(MiddlewareMixin):
10     def process_request(self,request):
11         '''
12         自定義權限校驗的中間件
13         :param request: 請求對象
14         :return:
15         '''
16         # 1 取到當前此次請求訪問的url是什麼
17         url=request.path_info   # request.get_full_path()
18         # 過濾白名單
19         for item in settings.PERMISSION_WHITE_URL:
20             reg="^{}$".format(item)
21             if re.match(reg,url):
22                 return None
23         # 取到當前用戶的權限列表
24         permission_list=request.session.get(settings.PERMISSION_SESSION_KEY,None)
25         # 進行權限校驗
26         if  permission_list is None:
27             # 用戶沒登陸
28             return redirect("/login/")
29         for i in permission_list:
30             reg="^{}$".format(i['permissions__url'])
31             if re.match(reg,url):
32                 break
33         else:
34             return HttpResponse("你沒有此權限")
View Code

2 而後在setting.py文件裏註冊一下

'rbac.middleware.rbac.RBACMiddleware',

 五 項目登陸函數的引用就是導入剛纔封裝好的初始化權限的函數

'''
跟用戶相關的視圖都寫在這裏
'''
from django.shortcuts import redirect, render, HttpResponse
from rbac.models import UserInfo
from rbac.service.permission import init_permission


def login(request):
    error_msg = ""
    if request.method == "POST":
        # 取用戶名和密碼
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        # 驗證
        user_obj = UserInfo.objects.filter(username=username, password=pwd).first()
        if user_obj:
            # 登陸成功
            # 調用封裝好的初始化函數裏面含有權限列表和顯示菜單
            init_permission(request,user_obj)

            return redirect("/customer/list/")
        else:
            error_msg = "用戶名或密碼錯誤"

    return render(request, "login.html")

六 頁面中引用模板語言

1 首先在rbac下面新建一個python packages名字爲templatetags(名字必須是這個)而後新建一個py文件,名字隨意,我這裏叫ooxx

filename 就是將你返回的結果給那個頁面調用,show_menu就是你自定義的模板語言的名字

from django import template

from luffy_permission import settings

register = template.Library()


@register.inclusion_tag(filename="my_menu.html")
def show_menu(request):
# menu_list是你從session裏面獲取的用戶的菜單列表
menu_list
= request.session[settings.MENU_SESSION_KEY] return {"menu_list": menu_list} # 把menu_list返回給my_menu.html這個頁面

2 新建一個my_menu.html的文件,名字跟filename後面的一致,在rbac目錄下新建一個templates

這個裏面的menu_list就是你上面自定義的的返回結果,menu.icon表明是圖標字段,menu.title表明是菜單名字

1 {% for menu in menu_list %}
2     <a href="{{ menu.url }}" class="active">
3         <span class="icon-wrap"><i class="fa {{ menu.icon }}"></i></span> {{ menu.title }}</a>
4 
5 {% endfor %}

 

3 讓你真正給用戶看的html頁面去引用ooxx,就是在菜單的div裏面加上這個 request是show_menu的一個參數

      <div class="static-menu">
                {% load ooxx %}
                {% show_menu request %}

            </div>

 七 rbac權限目錄結構

 

新的項目中如何引用rbac權限管理##########################################################


1. 拷貝rbac這個app到項目中
2. 把rbac/migrations目錄下的遷移記錄都刪掉
3. 在項目中註冊rbac這個app
4. 建立數據庫遷移(執行那兩條命令)

1. python manage.py makemigrations
2. python manage.py migrate

5. 註冊admin,錄入數據 --> 自動發現並錄入權限URL
6. 在登陸流程中初始化權限信息,配置登陸函數引用封裝好的初始化權限

from django.shortcuts import render, HttpResponse, redirect
from django.conf import settings
from rbac.service.permission import init_permission
from rbac.models import UserInfo


# Create your views here.
def login(request):
    if request.method == "POST":
        username = request.POST.get("username")
        pwd = request.POST.get("password")

        user_obj = UserInfo.objects.filter(username=username, password=pwd).first()
        if user_obj:
            # 登陸成功
            # 初始化權限信息
            init_permission(request, user_obj)
            return redirect("/book_list/")
    return render(request, "login.html")


def book_list(request):
    return render(request, "book_list.html")


def book_add(request):
    return render(request, "book_add.html")
View Code

7. 註冊中間件
8. 在settings.py中設置權限相關的配置項

# 設置白名單
PERMISSION_WHITE_URL=[
    "/login/",
    "/admin/.*",
]
#權限列表
PERMISSION_SESSION_KEY="permission_list"

#菜單列表
MENU_SESSION_KEY="menu_list"

9 在html列表頁面引用

   {% load ooxx %}
    {% show_menu request %}
相關文章
相關標籤/搜索