django開發之許可權管理(二)——許可權管理詳解(許可權的設定和中介軟體的使用者session獲取)
阿新 • • 發佈:2019-01-01
注意 每次開發的時候 都先要理清楚要做什麼?要實現怎麼樣的功能?要怎麼實現?
在 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