Solution to How to Pass Extra Data to a Django REST Framework Serializer and Save it to … - Sikademy

Nov. 28, 2020

Archangel Macsika Sikademy Image

Archangel Macsika

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)


Related Answers

Was this answer helpful?

Join our Community to stay in the know

Get updates for similar and other helpful Answers