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

如何安全设置UserList的权限类并实现仅返回当前用户数据

解决UserList的权限与数据过滤问题

当然可以通过重写get_queryset()方法来实现仅返回当前登录用户数据的需求,这也是Django REST Framework中处理这类数据权限问题的常规操作。下面根据不同业务场景给你具体的实现方案:

场景1:所有登录用户仅能访问自身数据

如果你的需求是不管用户角色,只要登录就只能查看自己的信息,完全看不到其他用户的数据,那可以直接修改get_queryset(),同时调整权限类确保只有登录用户能访问这个端点:

from django.contrib.auth import get_user_model
from rest_framework import mixins, generics
from rest_framework.permissions import IsAuthenticated

class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]  # 只允许登录用户访问

    def get(self, request, *args, **kwargs):
        self.serializer_class = UserGetSerializer
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def get_queryset(self):
        # 直接过滤当前登录用户的数据,不用依赖URL里的query参数,更安全
        return get_user_model().objects.filter(pk=self.request.user.pk)

这么做的优势:

  • 去掉了原来依赖query_params的逻辑,避免有人通过修改URL参数偷偷获取所有用户数据
  • 权限类设为IsAuthenticated,直接把未登录用户挡在外面
  • 从数据集根源上限制了范围,不管后续怎么处理,返回的都只会是当前用户的数据

场景2:管理员能看全量用户,普通用户仅能看自己

如果需要保留管理员查看全部用户的权限,同时限制普通用户只能访问自身数据,那可以在get_queryset()里加个用户角色判断:

from django.contrib.auth import get_user_model
from rest_framework import mixins, generics
from rest_framework.permissions import IsAuthenticated

class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    serializer_class = UserSerializer
    permission_classes = [IsAuthenticated]

    def get(self, request, *args, **kwargs):
        self.serializer_class = UserGetSerializer
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def get_queryset(self):
        current_user = self.request.user
        # 判断当前用户是否是管理员(staff或超级用户)
        if current_user.is_staff or current_user.is_superuser:
            return get_user_model().objects.all()
        else:
            # 普通用户只返回自己的数据
            return get_user_model().objects.filter(pk=current_user.pk)

额外的优化小建议

  • 如果你这个视图主要是用来让用户查看自己的信息,其实更推荐用RetrieveAPIView而不是ListAPIView——因为单个用户的数据是单条记录,用详情视图语义更清晰,代码也更简洁:
from rest_framework import generics

class UserProfileView(generics.RetrieveAPIView):
    serializer_class = UserGetSerializer
    permission_classes = [IsAuthenticated]

    def get_object(self):
        # 直接返回当前登录用户,不用从URL里取pk参数
        return self.request.user
  • 建议把创建用户和查看用户的逻辑拆成两个独立视图:一个UserCreateView处理用户注册,一个UserProfileView处理当前用户的信息查看,这样代码职责更单一,后续维护也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 12:22:32