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

为何Django REST中管理员用户无法通过IsAdminUser权限验证?

Django REST框架管理员授权问题解决方案

问题根源

你遇到的未授权提示,核心原因是Django REST框架的IsAdminUser权限类,判断的是Django内置User模型的is_staff或is_superuser字段是否为True,但你创建Admin对象时,关联的User对象默认这两个属性都是False(create_user方法的默认值),所以权限验证直接失败。

具体修复步骤

1. 修复Admin创建逻辑,给关联User设置管理员属性

把AdminAPIViewSet中创建Admin的代码修改,直接给刚生成的django_user对象设置并保存管理员属性,不要用硬编码的pk=1001:

def create(self, request, *args, **kwargs):
    serializer = AdminSerializer(data=request.data)
    if serializer.is_valid():
        email = serializer.data['email']
        username = serializer.data['email']
        password = serializer.data['password']

        with transaction.atomic():
            django_user = User.objects.create_user(username, email, password)
            # 给关联的User对象开启管理员权限
            django_user.is_staff = True
            django_user.is_superuser = True
            django_user.save()
            
            admin = Admin.objects.create(**serializer.data, django_user=django_user)
            return Response(admin.pk)

    return Response({'error': 'Invalid data'}, status=status.HTTP_400_BAD_REQUEST)

注:create_user方法创建的User默认is_staff和is_superuser都是False,必须显式设置并保存,才能让IsAdminUser权限类通过验证。

2. 优化AdminAPIViewSet的查询逻辑(可选但更合理)

当前的get_queryset让管理员只能查看自己的Admin数据,若需要管理员查看所有Admin数据,可调整为:

def get_queryset(self):
    user = self.request.user
    if user.is_authenticated:
        # 管理员返回所有Admin数据,普通用户仅返回自身关联数据
        if user.is_staff or user.is_superuser:
            return Admin.objects.all()
        return Admin.objects.filter(username=user.admin.username)
    return Admin.objects.none()  # 用ORM的none()比空列表更规范

3. 实现普通客户仅查看自身数据的权限逻辑

针对普通客户的只读视图(ClientReadOnlyAPIViewSet),需要自定义权限类,确保普通用户只能访问自己的客户数据,管理员可访问所有:
首先定义自定义权限类:

from rest_framework import permissions

class IsOwnerOrAdmin(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # 管理员允许访问所有对象
        if request.user.is_staff or request.user.is_superuser:
            return True
        # 普通用户仅能访问自己关联的Client对象
        return obj.django_user == request.user

然后修改ClientReadOnlyAPIViewSet:

class ClientReadOnlyAPIViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer
    permission_classes = [permissions.IsAuthenticated, IsOwnerOrAdmin]

    def get_queryset(self):
        user = self.request.user
        if user.is_staff or user.is_superuser:
            return Client.objects.all()
        # 普通用户仅返回自身关联的Client数据
        return Client.objects.filter(django_user=user)

4. 验证效果

  • 创建Admin账号后,登录访问/api/v1/clientslist/,应能查看所有客户数据
  • 普通客户登录后访问/api/v1/clients/,仅能看到自己的数据
  • 未登录用户无法访问上述受权限保护的端点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:25:22