Django обратный внешний ключ приводит к дублированию запросов
Я пытаюсь использовать ViewSet для возврата списка всех активов с именем типа актива (вместо простого id), но согласно django-debug-toolbar, мои запросы дублируются, что приводит к более медленным результатам.
1 Тип актива может иметь несколько активов.
Итак, когда я пытаюсь получить все активы (дочерние) - он пытается получить имена типов активов (родительских) для каждого из активов (дочерних), но он выполняет один запрос для каждого актива (дочернего). Выглядит это примерно так: Он дублируется 6 раз, потому что у меня 6 значений в таблице Asset в настоящее время.
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.00
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times. 3.95
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times.
Ожидаемый результат
Все, что мне нужно, это просто список всех активов вместе с названиями AssetType - есть ли лучший способ сделать это?
Вот мои модели:
class AssetType(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=80, unique=True)
description = models.CharField(max_length=80)
class Meta:
db_table = "mm_asset_type"
class Asset(models.Model):
asset_type = models.ForeignKey(AssetType, on_delete=models.CASCADE)
asset_name = models.CharField(max_length=80)
display_name = models.CharField(max_length=80)
class Meta:
db_table = "mm_asset_registry"
Вот мои сериализаторы:
class AssetTypeSerializer(serializers.ModelSerializer):
class Meta:
model = AssetType
fields = "__all__"
class AssetSerializer(serializers.ModelSerializer):
asset_type_name = serializers.CharField(source='asset_type.name')
class Meta:
model = Asset
fields = ("id", "asset_type_name", "asset_name", "display_name")
Наконец, это мой ViewSet
class AssetViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
queryset = Asset.objects.all()
serializer_class = AssetSerializer
Итак, когда я пытаюсь получить все активы - он пытается получить имена типов активов для каждого из них, но выполняет один запрос для каждого актива. Выглядит это примерно так:
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (27,)
6 similar queries. Duplicated 3 times. 3.00
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times. 3.95
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times. 3.99
Sel Expl
+
QUERY = 'SELECT TOP 21 [mm_asset_type].[id], [mm_asset_type].[name], [mm_asset_type].[description] FROM [mm_asset_type] WHERE [mm_asset_type].[id] = %s' - PARAMS = (29,)
6 similar queries. Duplicated 3 times.
Ожидаемый результат
Все, что мне нужно, это просто список всех активов (дочерних) вместе с именами AssetType (родительских) - есть ли лучший способ сделать это?
Спасибо
Вам следует использовать .select_related(…)
[Django-doc] для получения типов с тем же запросом:
class AssetViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
queryset = Asset.objects.select_related('asset_type')
serializer_class = AssetSerializer
Таким образом, поля asset_type
будут получены в том же запросе, что и поля Asset
, и таким образом общее количество запросов сократится до одного.