Оптимизация запроса в django

У меня имеются модели, сериализаторы, и вьюшка. Проблема n+1, у меня в бд 5 товаров, но по итогу просходит 7 запросов. Если я уберу метод get_color в сериализаторе, то запросов станет 2, но не будет нужных мне полей. Как сделать нужно, чтобы не было там много запросов.

models.py

class Product(models.Model):
    name = models.CharField(max_length=255, unique=True, verbose_name='Название')
    description = models.TextField(verbose_name='Описание')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='Цена')
    categories = models.ManyToManyField(Category, related_name='products', verbose_name='Категории')
    введите сюда код

class ProductColorSize(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, verbose_name='Товар', related_name='product_color_sizes')
    color = models.ForeignKey(Color, on_delete=models.CASCADE, verbose_name='Цвет')
    size = models.ForeignKey(Size, on_delete=models.CASCADE, verbose_name='Размер')

serializers.py

... # остальные обычные model сериализаторы


class ProductSerializer(ModelSerializer):
    colors = SerializerMethodField()

    class Meta:
        model = Product
        fields = '__all__'

    def get_colors(self, obj):
        color_sizes = defaultdict(set)

        for pcs in obj.product_color_sizes.filter(product=obj).select_related('product', 'color', 'size'):
            color_sizes[pcs.color].add(pcs.size.name)

        colors = []
        for color, sizes in color_sizes.items():
            color_data = ColorSerializer(color).data
            color_data['available_sizes'] = sorted(list(sizes))
            colors.append({"color": color_data})

        return colors

views.py

class ProductAPIView(ReadOnlyModelViewSet):
    serializer_class = ProductSerializer
    queryset = Product.objects.all().prefetch_related(
        Prefetch('categories', Category.objects.all().only('id')),
    )
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['id', 'categories']

Мне необходима следующая структура вывода данных:

[
  {
        "id": 1,
        "colors": [
            {
                "color": {
                    "id": 1,
                    "name": "Белый",
                    "available_sizes": [
                        "66",
                        "80"
                    ]
                }
            },
            {
                "color": {
                    "id": 2,
                    "name": "Черный",
                    "available_sizes": [
                        "80"
                    ]
                }
            }
        ],
        "name": "Название",
        "description": "Описание",
        "price": "1000",
        "categories": []
  },
]
Вернуться на верх