【Django】 Pass the ModelSerializer an API-authenticated user instance


It was a note because it was slightly jammed.


  • Python 3.7.4
  • Django 3.0.3
  • django-rest-framework 3.11.0

About ModelSerializer

In django-rest-framework (DRF), conversion between Json and Model is performed via an object called ModelSerializer. When registering by editing the value received by the API, returning a record that does not exist in the table, processing data and making it Json, a method is often added to Serializer.

In DRF, when token authentication is performed, the user instance is stored in the request object. When you pass a user instance to Serializer, the value of the relation destination can be automatically entered, so there are many usage scenes.


The premise Visitor model is as follows.

import uuid
from django.db import models
from api.models import AppUser
from web.models import AdminUser

class Visitor(models.Model):
    class Meta:
        db_table = "visitor"
        verbose_name_plural = '訪問者'

    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    parent_user = models.ForeignKey(AdminUser,
    name = models.CharField(max_length=50)
    email = models.EmailField(max_length=255, null=True, blank=True)
    company = models.CharField(max_length=50, blank=True, null=True)
    memo = models.TextField(blank=True, null=True, max_length=300)
    visit_count = models.PositiveIntegerField(default=0)
    created_by = models.ForeignKey(AppUser,
                                   null=True, blank=True,
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name


Serializer generates fields tied to the model. To change the value arbitrarily, override it in the SerializerMethodField(). The field defined in the SerializerMethodField() calls a method called get_ and stores the return value.

get_ methods have instance in their arguments. Therefore, I thought that it would be passed here when API authentication is performed, but here it seems that the instance itself created at the time of Create is passed. (By using this, it is also possible to automatically create the data of the relation destination.) )

from rest_framework.serializers import ModelSerializer, SerializerMethodField

class VisitorCreateSerializer(ModelSerializer):
    created_by = SerializerMethodField()
    parent_user = SerializerMethodField()

    class Meta:
        model = Visitor
        read_only_fields = (
        fields = (

    def get_created_by(self, instance):
        return str(instance.pk)

    def get_parent_user(self, instance):
        return str(instance.parent_user.pk)


In the View, there is a part that instantiates a Serializer, so you can pass user to instance here. This time I wanted to separate serializer only create, so I overridden the create method and specified Serializer.

from rest_framework import status, viewsets
from rest_framework.permissions import IsAuthenticated
from .serializers import VisitorSerializer, VisitorCreateSerializer
from .models import Visitor
from utils.auth.authentication import APIAuthentication
from rest_framework.response import Response

class VisitorViewSet(viewsets.ModelViewSet):
    serializer_class = VisitorSerializer # create以外に使用するserializer
    queryset = Visitor.objects.all()

    authentication_classes = (APIAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get_queryset(self):
        # API認証した場合,userインスタンスはrequest.userに格納される。
        admin = self.request.user.parent_user
        qs = Visitor.objects.filter(parent_user=admin)
        return qs

    # createメソッドをオーバーライド
    def create(self, request, *args, **kwargs):
        # Serializerにrequest.userを渡すと、get_<field名>メソッドにinstanceが渡る
        serializer = VisitorCreateSerializer(instance=request.user, data=request.data)
        # ここから下はそのまま
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
Ela ragnar
Author by

Ela ragnar


Updated on February 21, 2020