- Python 3.5
- Django==1.11
- djangorestframework==3.6.2
问题:外键序列化,只显示 id 而不是内容
有两个 models,一个 model 是大学 University,包含字段 name。另一个是学生 Student。Student 中存在外键 university 指向 University 这个 model。如果序列化 Student 这个 model 的时候,在 Meta 类里面的 field 直接写 university
,得到的结果就是 University 中的 id,而不是对应的名字 name。
因此这里采用两种方法去获取外键中的字段值,也就是拿到 University 中的 name。
问题代码如下:
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
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')
第一种方法:
在序列化的时候,就创建一个新的字段叫 university_name,指定为 serializers.CharField
,而且字段使用 source 这个属性,具体而言格式为:
CharField(source='<本model中的外键>.<外键指向的model的相应属性>')
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
使用 CharField(source='<本model中的外键>.<外键指向的model的相应属性>')
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')
第二种方法:
该方法相对更加复杂,
- 首先,在 models 里面
@property
装饰符先创建一个
university_name 函数,这个函数返回的是外键对应 model 的相应字段,比如 university.name。 - 然后,序列化的时候,指定为
serializers.ReadOnlyField()
类型。
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
使用 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')
参考
Retrieving a Foreign Key value with django-rest-framework serializers