drf如何序列化多个字段

时间:2018-04-11 16:59:21

标签: django python-3.x django-rest-framework

默认情况下DRF如何处理序列化多个人? 我看到默认情况下将字段渲染为ex:[1,2,3]

的数组

我预取相关模型时只使用2个查询。 但是,当我使用.values_list('id',flat = True)生成它时,它会为每一行进行额外的查询。

模型

class Fails(models.Model):
    runs = models.ManyToManyField(Runs, related_name='fails')

class Runs(models.Model):
    name = models.TextField()

查看

class FailsViewSet(viewsets.ModelViewSet):
    ...
    def get_queryset(self):
    ...
    return Fails.objects.filter(**params).prefetch_related('runs')

串行

class FailsSerializer(QueryFieldsMixin, serializers.ModelSerializer):
    runs = serializers.SerializerMethodField()

    def get_failbin_regressions(self, obj):
        runids = self.context.get('runids')
        return obj.runs.values_list('id', flat=True) #this creates an extra query for every row

最终目标是让运行显示已过滤的runid列表。

return obj.runs.values_list('id', flat=True).filter(id__in=runids)

runs = obj.runs.values_list('id', flat=True)
return [x for x in runs if x in runids] #to avoid an extra query from the .filter

我知道过滤器会创建更多查询,我认为预取模型在serializerMethodField中丢失了。

当我手动执行此操作时,有没有办法获取像drf这样的ID列表而没有额外的查询成本? 我找不到任何关于如何实现manytomany渲染的文档。

1 个答案:

答案 0 :(得分:1)

致电:

obj.runs.values_list('id', flat=True)

您正在执行新的数据库查询。因为它将为每个实例调用,所以你会有很多额外的查询。

prefetch_related加载关联的实例。因此,您无需额外查询即可与Python对象进行交互。您可以通过以下方式解决问题:

def get_failbin_regressions(self, obj):
    runids = self.context.get('runids')
    return [run.id for run in obj.runs.all() if run.id in runids]