最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Django 按組控制權(quán)限類及定義方法詳解

 更新時(shí)間:2023年06月21日 15:09:32   作者:alue  
這篇文章主要為大家介紹了Django 按組控制權(quán)限類及定義方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

任務(wù)描述

后端接口,能夠方便的使用角色組權(quán)限控制, 例如

# 基于函數(shù)的控制
@api_view(['GET'])
@permission_groups(['開發(fā)組','測(cè)試組'])
def api(request):
    return Response()
# 或者在類中
class SomeViewSet():
    group_names = ['開發(fā)組','測(cè)試組']

只要增加一行代碼, 聲明組名稱, 就能夠讓這個(gè)接口只對(duì)該角色開放權(quán)限.

方法

思路很簡(jiǎn)單, 就是仿照 DRF 的權(quán)限控制, 自定義自己的權(quán)限驗(yàn)證行為即可.

權(quán)限類定義

仿照drf的權(quán)限類 IsAuthenticated 的寫法:

class IsAuthenticated(BasePermission):
    def has_permission(self, request, view):
        return bool(request.user and request.user.is_authenticated)

我們的權(quán)限類,需要一個(gè)組名稱的參數(shù), 所以需要用工廠模式, 根據(jù)參數(shù), 動(dòng)態(tà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)限類 
SigmaPermissionFactory = sigma_permission()

我們用類似閉包的形式, 構(gòu)建了自己的權(quán)限類 SigmaPermission, 并且能夠接收組名稱列表作為參數(shù), 內(nèi)部方法 has_permission 實(shí)現(xiàn)了權(quán)限驗(yàn)證的工作.

下面, 就要要看看權(quán)限類該怎么使用. 根據(jù)兩種場(chǎng)景, 分別采用裝飾器和基類繼承的方式.

基于函數(shù)的權(quán)限控制

可以參考drf的 permission_classes 裝飾器的寫法

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)? 我們的類工廠生成 groups_permission 時(shí), 已經(jīng)完成了初始化. 而Python的類只有在初始化時(shí)是 callable 的, 一旦初始化完成之后, 就不能再次callable. 而 permission_classes里的元素必須可以 callable , 所以用 lambda 函數(shù)的方式實(shí)現(xiàn).

基于類的權(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é)

通過這個(gè)案例, 我們能夠?qū)W到工廠函數(shù)/類的callable/lambda 函數(shù)的使用場(chǎng)景.

以上就是Django 按組控制權(quán)限類及定義方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Django 按組控制權(quán)限的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

怀安县| 繁昌县| 阿荣旗| 筠连县| 龙川县| 资兴市| 黔南| 新乡市| 涿鹿县| 泉州市| 台北市| 淅川县| 石家庄市| 瑞丽市| 崇信县| 河北省| 宜春市| 海丰县| 都江堰市| 沾益县| 伊川县| 威远县| 会昌县| 延寿县| 纳雍县| 当阳市| 广东省| 绥中县| 若尔盖县| 洮南市| 成都市| 杭锦旗| 依安县| 白玉县| 阿拉善盟| 天等县| 滕州市| 包头市| 瓮安县| 花垣县| 镇赉县|