【问题标题】:How does drf serialize manytomany fieldsdrf如何序列化多对多字段
【发布时间】:2018-09-21 16:08:56
【问题描述】:

默认情况下,DRF 如何处理多线程序列化? 我认为它默认将字段呈现为 id 数组,例如:[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 列表而无需额外的查询成本? 我找不到任何关于他们如何实现多线程渲染的文档。

【问题讨论】:

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


    【解决方案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]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      相关资源
      最近更新 更多