默认情况下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渲染的文档。
答案 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]