How can I reduce the number of queries in a queryset?

I have the following serializers:

class LiteratureProductSerializer(serializers.ModelSerializer):
  author = AuthorSerializer()
  binding = BindingSerializer()
  language = LanguageSerializer()
  genres = GenreSerializer(many=True)

  class Meta:
    model = LiteratureProduct
    fields = ('year_of_manufacture', 'pages', 'isbn', 'author', 'binding', 'language', 'genres')

class AccessoryProductSerializer(serializers.ModelSerializer):
  manufacturer = ManufacturerSerializer()
  seria = SeriaSerializer()
  material = MaterialSerializer()

  class Meta:
    model = AccessoryProduct
    fields = ('manufacturer', 'seria', 'material', 'size')

class FoodProductSerializer(serializers.ModelSerializer):
  manufacturer = ManufacturerSerializer()

  class Meta:
    model = FoodProduct
    fields = ('manufacturer')

class ClotherProductSerializer(serializers.ModelSerializer):
   material = MaterialSerializer()
   colors = ColorSerializer(many=True)
   sizes = SizeSerializer(many=True)

   class Meta:
    model = ClotherProduct
    fields = ('material', 'colors', 'sizes', 'year_of_manufacture')

class ProductSerializer(serializers.ModelSerializer):
   category = CategorySerializer()
   source = SourceSerializer()
   literature_product = LiteratureProductSerializer()
   accessory_product = AccessoryProductSerializer()
   food_product = FoodProductSerializer()
   clother_product = ClotherProductSerializer()

   class Meta:
    model = Product
    fields = ('id', 'name', 'slug', 'description', 'image', 'price', 'discount', 'amount', 'is_active', 'weight', 'rating', 'created_date', 'category', 'source', 'literature_product', 'accessory_product', 'food_product', 'clother_product')

Now I want to display information about a single object, which can belong to one of these four categories. I created the following API view. Since I have many ForeignKey and ManyToMany relationships, I used select_related and prefetch_related for optimization. Here's the code of my view:

class ProductsAPIView(RetrieveAPIView):
serializer_class = ProductSerializer
lookup_field = 'slug'
lookup_url_kwarg = 'product_slug'

def get_queryset(self):
    return Product.objects.select_related(
        'category', 'source', 'literature_product', 'literature_product__author', 'literature_product__binding', 'literature_product__language', 'accessory_product', 'food_product', 'clother_product',
    'accessory_product__manufacturer', 'accessory_product__seria', 'accessory_product__material', 'food_product__manufacturer',
    'clother_product__material',).prefetch_related(
        Prefetch('literature_product__author'),
        Prefetch('literature_product__binding'),
        Prefetch('literature_product__language'),
        Prefetch('literature_product__genres'),
        Prefetch('clother_product__colors'),
        Prefetch('clother_product__sizes'),
    )

Now I have the following problem: the query becomes too complex because even if the product is from the "Food" category, it still joins data from tables of other categories, resulting in a lot of joins. What can be done in this situation? Maybe the database structure was not designed correctly?

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