I am using django-oscar with my own Product class, and a serializer for Django REST Framework. I am finding that adding some properties which are stored as attributes results in a huge number of queries.
For example as soon as I add "legacy_title" (which is an attribute I've added) to the serializer's fields, the number of queries made to render this result goes up from 3 to 70. I have 21 products in my databases.
from oscarapi.serializers.product import ProductSerializer as CoreProductSerializer
class ProductSerializer(CoreProductSerializer):
class Meta(CoreProductSerializer.Meta):
fields = (
"url",
"id",
"description",
"slug",
"upc",
"title",
"structure",
"legacy_title",
)
My Product class:
from oscar.apps.catalogue.abstract_models import AbstractProduct
def attribute_error_as_none(callable_):
try:
return callable_()
except AttributeError:
return None
class Product(AbstractProduct):
@property
def legacy_title(self) -> str:
return attribute_error_as_none(lambda: self.attr.legacy_title) or self.title
I'm using django-oscar-api's built-in ProductList view. If I add a few more fields which are backed by attributes, then the query count keeps going up, to 84 queries for these 21 products.
Then add things like children, recommendations, and images, and it takes 240 queries to render this result!
How can I get the query count under control? The endpoint to fetch all products is by far the slowest API endpoint in my entire backend and is becoming a problem. Should I override the ProductList view, with a custom queryset with some select_related or prefetch_related peppered in? I tried prefetch_related("attributes") but that only increases the query count by 1.
I brought the number of queries back under control by overriding
django-oscar-api'sProductList.To make use of these
prefetched_attr_values, myProductmodel looks like this: