Django REST Framework Serialized Foreign Key Method for getting the value of a foreign key

  • 2021-07-26 08:35:56
  • OfStack

Requirement: Serialize the foreign key and get the value of the foreign key except id

Using Django REST Framework although the development interface is fast, However, if you want to get foreign key information other than the foreign key id value, directly inherit the serializers. ModelSerializer class, and then specify in fields that the returned field cannot get other values of the foreign key. For example, I need the name attribute value of the foreign key now. Here are two methods to get the value of the foreign key we want by serializing the foreign key.

There are two Model: Questionnaire (Questionnaire); Question (Question). A questionnaire contains multiple questions, and the questions are associated with the corresponding questionnaires through foreign keys.

model.py


class Questionnaire(models.Model):
 ''' Questionnaire '''
 title = models.CharField(' Title ',max_length=100)
 class Meta:
  verbose_name_plural = ' All questionnaires '
 
class Question(models.Model):
 ''' Problem '''
 # Subordinate questionnaire 
 questionnaire = models.ForeignKey(Questionnaire,verbose_name=' Subordinate questionnaire ',related_name='questions')
 # Question title 
 title = models.CharField(' Problem ',max_length=150)
 # Whether it is multiple selection 
 is_checkbox = models.BooleanField(' Multiple selection ',default=False,help_text=' Is it a multiple choice problem ')
 class Meta:
  verbose_name_plural = ' Problem '

serializers.py


from rest_framework import serializers
from question.models import Question,Questionnaire
 
class QuestionnaireSerializer(serializers.ModelSerializer):
 class Meta:
  model = Questionnaire
  fields = ('title',)
 
class QuestionSerializer(serializers.ModelSerializer):
 class Meta:
  model = Question
  fields = ('title','is_checkbox')

This is no foreign key to serialize the code, we can only get model in the value of the field, so now I want to use QuestionSerializer this serialized class to get its foreign key questionnaire value (questionnaire_title), there are two ways to achieve

1. Create a new field (questionnaire_title) at serialization time and specify the attribute source= in this field as follows

serializers.py


from rest_framework import serializers
from question.models import Question,Questionnaire,Choice
 
class QuestionnaireSerializer(serializers.ModelSerializer):
 class Meta:
  model = Questionnaire
  fields = ('title',)
 
class QuestionSerializer(serializers.ModelSerializer):
 questionnaire_title = serializers.CharField(source='questionnaire.title')
 questionnaire_id = serializers.IntegerField()
 class Meta:
  model = Question
  fields = ('title','is_checkbox','questionnaire_title','questionnaire_id')

The reason why the attribute source= is not added to the second field questionnaire_id is that this field name is the same as the field name 1 in model, which will be automatically recognized by django. If this field is changed to questionnaire_ID, the attribute source= needs to be set.

2. Create a function named questionnaire_title directly in model through property decorator, and return the information we want in the function, such as questionnaire_name, questionnaire_id, and then specify it as ReadOnlyField () field when serializing; Specific operations are as follows

models.py


class Questionnaire(models.Model):
 ''' Questionnaire '''
 title = models.CharField(' Title ',max_length=100)
 class Meta:
  verbose_name_plural = ' All questionnaires '
 
class Question(models.Model):
 ''' Problem '''
 # Subordinate questionnaire 
 questionnaire = models.ForeignKey(Questionnaire,verbose_name=' Subordinate questionnaire ',related_name='questions')
 # Question title 
 title = models.CharField(' Problem ',max_length=150)
 # Whether it is multiple selection 
 is_checkbox = models.BooleanField(' Multiple selection ',default=False,help_text=' Is it a multiple choice problem ')
 class Meta:
  verbose_name_plural = ' Problem '
 
 @property
 def questionnaire_title(self):
  return self.questionnaire.title,self.questionnaire.id
serializers.py Use ReadOnly

from rest_framework import serializers
from question.models import Question,Questionnaire
 
class QuestionnaireSerializer(serializers.ModelSerializer):
 class Meta:
  model = Questionnaire
  fields = ('title',)
 
class QuestionSerializer(serializers.ModelSerializer):
 questionnaire_title = serializers.ReadOnlyField()
 questionnaire_id = serializers.ReadOnlyField()
 class Meta:
  model = Question
  fields = ('title','is_checkbox','questionnaire_title','questionnaire_id')

These are two ways to get foreign key information by serializing the foreign key, both of which are particularly simple and practical in general, except that the second method requires a few more lines of code.


Related articles: