如何在ModelViewSet中校验用户权限以确定返回的数据范围
基于Django REST Framework ModelViewSet的权限校验与数据范围控制实现
核心实现逻辑是结合DRF自带的权限校验能力,搭配重写get_queryset方法,共同完成权限判定和数据范围过滤:
1. 自定义权限类(用于接口访问/单对象操作权限校验)
如果需要先限制用户是否有权限访问该接口、操作指定资源,可以继承BasePermission自定义权限规则:
from rest_framework.permissions import BasePermission class CustomResourcePermission(BasePermission): # 校验用户是否有权限访问当前接口 def has_permission(self, request, view): # 示例:仅通过身份认证的用户可访问 return request.user.is_authenticated # 校验用户是否有权限操作单个资源对象 def has_object_permission(self, request, view, obj): # 示例:管理员可操作全量数据,普通用户仅能操作自己创建的资源 if request.user.is_staff: return True return obj.create_user == request.user
2. 重写get_queryset方法控制返回数据范围
get_queryset是DRF视图控制返回数据集合的核心入口,你可以在这个方法里根据当前登录用户的角色、权限等级,返回对应范围的数据:
from rest_framework.viewsets import ModelViewSet from .models import YourBusinessModel from .serializers import YourBusinessSerializer class YourBusinessViewSet(ModelViewSet): serializer_class = YourBusinessSerializer # 绑定自定义权限类,完成接口访问前置校验 permission_classes = [CustomResourcePermission] def get_queryset(self): current_user = self.request.user # 管理员返回全量数据 if current_user.is_staff: return YourBusinessModel.objects.all() # 普通用户仅返回与自身关联的数据 return YourBusinessModel.objects.filter(create_user=current_user)
3. 多角色复杂场景扩展
如果存在多级权限(比如超级管理员、大区管理员、部门管理员、普通员工),可以在用户模型中新增角色、数据范围关联字段,在get_queryset中增加判断分支即可:
- 示例逻辑:
def get_queryset(self): current_user = self.request.user # 超级管理员返回全量数据 if current_user.role == "super_admin": return YourBusinessModel.objects.all() # 大区管理员返回对应大区所有数据 elif current_user.role == "region_admin": return YourBusinessModel.objects.filter(region_id=current_user.region_id) # 部门管理员返回对应部门所有数据 elif current_user.role == "dept_admin": return YourBusinessModel.objects.filter(dept_id=current_user.dept_id) # 普通员工仅返回自己创建的数据 return YourBusinessModel.objects.filter(create_user=current_user)
注意:如果你同时在视图类中配置了
queryset静态类属性,它的优先级低于get_queryset的返回值,动态数据范围控制优先使用重写get_queryset的方式实现,不要硬编码静态查询集。
内容的提问来源于stack exchange,提问作者golkarm
相关产品推荐
相关产品推荐

