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

Django REST ModelViewSet自定义权限:普通用户仅可操作所属物料

实现方案

推荐使用Django REST Framework自带的自定义权限类实现需求,相比重写每个视图方法的逻辑,权限和业务分离的方案可维护性更高。

1. 定义自定义权限类

from rest_framework.permissions import BasePermission

# 你原有的admin判断逻辑
def app_admin(user):
    if user.user_is_admin:
        return True
    if user.is_superuser:
        return True
    return False

class MaterialPermission(BasePermission):
    # 全局权限校验,控制是否可访问视图
    def has_permission(self, request, view):
        # 未登录用户直接拒绝
        if not request.user.is_authenticated:
            return False
        # 管理员直接放行所有操作
        if app_admin(request.user):
            return True
        # 普通用户允许访问的动作,可根据需求调整
        allowed_actions = ['list', 'retrieve', 'create', 'destroy']
        return view.action in allowed_actions

    # 对象级权限校验,控制是否可操作单条具体记录
    def has_object_permission(self, request, view, obj):
        if app_admin(request.user):
            return True
        # 校验当前用户是否和目标material有关联关系
        return UserMaterialAllow.objects.filter(
            user=request.user,
            material=obj
        ).exists()

2. 调整MaterialView配置

class MaterialView(viewsets.ModelViewSet):
    queryset = Material.objects.all()
    # 注意你原来的代码里是横线,要改成下划线的serializer_class
    serializer_class = MaterialSerializer
    # 绑定自定义权限类
    permission_classes = [MaterialPermission]

    # 重写查询集,普通用户仅能看到自己关联的Material
    def get_queryset(self):
        origin_queryset = super().get_queryset()
        user = self.request.user
        if app_admin(user):
            return origin_queryset
        return origin_queryset.filter(usermaterialallow__user=user)

    # 可选:普通用户创建Material时自动建立关联关系,根据你的业务逻辑调整
    def perform_create(self, serializer):
        material = serializer.save()
        if not app_admin(self.request.user):
            UserMaterialAllow.objects.get_or_create(
                user=self.request.user,
                material=material
            )

注意事项

  • 如果你的业务规则要求普通用户只能创建已经关联过权限的Material,可以在perform_create中添加校验,不符合规则直接返回403
  • 如果不需要自动创建关联关系,直接删除perform_create方法即可
  • 对象级权限默认不会对list接口生效,所以必须重写get_queryset做过滤,避免普通用户看到其他用户的Material

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 08:15:03