Django Rest Framework ListAPIView用户权限失效问题求助
问题原因
DjangoModelPermissions权限类的默认逻辑是不对安全请求方法(GET、HEAD、OPTIONS)做权限校验,它仅针对修改类方法(POST、PUT、DELETE等)验证对应的add/change/delete权限。只要用户通过了IsAuthenticated的认证(即已登录),就允许访问GET接口,哪怕用户没有view_facility权限。这就是无权限用户能调用GET但POST被禁止的核心原因。
解决方案
要让GET请求也校验view_facility权限,需要自定义一个继承自DjangoModelPermissions的权限类,修改其perms_map属性,为安全方法绑定对应的view权限。
步骤1:自定义权限类
在项目的权限文件(比如permissions.py)中添加如下代码:
from rest_framework.permissions import DjangoModelPermissions class CustomModelPermissions(DjangoModelPermissions): # 重写权限映射,为GET、HEAD方法添加view权限要求 perms_map = { 'GET': ['%(app_label)s.view_%(model_name)s'], 'HEAD': ['%(app_label)s.view_%(model_name)s'], 'OPTIONS': [], 'POST': ['%(app_label)s.add_%(model_name)s'], 'PUT': ['%(app_label)s.change_%(model_name)s'], 'PATCH': ['%(app_label)s.change_%(model_name)s'], 'DELETE': ['%(app_label)s.delete_%(model_name)s'], }
步骤2:在视图中使用自定义权限类
修改你的FacilityListView,将原有的DjangoModelPermissions替换为自定义的权限类:
from rest_framework.generics import ListAPIView from rest_framework.permissions import IsAuthenticated from .models import Facility from .serializers import FacilitySerializer from .permissions import CustomModelPermissions class FacilityListView(ListAPIView): queryset = Facility.objects.all() serializer_class = FacilitySerializer permission_classes = [IsAuthenticated, CustomModelPermissions]
验证要点
- 确认
view_facility权限已存在于系统权限表中(Django会在模型执行migrate时自动生成该权限)。 - 测试时使用普通无权限用户,超级用户默认会跳过所有权限校验,无法验证真实效果。
内容的提问来源于stack exchange,提问作者Mathijs van Nimwegen
相关产品推荐
相关产品推荐

