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
相关产品推荐
相关产品推荐

