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è)試組']
只要增加一行代碼, 聲明組名稱, 就能夠讓這個(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è)組名稱的參數(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
, 并且能夠接收組名稱列表作為參數(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-06Python開(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-12Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析
這篇文章主要介紹了Python中eval帶來(lái)的潛在風(fēng)險(xiǎn)代碼分析,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼
這篇文章主要介紹了Python時(shí)間戳與時(shí)間字符串互相轉(zhuǎn)換實(shí)例代碼,大家參考使用2013-11-11Python matplotlib的使用并自定義colormap的方法
今天小編就為大家分享一篇Python matplotlib的使用并自定義colormap的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12