1. 程式人生 > >django開發之許可權管理(二)——許可權管理詳解(許可權的設定和中介軟體的使用者session獲取)

django開發之許可權管理(二)——許可權管理詳解(許可權的設定和中介軟體的使用者session獲取)

注意 每次開發的時候 都先要理清楚要做什麼?要實現怎麼樣的功能?要怎麼實現?
在 django中

一般分這幾步走:設計url,設計檢視函式,從資料庫中拿資料進行渲染
這裡其實是django的請求生命週期

在這裡插入圖片描述
1、請求生命週期

  • wsgi, 他就是socket服務端,用於接收使用者請求並將請求進行初次封裝,然後將請求交給web框架(Flask、Django)

  • 中介軟體,幫助我們對請求進行校驗或在請求物件中新增其他相關資料,例如:csrf、request.session

  • 路由匹配

  • 檢視函式,在檢視函式中進行業務邏輯的處理,可能涉及到:orm、templates => 渲染

  • 中介軟體,對響應的資料進行處理。

  • wsgi,將響應的內容傳送給瀏覽器。

2、什麼wsgi
wsgi:web服務閘道器介面

實現該協議的模組:

  • wsgiref(測試版本,效能特別差)
  • werkzurg
  • uwsig

wsgiref示例:

from wsgiref.simple_server import make_server
 
def run_server(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [bytes('<h1>Hello, web!</h1>', encoding='utf-8'), ]  #位元組
  
  
if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8000, run_server)
    httpd.serve_forever()

werkzeug示例:

from werkzeug.wrappers import Response
from werkzeug.serving import run_simple
 
def run_server(environ, start_response):
    response = Response('hello')
    return response(environ, start_response)     #物件
 
if __name__ == '__main__':
    run_simple('127.0.0.1', 8000, run_server)

3、檢視
FBV
url - 函式

CBV
url - view

FBV(function base view)與CBV(class base view)本質是一樣的,只是fbv基於函式,cbv基於類。只不過fbv較cbv往後多執行了幾步。

4、rest-framework
rest-framework從dispatch方法開始介入,執行完檢視,如果有rest-framework元件,就執行rest-framework。

5、restfui規範

下面開始我們的設計

1:設計使用者登入url
1.1在url中
from web.views import account

urlpatterns = [
    url(r'^login/$', account.login, name='login'),]

2:設計檢視

from django.shortcuts import render, redirect, reverse
from rbac import models
from rbac.service.SetPermissions import SetPermission


def login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        obj = models.User.objects.filter(name=user, password=pwd).first()

        if not obj:
            return render(request, 'login.html')
        # 重點在這呢
        # 在外邊的rbac新建一個資料夾 裡面存放這個初始化許可權資訊的函式
        # 傳request是為了方便將資訊存到seesion中,傳入當前登入的物件是為了查出物件所具有的許可權
        SetPermission(request, obj)
        # 登入成功和設定好session之後跳轉到自己定義的頁面 比如客戶展示
        return redirect(reverse('customer_list'))

    return render(request, 'login.html')

3:查詢資料

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/12/31 0031 17:23
# @Author : BigC
# @Site : 
# @File : SetPermissions.py
# @Software: PyCharm
# @contact: [email protected]
from django.conf import settings


def SetPermission(request, obj):
    ret = obj.roles.all().filter(permissions__url__isnull=False
                                 ).values('permissions__url',
                                          'permissions__title',
                                          'permissions__menu',
                                          'permissions__parent',
                                          'permissions__name',
                                          'permissions__menu__title',
                                          'permissions__menu__icon',
                                          'permissions__menu__weight',
                                          'permissions__id',
                                          'permissions__name',
                                          'permissions__menu_id',
                                          ).distinct()
    menu_dict = {}
    permission_dict = {}

    print(ret)
    # {
    #     'permissions__url': 'customer/list/',
    #     'permissions__title': '檢視客戶',
    #     'permissions__menu': 1,
    #     'permissions__parent': None,
    #     'permissions__name': 'customer/list/',
    #     'permissions__menu__title': '檢視客戶',
    #     'permissions__menu__icon': 'fa-book',
    #     'permissions__menu__weight': 1
    # }
    for item in ret:
        print(item)
        permission_dict['permissions__name'] = ({
            'panme': item['permissions__parent__name'],
            'title': item['permissions_title'],
            'url': item['permissions__menu'],
            'id': item['permissions__id'],
            'pid': item['permissions__parent__id'],
        })
        menu_dict = []
        menu_id = item.get('permissions__menu_id')
        if menu_id not in menu_dict:
            menu_dict[menu_id] = {
                'title': item.get('permissions__menu__title'),
                'icon': item.get('permissions__menu__icon'),
                'weight': item.get('permissions__menu__weight'),
                'children': [{
                    'title': item.get('permissions__title'),
                    'url': item.get('permissions_url'),
                    'id': item.get('permissions__id'),
                }],
            }
        else:
            menu_dict[menu_id]['children'].append(
                {'title': item.get('permissions__title'),
                 'url': item.get('permissions_url'),
                 'id': item.get('permissions__id'), }
            )

        # 存許可權
        request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
        # 存選單
        request.session[settings.PERMISSION_MENU_KEY] = menu_dict