首页 文章

drf如何序列化多个字段

提问于
浏览
2

DRF默认如何处理序列化多个?我看到默认情况下将字段呈现为ids 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 回答

  • 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]
    

相关问题