Django 按組控制權(quán)限類(lèi)及定義方法詳解
任務(wù)描述
后端接口,能夠方便的使用角色組權(quán)限控制, 例如
# 基于函數(shù)的控制
@api_view(['GET'])
@permission_groups(['開(kāi)發(fā)組','測(cè)試組'])
def api(request):
return Response()
# 或者在類(lèi)中
class SomeViewSet():
group_names = ['開(kāi)發(fā)組','測(cè)試組']
只要增加一行代碼, 聲明組名稱(chēng), 就能夠讓這個(gè)接口只對(duì)該角色開(kāi)放權(quán)限.
方法
思路很簡(jiǎn)單, 就是仿照 DRF 的權(quán)限控制, 自定義自己的權(quán)限驗(yàn)證行為即可.
權(quán)限類(lèi)定義
仿照drf的權(quán)限類(lèi) IsAuthenticated 的寫(xiě)法:
class IsAuthenticated(BasePermission):
def has_permission(self, request, view):
return bool(request.user and request.user.is_authenticated)
我們的權(quán)限類(lèi),需要一個(gè)組名稱(chēng)的參數(shù), 所以需要用工廠模式, 根據(jù)參數(shù), 動(dòng)態(tài)生成類(lèi).
def sigma_permission():
class SigmaPermission(BasePermission):
def __init__(self, group_names: List[GroupName] = None):
self._sigma_groups = group_names
def has_permission(self, request, view):
if request.user.is_anonymous:
return False
return set(request.user.groups.all().values_list('name', flat=True)) & set(self._sigma_groups)
return SigmaPermission
# 能夠接受參數(shù)的權(quán)限類(lèi)
SigmaPermissionFactory = sigma_permission()
我們用類(lèi)似閉包的形式, 構(gòu)建了自己的權(quán)限類(lèi) SigmaPermission, 并且能夠接收組名稱(chēng)列表作為參數(shù), 內(nèi)部方法 has_permission 實(shí)現(xiàn)了權(quán)限驗(yàn)證的工作.
下面, 就要要看看權(quán)限類(lèi)該怎么使用. 根據(jù)兩種場(chǎng)景, 分別采用裝飾器和基類(lèi)繼承的方式.
基于函數(shù)的權(quán)限控制
可以參考drf的 permission_classes 裝飾器的寫(xiě)法
def permission_classes(permission_classes):
def decorator(func):
func.permission_classes = permission_classes
return func
return decorator
我們定義自己的組權(quán)限裝飾器:
def permission_groups(group_names: List[GroupName]):
""" 組權(quán)限裝飾器 """
def decorator(func):
groups_permission = SigmaPermissionFactory(group_names)
if hasattr(func, 'permission_classes') and func.permission_classes is not None:
func.permission_classes = [*func.permission_classes, lambda: groups_permission]
else:
func.permission_classes = [lambda: groups_permission]
return func
return decorator
注意: 這里注冊(cè) permission_classes 時(shí), 必須要用 lambda 函數(shù)的方式. 這是因?yàn)? 我們的類(lèi)工廠生成 groups_permission 時(shí), 已經(jīng)完成了初始化. 而Python的類(lèi)只有在初始化時(shí)是 callable 的, 一旦初始化完成之后, 就不能再次callable. 而 permission_classes里的元素必須可以 callable , 所以用 lambda 函數(shù)的方式實(shí)現(xiàn).
基于類(lèi)的權(quán)限控制
這個(gè)方法就簡(jiǎn)單許多, 只用重載 get_permissions 方法就行.
class SigmaViewSet(ModelViewSet):
def get_permissions(self):
permissions = [permission() for permission in self.permission_classes]
if hasattr(self, 'group_names '):
groups_permission = SigmaPermissionFactory(self.group_names )
permissions.append(groups_permission)
return permissions總結(jié)
通過(guò)這個(gè)案例, 我們能夠?qū)W到工廠函數(shù)/類(lèi)的callable/lambda 函數(shù)的使用場(chǎng)景.
以上就是Django 按組控制權(quán)限類(lèi)及定義方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Django 按組控制權(quán)限的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
利用Pandas實(shí)現(xiàn)對(duì)數(shù)據(jù)進(jìn)行移動(dòng)計(jì)算
這篇文章主要為大家詳細(xì)介紹了如何利用Pandas實(shí)現(xiàn)對(duì)數(shù)據(jù)進(jìn)行移動(dòng)計(jì)算,文中的示例代碼講解詳細(xì),對(duì)我們了解Pandas有一定幫助,需要的可以參考一下2022-07-07
使用NumPy和pandas對(duì)CSV文件進(jìn)行寫(xiě)操作的實(shí)例
今天小編就為大家分享一篇使用NumPy和pandas對(duì)CSV文件進(jìn)行寫(xiě)操作的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
Python開(kāi)發(fā)中的Nonetype類(lèi)型詳解
這篇文章主要介紹了Python開(kāi)發(fā)中的Nonetype類(lèi)型詳解,None有自己的數(shù)據(jù)類(lèi)型NoneType,你可以將None復(fù)制給任何變量,但是你不能創(chuàng)建其他NoneType對(duì)象,需要的朋友可以參考下2023-12-12
Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析
這篇文章主要介紹了Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼,大家參考使用2013-11-11
Python matplotlib的使用并自定義colormap的方法
今天小編就為大家分享一篇Python matplotlib的使用并自定義colormap的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12

