Django Rest:超链接模型序列化器传查询集报错求助
解决DRF中序列化查询集时的AssertionError问题
首先,咱们先搞明白这个报错的根源:你现在是在序列化数据库里的现有数据(返回点赞的用户列表),但错误地调用了.is_valid()方法——这个方法是给反序列化(比如处理POST请求的输入数据)用的,序列化输出的时候根本不需要它,而且你实例化序列化器时也没传data=参数,所以才会触发这个断言错误。
另外你提到用.values()或.values_list()会导致超链接URL生成失败,这是因为DRF的超链接字段(比如HyperlinkedModelSerializer里的字段)需要完整的模型实例来生成链接,而.values()返回的是字典,不是模型实例,自然没法生成正确的超链接。
修正后的代码
直接去掉不必要的.is_valid()调用,并且返回序列化器的.data属性(而不是序列化器本身)就可以解决问题:
class JobViewSet(viewsets.ModelViewSet): queryset = models.Job.objects.all() serializer_class = serializers.JobSerializer @action(methods=["get"], detail=True, url_path="like-detail", url_name="like-detail") def list_likes(self, request, pk=None): job = self.get_object() queryset = job.likes.all() # 序列化查询集时,直接传入模型实例集合,不需要data参数 serializer = UserSerializer(queryset, many=True, context={"request": request}) # 直接返回序列化后的data字典即可,不需要验证 return Response(serializer.data)
关键知识点说明
序列化 vs 反序列化的区别
- 当你要返回数据库中的数据时(GET请求),属于序列化输出:把模型实例转成JSON等格式,只需要把实例/QuerySet传给序列化器,然后取
.data属性返回。 - 当你要处理前端传入的数据时(POST/PUT/PATCH),属于反序列化输入:需要把
data=request.data传给序列化器,然后调用.is_valid()验证数据,再保存。
- 当你要返回数据库中的数据时(GET请求),属于序列化输出:把模型实例转成JSON等格式,只需要把实例/QuerySet传给序列化器,然后取
超链接字段的要求
如果你用了HyperlinkedModelSerializer或者HyperlinkedRelatedField,必须传递完整的模型实例给序列化器,同时在context里传入request(你已经做对了这部分),这样DRF才能基于当前请求生成正确的超链接URL。用.values()会丢失模型实例的上下文,所以肯定不行。
内容的提问来源于stack exchange,提问作者Gaurov Soni
相关产品推荐
相关产品推荐

