Django Rest Framework Tips and Tricks
Tags: django, djangorestframework, python
Published: 2021-06-28 05:19:42

---
title: Django Rest Framework Tips and Tricks
published: true 
tags:
  - "Django"
  - "DjangoRestFramework"
  - "Python"
---

> Original Post in https://skamalakannan.dev/posts/django-rest-framework-tips/

Django Rest Framework is a powerful tool for creating API, and it comes with a lot of features. Here is the list of tips that will help in developing your API better.

### **Sending common field in all the responses**
We might have use cases where we want to send a lot in all our responses, like resource URI, create date, or created user kind of fields.We can use serializer mixins for this purpose. Mixins are abstract classes, and we can define all the variables in these mixins, and we can inherit these mixins to the actual class. 

```python

from user.serializers import UserMinimumSerializer

class CreatedModifiedSerializer(serializers.Serializer):
    created_date = serializers.DateTimeField(read_only=True)
    created_by = UserMinimumSerializer(read_only=True)
    modified_date = serializers.DateTimeField(read_only=True)
    modified_by = UserMinimumSerializer(read_only=True)

    class Meta:
        abstract = True

class OrderSerializer(CreatedModifiedSerializer):

    class Meta:
        model = Order
        fields = '__all__'
```
In the above example, we have created a `CreatedModifiedSerializer` as a mixin. It will get applied to the `OrderSerializer`, if the `Order` doesn't have any one of the fields declared in the mixin, we will receive an exception.
### **Return computed value from the model**
if you have a scenario is to send the computed value. We can create a property for a model and specify the property name directly in the Serializer class.  
```python

class Order(models.Model):
    qty = models.IntegerField()
    price_per_qty = models.DecimalField(max_digits=5, decimal_places=2, default=0.0)

    @property 
    def total_amount(self):
        return self.qty * self.price_per_qty

class OrderSerializer(models.ModelSerializer):

    class Meta:
        model = Order
        fields = ('qty', 'price_pert_qty', 'total_amount') #Total amount is property of the model
```

Since the `total_amount` is a property, it will pick it directly. We can also declare the field type, specify as read-only, or result in an `AttributeError` exception.

### **Saving nested serializer**
If we want to create or update a nested model relation. drf-writable-nested is a package that comes for rescue; it supports nested serializer both create and update operations. it also available supports for OneToOne, ForeignKey, ManyToMany. 
https://github.com/beda-software/drf-writable-nested
```python
from drf_writable_nested.serializers import WritableNestedModelSerializer
from rest_framework.serializers import ModelSerializer

class OrderItemSerializer(ModelSerializer):
    class Meta:
        model = OrderItems
        fields = '__all__'

class OrderSerializer(WritableNestedModelSerializer):
    items = OrderItemSerializer(many=True)

    class Meta:
        model = Order
        fields = '__all__'

```
### **Accept object id while create and update, return object through serializer**
By default, DRF accepts and returns the field in the same format. If the use case is to accept the id update and create but return the serialized object. We can use `PresentablePrimaryKeyRelatedField` from the drf-extra-fields package for this purpose.
The custom field takes two arguments one is the `queryset` of the model, and another one `presentation_serializer` is a serializer class for the model. 
```python
from drf_extra_fields.relations import PresentablePrimaryKeyRelatedField
from rest_framework.serializers import ModelSerializer

class OrderSerializer(ModelSerializer):
    items = OrderItemSerializer(many=True)
    order_type = PresentablePrimaryKeyRelatedField(
        queryset = OrderType.objects.all(),
        presentation_serializer=OrderTypeSerializer
    )
    class Meta:
        model = Order
        fields = '__all__'

```
[drf-extra-fields](https://github.com/Hipo/drf-extra-fields) has many more custom fields, like `Base64ImageField`, it will accept a image file
as base64 encoded and will return as image file. please checkout the https://github.com/Hipo/drf-extra-fields for more information