Django ModelViewSet中request.user返回AnonymousUser报错排查
问题根因
这个报错和ModelViewSet、APIView的继承差异没有关系,本质是两个配置问题叠加导致的:
- 你的
DocumentViewSet配置了permission_classes = (AllowAny,),所有未登录的匿名请求都能直接进入视图逻辑,这时候self.request.user是Django内置的AnonymousUser实例,没有你自定义User模型的UUID格式主键 - 你写的
get_queryset方法没有做登录态判断,直接拿AnonymousUser实例去过滤Document的user外键字段,ORM在做查询参数校验时,发现传入的用户对象没有合法UUID值,直接抛出“AnonymousUser” is not a valid UUID的校验错误 - 你觉得其他APIView运行正常,本质是测试那些接口时你一直带着有效登录凭证,你可以试试不带任何认证信息请求
UserMeApi,一样会因为直接访问匿名用户的id属性报错,和视图类型无关。
修复方案
1. 先处理权限和查询集逻辑
如果Document接口只允许登录用户访问,直接替换权限类即可,未登录请求会被直接拦截返回401,根本不会走到get_queryset逻辑:
from rest_framework.permissions import IsAuthenticated class DocumentViewSet(viewsets.ModelViewSet): model = Document serializer_class = DocumentSerializer list_serializer_class = DocumentListSerializer # 替换原来的AllowAny permission_classes = (IsAuthenticated,) def get_queryset(self): return Document.objects.filter(user=self.request.user) # 其他原有方法暂时保留
如果业务上需要允许匿名访问部分接口(比如匿名用户查看公开文档),就在get_queryset里加匿名分支,不要拿匿名用户做外键过滤:
def get_queryset(self): user = self.request.user if user.is_anonymous: # 匿名用户返回空查询集,或者返回公开文档的查询集,例如 Document.objects.filter(is_public=True) return Document.objects.none() return Document.objects.filter(user=user)
2. 修复创建文档时用户字段丢失的隐藏bug
你现在的代码里有个逻辑冲突:你在序列化器里给user字段配了CurrentUserDefault,又在ViewSet里重写了perform_create传user参数,同时还重写了序列化器的create方法直接调用Document.objects.create——这会导致perform_create传入的user参数根本进不了你重写的create方法,最后创建出来的Document关联的user字段大概率是空的。
两种修复方式选一个就行:
- 方式一:删掉ViewSet里的
perform_create方法,保留序列化器user字段的CurrentUserDefault配置,登录态下序列化器会自动把当前用户写入validated_data,不需要额外传参 - 方式二:删掉序列化器user字段上的
default=serializers.CurrentUserDefault()配置,保留perform_create逻辑,同时修改序列化器的create方法,接收额外传入的keyword参数:def create(self, validated_data, **kwargs): question_blocks = validated_data.pop("question_blocks") outline_blocks = validated_data.pop("outline_blocks") source_cards = validated_data.pop("source_cards") # 把perform_create传进来的user参数带上 document = Document.objects.create(user=kwargs.get("user"), **validated_data) # 剩下的关联表创建逻辑不变
内容的提问来源于stack exchange,提问作者Tyler Kim
相关产品推荐
相关产品推荐

