Django REST Framework gets the value of the foreign key

Problem: Foreign key serialization, showing only id, not content

There are two models, and one model is the University, which contains the field name.The other is Student Student.There is a foreign key university pointing to the University model in Student.If you serialize the Student model by writing university directly from the field in the Meta class, the result is the id in University, not the name.

So there are two ways to get the field value in the foreign key, which is to get the name in University.

The problem code is as follows:

core/models.py

from django.db import models

class University(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = "University"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University,
                                   on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Student"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(self.first_name, self.last_name)

Serialize core/serializers.py

from rest_framework import serializers
from .models import University, Student


class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University
        fields = ('name')


class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ('university', 'first_name', 'last_name')

First method:

When serializing, create a new field called university_name, designated as serializers.CharField, and use the property source, specifically in the format:

  • CharField (source='<foreign key>. <corresponding properties of model pointed to by foreign key>')

core/models.py

from django.db import models

class University(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = "University"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University,
                                   on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Student"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(self.first_name, self.last_name)

core/serializers.py

Use CharField (source='<foreign key>. <corresponding properties of model pointed to by foreign key>')

from rest_framework import serializers
from .models import University, Student


class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University
        fields = ('name')


class StudentSerializer(serializers.ModelSerializer):
    university_name = serializers.CharField(source='university.name')

    class Meta:
        model = Student
        fields = ('university_name', 'first_name', 'last_name')

Second method:

This method is relatively more complex.

  • First, in models @property Decorator creates one first
    The university_name function, which returns the corresponding field of the foreign key corresponding to the model, such as university.name.
  • Then, when serializing, specify the serializers.ReadOnlyField() type.
class Student(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    university = models.ForeignKey(University,
                                   on_delete=models.CASCADE)

    class Meta:
        verbose_name = "Student"
        verbose_name_plural = verbose_name

    def __str__(self):
        return "{0} {1}".format(self.first_name, self.last_name)

    @property
    def university_name(self):
        return self.university.name

Use ReadOnly()

from rest_framework import serializers
from .models import University, Student


class UniversitySerializer(serializers.ModelSerializer):
    class Meta:
        model = University
        fields = ('name')
        
class StudentSerializer(serializers.ModelSerializer):
    university_name = serializers.ReadOnlyField()

    class Meta:
        model = Student
        fields = ('university_name', 'first_name', 'last_name')

Reference resources

Retrieving a Foreign Key value with django-rest-framework serializers

Tags: Django REST

Posted on Sun, 22 Mar 2020 09:32:20 -0700 by vtroubled