我有一个 DRF
ModelSerializer
类,用于序列化 Order
模型。这个序列化器有一个字段:
num_modelA = serializers.SerializerMethodField()
`
def get_num_modelA(self, o):
r = ModelA.objects.filter(modelB__modelC__order=o).count()
return r
其中 ModelA 有一个
ForeignKey
字段 modelB
,ModelB 有一个 ForeignKey
字段 modelC
,ModelC 有一个 ForeignKey
字段 order
。
这样做的问题显然是,对于每个序列化的订单,它都会对数据库进行额外的查询,从而降低性能。
我已经实现了一个静态方法
setup_eager_loading
,如here所述,解决了我遇到的其他字段的N+1查询问题。
@staticmethod
def setup_eager_loading(queryset):
# select_related for "to-one" relationships
queryset = queryset.select_related('modelD','modelE')
return queryset
我的想法是我也可以使用
prefetch_related
来减少查询数量。但我不确定如何执行此操作,因为 Order 和 ModelA 由多个外键分隔。让我知道是否还有其他有用的信息
您可以使用注释:
from django.db.models import Count
# …
@staticmethod
def setup_eager_loading(queryset):
# select_related for "to-one" relationships
return queryset.select_related('modelD','modelE').annotate(
num_modelA=Count('modelC__modelB__modelA')
)
在
Order
的序列化器中,您可以使用 num_modelA
作为 IntegerField
:
from rest_framework import serializers
class OrderSerializer(serializers.ModelSerializer):
num_modelA = serializers.IntegerField()
class Meta:
model = Order
fields = ['num_modelA', 'and', 'other', 'fields']