Django-Rest-Framework: How to add a calculated field into the serializer (using SerializerMethodField)
The goal is to add an extra field into the model serializer, which is calculated based on a field of the model.
Consider the `Product
` model as below.
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=50)
price = models.DecimalField(max_digits=5, decimal_places=2)
def get_discounted_price(self, percent):
return "%.2f" % (float(self.price) * (1 - percent / 100))
def __str__(self):
return self.name
Note that we have a method named `get_discounted_price`, which calculated the discount and returns a new sale price, after applying the discount.
And we want to add a new field into the serializer called sale_price
which shows the sale price.
Consider the ProductSerializer
serializer as below.
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
sale_price = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Product
fields = ["name", "price", "sale_price"]
def get_sale_price(self, obj):
return obj.get_discounted_price(5)
In fields
we are adding a new field called sale_price
which is not an attribute in our model, so we need to define it as an attribute of the serializer.
So, sale_price
is defined as a SerializerMethodField
in our serializer, which by-default calls get_sale_price
method (get_<field_name>
).
get_sale_price method gets the instance as an argument (which is a model instance), and then use the model instance method to calculate the discounted price.
Finally, we have the following view (list_view
), which returns the list of products.
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Product
from .serializers import ProductSerializer
@api_view(["GET"])
def list_view(request):
products = Product.objects.all()
data = ProductSerializer(products, many=True).data
return Response(data)
Add this view into the `urls.py`, and see the results into the browser (or using Postman).
That's all! You have a field sale_price
in API response, coming through the serializer.
Thank you very much for reading!