日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python---django中权限框架设计

發布時間:2024/8/26 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python---django中权限框架设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:admin下的權限了解

推文:如何正確使用 Django的User Model

(一)默認權限表是在自帶auth模塊,中permission表中

可以使用has_perm方法獲取用戶是否有這個權限

(二)Django自定義權限

(1)添加表

from django.db import models from django.contrib.auth.models import (BaseUserManager, AbstractBaseUser,PermissionsMixin
#BaseUserManager  用戶管理基類,用于創建用戶
#AbstractBaseUser 抽象類,聲明一些必須字段,不會自己生產表,繼承的子類才會,主要內容:class Meta abstract=True
#PermissionMixin 權限管理類,也是抽象類 )
class MyUserManager(BaseUserManager):   #用于創建用戶,需要在settings文件中聲明def create_user(self, email, name, password=None):""" Creates and saves a User with the given email, date ofbirth and password.""" if not email:raise ValueError('Users must have an email address')user = self.model(email=self.normalize_email(email),name=name,)user.set_password(password)user.save(using=self._db)return userdef create_superuser(self, email, name, password):""" Creates and saves a superuser with the given email, date ofbirth and password.""" user = self.create_user(email,password=password,name=name,)user.is_superuser = Trueuser.save(using=self._db)return userclass UserProfile(AbstractBaseUser,PermissionsMixin):  email = models.EmailField(verbose_name='email address',max_length=255,unique=True,)name = models.CharField(max_length=128)is_active = models.BooleanField(default=True)is_staff = models.BooleanField(default=True)# is_admin = models.BooleanField(default=False)  #其中is_admin沒有作用,is_superuser才是設置超級用戶role = models.ManyToManyField("Role",blank=True) #,null=Truenull has no effect on ManyToManyField.,null對于manytomanyfield無作用,會報警objects = MyUserManager() #用戶管理類和自定義用戶表關聯USERNAME_FIELD = 'email'REQUIRED_FIELDS = ['name']def __str__(self):return self.emaildef get_full_name(self):return self.emaildef get_short_name(self):return self.email

class Meta:
permissions = (  #用于管理權限條目
('自定義權限名','解釋'),
)

?

(2)settings文件中設置

AUTH_USER_MODEL = 'repository.UserProfile' #上面的值表示Django應用的名稱(必須位于INSTALLLED_APPS中)和你想使用的User模型的名稱。

(3)在admin文件中設置展示內容

from django import forms from django.contrib import admin from django.contrib.auth.models import Group from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.forms import ReadOnlyPasswordHashFieldfrom repository.models import UserProfileclass UserCreationForm(forms.ModelForm):  #創建時顯示的表單信息"""A form for creating new users. Includes all the requiredfields, plus a repeated password.""" password1 = forms.CharField(label='Password', widget=forms.PasswordInput)password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)class Meta:model = UserProfilefields = ('email', 'name')def clean_password2(self):  #對字段進行驗證# Check that the two password entries matchpassword1 = self.cleaned_data.get("password1")password2 = self.cleaned_data.get("password2")if password1 and password2 and password1 != password2:raise forms.ValidationError("Passwords don't match")return password2def save(self, commit=True):  # Save the provided password in hashed formatuser = super().save(commit=False)user.set_password(self.cleaned_data["password1"])if commit:user.save()return userclass UserChangeForm(forms.ModelForm):  #修改時顯示的表單信息"""A form for updating users. Includes all the fields onthe user, but replaces the password field with admin's password hash display field.""" password = ReadOnlyPasswordHashField()  #密碼字段顯示時是hash加密只讀字段class Meta:model = UserProfilefields = ('email', 'password', 'name', 'is_active', 'is_superuser')def clean_password(self):# Regardless of what the user provides, return the initial value.# This is done here, rather than on the field, because the# field does not have access to the initial valuereturn self.initial["password"]class UserProfileAdmin(BaseUserAdmin):  #用于注冊的表類# The forms to add and change user instancesform = UserChangeFormadd_form = UserCreationForm# The fields to be used in displaying the User model.# These override the definitions on the base UserAdmin# that reference specific fields on auth.User.list_display = ('email', 'name', 'is_superuser')list_filter = ('is_superuser',)fieldsets = ( #用于修改(None, {'fields': ('email', 'password')}),('Personal info', {'fields': ('name',)}),('Permissions', {'fields': ('is_active','is_staff','is_superuser','role','user_permissions','groups',)}),)# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin# overrides get_fieldsets to use this attribute when creating a user.add_fieldsets = ( #用于添加(None, {'classes': ('wide',),'fields': ('email', 'name', 'password1', 'password2')}),)search_fields = ('email',)ordering = ('email',)filter_horizontal = ('role','user_permissions',)# Now register the new UserAdmin... admin.site.register(UserProfile, UserProfileAdmin) # ... and, since we're not using Django's built-in permissions, # unregister the Group model from admin. admin.site.unregister(Group)

?二:通用權限框架設計

(一)業務場景分析(如何去實現將不同權限分配給用戶)

python---CRM用戶關系管理

(二)權限管理分析

主要實現:將權限列表定義出來,與角色(用戶組)相互關聯就可以

權限列表實現:

?

?(三)實現方法

(1)定義權限列表文件,將權限列表定義。設置為裝飾器,根據每個用戶訪問的url去反解,獲取到對應的權限列表名,從而去數據庫中獲取,使用has_prem獲取是否擁有權限。從而在用戶訪問url時進行判斷

?permission_list.py(這部分最好是放入數據庫中,可以改進

from kingadmin import permission_hookperm_dict = {'repository_table_obj_list':['table_obj_list',"GET",[],{},permission_hook.view_my_own_customers],  
#第一個是url_name,第二個是訪問方式,第三個是訪問參數必須有的字段,第四個是字段中必須是指定的值,第五個是鉤子函數,是對第三,第四參數的補充,實現動態驗證
'repository_table_obj_change_view':['table_obj_change',"GET",[],{}],'repository_table_obj_change': ['table_obj_change', "POST", [], {}],'repository_table_obj_add_view': ['table_obj_add', "GET", [], {}],'repository_table_obj_add': ['table_obj_add', "POST", [], {}],'repository_table_obj_delete_view': ['table_obj_delete', "GET", [], {}],'repository_table_obj_delete': ['table_obj_delete', "POST", [], {}], } from django.conf.urls import url from kingadmin import viewsurlpatterns = [url(r"^login.html$",views.acc_login),url(r"^logout.html$", views.acc_logout,name="logout"),url(r"^$",views.app_index),url(r"^(\w+)/(\w+)/$",views.table_obj_list,name="table_obj_list"),url(r"^(\w+)/(\w+)/(\d+)/change/$", views.table_obj_change, name="table_obj_change"),url(r"^(\w+)/(\w+)/add/$", views.table_obj_add, name="table_obj_add"),url(r"^(\w+)/(\w+)/(\d+)/delete/$", views.table_obj_delete, name="table_obj_delete"), ] urls文件,可以知道對應的url_name

resolve方法可以翻轉獲取url的數據

(2)permission文件,用于生成裝飾器,驗證權限列表

from .permission_list import perm_dict from django.conf import settings from django.core.urlresolvers import resolve from django.shortcuts import render,redirect,HttpResponse
#對權限進行檢測 def perm_check(
*args,**kwargs):request = args[0]resolve_url_obj = resolve(request.path)  #1,獲取當前請求的urlcurrent_url_name = resolve_url_obj.url_name  #2,把url解析成url_namematch_results = [None,]match_key = Noneif request.user.is_authenticated() is False:   #3,進行用戶登錄驗證return redirect(settings.LOGIN_URL)for permssion_key,permssion_val in perm_dict.items():
#從權限列表中獲取url信息,以及鉤子函數(重點)per_url_name
= permssion_val[0]per_method = permssion_val[1]per_args = permssion_val[2]per_kargs = permssion_val[3]per_hook_name = permssion_val[4] if len(permssion_val) > 4 else Noneif per_url_name == current_url_name: #4.匹配url_nameif per_method == request.method: #5.匹配訪問方法args_matched = False #用于匹配參數args,一次參數失敗,則失敗request_method_dict = getattr(request, per_method)for item in per_args:  #6.匹配參數if request_method_dict.get(item,None):args_matched = Trueelse:args_matched = Falsebreak #一次匹配不上,就跳出else: #當不存在參數,列表為空時args_matched = Truekwargs_matched = False #用于匹配特定的參數for k,v in per_kargs.items():  #7.匹配指定參數值arg_val = request_method_dict.get(k,None)if arg_val == str(v):kwargs_matched = Trueelse:kwargs_matched = Falseelse:kwargs_matched = Truehook_matched = Falseif per_hook_name:  #8.匹配鉤子函數hook_matched = per_hook_name(request)else:hook_matched = Truematch_results = [args_matched,kwargs_matched,hook_matched]if all(match_results): #9.都匹配了  全局驗證,獲取了權限名,用于下面數據庫查詢match_key = permssion_keybreakif match_key:app_name,*per_name = match_key.split("_")perm_obj = "%s.%s"%(app_name,match_key)if request.user.has_perm(perm_obj):  #10.數據庫查看用戶是否被分配該權限print("當前用戶有權限")return Trueelse:print("當前用戶沒有權限")return Falseelse:print("未匹配到權限項,當前用戶沒有權限")return False
#裝飾器函數 def check_permission(func):def inner(
*args,**kwargs):if not perm_check(*args,**kwargs):request = args[0]return render(request,"kingadmin/page_403.html")return func(*args,**kwargs)return inner

總結:

def perm_check(*args,**kwargs):1.獲取當前請求的url,使用resolve解析獲取url_name2.匹配用戶是否登錄,使用user.is_authenticated方法3.使用url_name去權限列表permission_list文件中的權限列表中去匹配權限項4.將權限項解析分為,per_url_name(權限url_name),per_method (url訪問方法),per_args (獲取的參數名),per_kargs (獲取的參數值,字典),per_hook_name (獲取的權限鉤子函數)5.驗證了上面的幾部分,獲取了權限名,然后去數據庫中獲取當前用戶是否擁有該權限,使用user.has_perm(權限名<注意:權限名是由數據表應用加上權限名>)

(3)鉤子函數案例(使當前用戶只能訪問自己的客戶)

def view_my_own_customers(request):if str(request.user.id) == request.GET.get('consultant'):return Trueelse:return False

?

轉載于:https://www.cnblogs.com/ssyfj/p/9135479.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的python---django中权限框架设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。