I have the below serializer:
class OrderItemResponseSerializer(serializers.ModelSerializer):
prepack_qty = serializers.SerializerMethodField()
product_description = serializers.SerializerMethodField()
class Meta:
model = OrderItem
fields = (
"product",
"qty_ordered",
"qty_approved",
"status",
"prepack_qty",
"product_description"
)
def get_prepack_qty(self, obj):
return obj.product.prepack_quantity
def get_product_description(self, obj):
return obj.product.product_description
When I make a get request to /orders
, I make a lot of SQL queries to the database because different orders may contain the same product. How can I cache the result of get_prepack_qty
and get_product_description methods? I tried to use @cached_property
this way:
class OrderItem(models.Model):
...
@cached_property
def item_product_description(self):
return self.product.product_description
But the number of requests to the database remained the same.
CodePudding user response:
Well, first of all, I should say that what you have implemented in this piece of code below:
...
@cached_property
def item_product_description(self):
return self.product.product_description
And using @cached_property
alone doesn't cache the data for you, you just created a property in the model for get_product_description
serializer method, And this does not reduce the volume and number of your queries to the database at all; Of course you need .bind()
method in your serializer method like below:
class BlobSerializer(SerializerCacheMixin, serializers.Serializer):
blobs = serializers.SerializerMethodField()
def get_blobs(self, instance):
# recursive serializer
serializer = self.__class__(instance.results, many=True)
serializer.bind('*', self)
return serializer.data
But in order to cache the result of this method As you asked in your question there is a good project in Pypi called drf-serializer-cache
you can use it easily for this purpose, for example, the following piece of code is taken from the document of this project:
from drf_serializer_cache import SerializerCacheMixin from rest_framework import serializer class ResultSerializer(SerializerCacheMixin, serializers.Serializer): results = serializers.SerializerMethodField() def get_results(self, instance): # recursive serializer serializer = self.__class__(instance.results, many=True) serializer.bind('*', self) # bind call is essential for >efficient cache! return serializer.data
Also if you want to implement it yourself in your project Seeing the implementation of SerializerCacheMixin
object in this project can help you a lot or even use it directly.