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?