How to Pass Extra Data to a Django REST Framework Serializer and Save it to the Database
Overview of Saving Data to the database using Django REST Framework Serializer
If you've worked with the standard Django form, you would have encountered the pattern where form data are temporarily stored with commit=False
, and afterward, some additional data are passed to the instance before saving it to the database.
This is very efficient for form handling because we can save the form data in a single database query. It is also useful in processing and passing data not defined in the form e.g time of registration, date, etc.
In this post, you will learn how to Pass Extra Data to a Django REST Framework Serializer and Save it to the Database.
In a standard Django form, a code snippet of the procedure would look like this:
form = VoterForm(request.POST)
if form.is_valid():
voter = form.save(commit=False)
voter.user = request.user
voter.save()
Set Up a Django REST Framework API Project
Django Version: Django 3.1.
O.S Platform: MacOs Mojave.
We will begin by installing Django and Django REST Framework (DRF):
pip install django
pip install djangorestframework
Next, we want to create a new Django REST Framework project and navigate to it:
django-admin.py startproject voterproject . && cd voterproject
Create a new app:
django-admin.py startapp source
Here is what your project structure should look like:
voterproject/
source/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
manage.py
Add the created source app and the installed rest_framework app to the INSTALLED_APPS
section in the settings.py file of the Django project:
voterproject/settings.py
INSTALLED_APPS = [
# Django Apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Third-Party Apps
'rest_framework',
# Personal Apps
'voterproject.source',
]
Next, we want to migrate the database:
python manage.py makemigrations
python manage.py migrate
Now, we want to set up a sample Voter model for the Django REST Framework Serializer.
voterproject/source/models.py
from django.contrib.auth.models import User
from django.db import models
class Voter(models.Model):
VOTED = 1
ACCEPTED = 2
REJECTED = 3
STATUS_CHOICES = (
(VOTED, 'You have voted.'),
(ACCEPTED, 'Your vote is accepted.'),
(REJECTED, 'Your vote is invalid.'),
)
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='voters')
voter_number = models.CharField(max_length=30)
date = models.DateTimeField(auto_now_add=True)
status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES)
Create a file named serializers.py
in the source app.
voterproject/source/serializers.py
from rest_framework import serializers
from source.models import Voter
class VoterSerializer(serializers.ModelSerializer):
class Meta:
model = Voter
fields = ('voter_number', 'status')
Two Ways to Save Extra Data to a Django REST Framework Serializer
How to Save Extra Data to a Django REST Framework Serializer Using ViewSet
voterproject/source/views.py
from rest_framework.viewsets import ModelViewSet
from source.models import Voter
from source.serializers import VoterSerializer
class VoterViewSet(ModelViewSet):
queryset = Voter.objects.all()
serializer_class = VoterSerializer
def perform_create(self, serializer):
serializer.save(user=self.request.user, status=Voter.SENT)
How to Save Extra Data to a Django REST Framework Serializer Using APIView
voterproject/source/views.py
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from source.models import Voter
from source.serializers import VoterSerializer
class VoterAPIView(APIView):
def post(self, request):
serializer = VoterSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(user=request.user, status=Voter.SENT)
return Response(status=status.HTTP_201_CREATED)