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

Django Rest Framework通过关联模型实现权限控制的方案咨询

方案结论

你提到的第二种自定义权限类的方案是DRF生态下处理关联对象权限的成熟标准实现,不存在根本性问题,完全符合你要求的「Study作为权限唯一可信来源」的要求,不需要冗余的权限同步逻辑。


实现示例

1. 自定义关联权限校验类

from rest_framework.permissions import BasePermission

class RelatedStudyAccessPermission(BasePermission):
    """校验用户对Result关联的Study是否有访问权限"""
    def has_permission(self, request, view):
        # 所有请求需先登录,列表页的权限过滤后续在queryset层处理
        return request.user.is_authenticated

    def has_object_permission(self, request, view, obj):
        # 直接复用Study的权限校验逻辑,此处按你实际的Study权限规则修改即可
        # 示例1:使用Django自带对象权限/ django-guardian 校验查看权限
        return request.user.has_perm("你的应用名.view_study", obj.study)
        # 示例2:如果Study有members多对多字段关联授权用户,替换为:
        # return obj.study.members.filter(id=request.user.id).exists()

2. Result视图层配置

需要同时配置权限类、重写查询集过滤,避免无权限用户在列表接口看到所有Result数据:

from rest_framework import viewsets
from .models import Result, Study
from .serializers import ResultSerializer
from .permissions import RelatedStudyAccessPermission

class ResultViewSet(viewsets.ModelViewSet):
    serializer_class = ResultSerializer
    permission_classes = [RelatedStudyAccessPermission]

    def get_queryset(self):
        # 仅返回用户有权限访问的Study对应的Result
        # 对应上面权限校验的两种写法,二选一即可
        # 写法1:适配django-guardian/自带对象权限的过滤
        accessible_studies = Study.objects.filter(
            user_permissions__user=self.request.user,
            user_permissions__codename="view_study"
        )
        # 写法2:适配Study.members多对多授权的过滤
        # accessible_studies = self.request.user.study_set.all()
        return Result.objects.filter(study__in=accessible_studies)

补充说明

如果使用django-guardian这类成熟的第三方对象权限组件,还可以直接使用它提供的DjangoObjectPermissionsFilter等过滤类,无需手动编写查询集过滤逻辑,进一步减少重复代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:06:01