You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django REST Framework如何快速检查用户权限?从Django权限装饰器迁移

嘿,我完全懂你这种痛点!之前用Django传统视图的permission_required装饰器确实顺手,换到DRF之后,DjangoModelPermissions虽然能搞定大部分场景,但依赖视图queryset这点有时候确实会绑住手脚。下面给你几个实用的解决方案,按需挑选就行:

方案1:自定义权限类(最灵活)

DRF的权限系统本身就是为扩展设计的,你可以完全脱离queryset限制,自己写一个权限类来实现任意逻辑。比如要检查用户是否拥有my_app.view_mymodel权限:

from rest_framework.permissions import BasePermission

class MyCustomPermission(BasePermission):
    def has_permission(self, request, view):
        # 全局权限检查:判断用户是否有指定权限
        return request.user.has_perm('my_app.view_mymodel')
    
    # 如果需要对象级别的权限控制,再实现这个方法
    def has_object_permission(self, request, view, obj):
        # 比如检查用户是否能操作这个具体对象
        return request.user.has_perm('my_app.change_mymodel', obj)

然后在视图里直接使用:

from rest_framework.views import APIView

class MyAPIView(APIView):
    permission_classes = [MyCustomPermission]
    
    def get(self, request):
        # 你的视图逻辑
        ...
方案2:用DRF自带的permission_required装饰器

其实DRF也提供了和Django原生风格一致的装饰器,完全不依赖queryset,直接就能用:

from rest_framework.decorators import permission_required

@permission_required('my_app.view_mymodel', login_url='/sign_in/')
def my_api_view(request):
    # 你的视图逻辑
    ...

如果是类视图,可以用method_decorator来包裹指定方法:

from django.utils.decorators import method_decorator
from rest_framework.views import APIView

@method_decorator(permission_required('my_app.view_mymodel', login_url='/sign_in/'), name='get')
class MyAPIView(APIView):
    def get(self, request):
        ...
方案3:扩展DjangoModelPermissions摆脱queryset依赖

如果你想复用DjangoModelPermissions的逻辑,但不想受限于视图的queryset,可以重写它的get_required_permissions方法,手动指定不同HTTP方法对应的权限:

from rest_framework.permissions import DjangoModelPermissions

class CustomDjangoModelPermissions(DjangoModelPermissions):
    def get_required_permissions(self, method, model_cls):
        # 手动映射HTTP方法到权限,不用依赖视图的queryset
        if method == 'GET':
            return ['my_app.view_mymodel']
        elif method == 'POST':
            return ['my_app.add_mymodel']
        elif method in ['PUT', 'PATCH']:
            return ['my_app.change_mymodel']
        elif method == 'DELETE':
            return ['my_app.delete_mymodel']
        return []

之后在视图里使用这个自定义类即可,哪怕视图没定义queryset也能正常工作:

class MyAPIView(APIView):
    permission_classes = [CustomDjangoModelPermissions]
    
    def get(self, request):
        ...
方案4:视图内部手动检查权限

如果只是某个特定逻辑需要临时检查权限,不想全局配置权限类,也可以直接在视图里判断:

from rest_framework.response import Response
from rest_framework import status

class MyAPIView(APIView):
    def get(self, request):
        if not request.user.has_perm('my_app.view_mymodel'):
            return Response({"detail": "没有访问权限"}, status=status.HTTP_403_FORBIDDEN)
        # 你的视图逻辑
        ...

内容的提问来源于stack exchange,提问作者Fabio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:33:57