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, и таким образом общее количество запросов сократится до одного.

Вернуться на верх