Django有很多外表查询,尽管有' select_related '



我想在django中加入一个父表和两个子表。

我可以看到,每次运行列表视图时,在ChildB表上执行50个查询(页面大小)。我认为我可以使用select_related方法提高性能,但似乎没有考虑到这一点。

使用prefetch_related的行为是预期的。

为什么不考虑select_related?

  • select_related for Django 2.2(我正在使用)
  • prefetch_related

模型:

class Parent(models.Model):
id = models.AutoField(primary_key=True)
uuid_a = models.ForeignKey(ChildA, db_column='uuid_a', db_index=True, default=None, editable=False, null=True,
on_delete=models.DO_NOTHING, primary_key=False, related_name='result_suppliers', unique=True,)
uuid_b = models.ForeignKey(ChildB, db_column='uuid_b', db_index=True, default=None, editable=False,
null=True, on_delete=models.DO_NOTHING, primary_key=False, related_name='duns_suppliers', unique=True,)

class ChildA(models.Model):
# ss
uuid = models.CharField(primary_key=True, editable=False, max_length=36, db_index=True)

class ChildB(models.Model):
# sd
id = models.AutoField(primary_key=True, editable=False)
duns_num = models.ForeignKey(ChildX, db_column='duns_num', to_field='duns_num', db_constraint=False, default=None, editable=False, null=True, on_delete=models.DO_NOTHING, primary_key=False, unique=False)

序列化器:


class ChildAListSerializer(serializers.ModelSerializer):
class Meta:
model = ChildA
fields = ['uuid', ]  # others

class ChildAListSerializer(serializers.ModelSerializer):
class Meta:
model = ChildB
fields = ['uuid', 'duns_num']  # others

class ParentListSerializer(serializers.Serializer):
uuid_a = ChildAListSerializer()
uuid_b = ChildBListSerializer()
last_sync = serializers.DateTimeField()
# others
class Meta:
model = Parent
fields = '__all__'

视图:

class ParentListView(ListAPIView):
"""
List view for deduplication suppliers screen
"""
filter_backends = [filters.DjangoFilterBackend]
filterset_class = DeduplicationParentFilter
pagination_class = LimitOffsetPagination
page_size = 30
max_page_size = 30
pk_field = 'id'  # Name of the primaryKey to use for counting
fk_fields = ['uuid_a', 'uuid_b']  # Name of the foreignKey to prefetch on request
model = Parent
serializer_class = ParentListSerializer
def get_queryset(self):
return Parent.objects.select_related(*self.fk_fields)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
result = {}

# Paginate response
page = self.paginate_queryset(queryset)
if page is not None:
# We can paginate, serialize page
serializer = self.get_serializer(page, many=True)
result['data'] = serializer.data
response = self.get_paginated_response(result)
else:
# We cant, serializer queryset
serializer = self.get_serializer(queryset, many=True)
result['data'] = serializer.data
response = JsonResponse(result)
return response

您的ChildB模型中有一个外键,它会导致额外的查询,因为您正在该模型序列化器中使用它。您需要将其添加到fk_fields。您可以像使用普通的form查询一样使用__来遵循这些关系。

fk_fields = ['uuid_a', 'uuid_b', 'uuid_b__duns_num']

相关内容

  • 没有找到相关文章

最新更新