- 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