Django REST Framework 序列化外键:获取非 ID 字段的两种方案
本文介绍在 Django REST Framework 中如何序列化外键以获取非 ID 字段信息。通过两种方法实现:一是在 Serializer 中使用 source 属性指定关联字段;二是在 Model 中利用 property 装饰器定义计算字段并配合 ReadOnlyField。适用于需要返回关联对象详细信息的 API 开发场景。
Django REST Framework 序列化外键:获取非 ID 字段的两种方案
需求:序列化外键,获取外键的除id之外的值
虽然 Django REST Framework 能加速接口开发,但若需返回外键关联对象的非 ID 属性(如 name),仅继承 serializers.ModelSerializer 并在 fields 中指定字段名是无法直接获取的。本文将介绍两种通过序列化外键来获取目标外键值的有效方法。
本文示例涉及两个 Model:问卷(Questionnaire)与问题(Question)。数据结构上,一张问卷包含多个问题,问题通过外键关联至对应的问卷。
模型定义与初始序列化配置
model.py
class Questionnaire(models.Model):
'''问卷'''
title = models.CharField('标题',max_length=100)
class Meta:
verbose_name_plural = '所有问卷'
class Question(models.Model):
'''问题'''
#所属问卷
questionnaire = models.ForeignKey(Questionnaire,verbose_name='所属问卷',related_name='questions')
#问题标题
title = models.CharField('问题',max_length=150)
#是否是多选
is_checkbox = models.BooleanField('是否多选',default=False,help_text='是否是多选问题')
class Meta:
verbose_name_plural = '问题'
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')
上述代码未对外键进行序列化,仅能获取 Model 中定义的直接字段值。若希望 QuestionSerializer 返回外键 question 的 questionnaire_title 属性,可采用以下两种实现方式。
方法一:使用 source 属性指定外键字段
1. 在序列化类中定义新字段(如 questionnaire_title),并通过 source 属性指定其数据来源。具体实现如下:
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')
字段 questionnaire_id 未设置 source 属性,因其名称与 Model 中的字段名一致,Django 会自动映射。若将该字段重命名为 questionnaire_ID,则必须显式设置 source 属性以建立映射关系。
方法二:利用 property 装饰器与 ReadOnlyField
2. 在 Model 中使用 property 装饰器定义名为 questionnaire_title 的方法,返回所需信息(如 questionnaire_name 和 questionnaire_id)。在序列化时,将该字段指定为 ReadOnlyField()。具体实现如下:
models.py
class Questionnaire(models.Model):
'''问卷'''
title = models.CharField('标题',max_length=100)
class Meta:
verbose_name_plural = '所有问卷'
class Question(models.Model):
'''问题'''
#所属问卷
questionnaire = models.ForeignKey(Questionnaire,verbose_name='所属问卷',related_name='questions')
#问题标题
title = models.CharField('问题',max_length=150)
#是否是多选
is_checkbox = models.BooleanField('是否多选',default=False,help_text='是否是多选问题')
class Meta:
verbose_name_plural = '问题'
@property
def questionnaire_title(self):
return self.questionnaire.title,self.questionnaire.id
serializers.py使用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')
以上介绍了通过序列化外键获取外键信息的两种方法。两者均简单实用,区别在于第二种方法需在 Model 中额外编写少量代码。
以上这篇Django REST Framework序列化外键获取外键的值方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









