Django REST Framework 得到外键的值

问题:外键序列化,只显示 id 而不是内容

有两个 models,一个 model 是大学 University,包含字段 name。另外一个是学生 Student。Student 中存在外键 university 指向 University 这个 model。若是序列化 Student 这个 model 的时候,在 Meta 类里面的 field 直接写 university,获得的结果就是 University 中的 id,而不是对应的名字 name。django

所以这里采用两种方法去获取外键中的字段值,也就是拿到 University 中的 name。函数

问题代码以下:spa

core/models.py.net

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.pyrest

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 这个属性,具体而言格式为:code

  • CharField(source='<本model中的外键>.<外键指向的model的相应属性>')

core/models.pyorm

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.pyget

使用 CharField(source='<本model中的外键>.<外键指向的model的相应属性>')it

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')

第二种方法:

该方法相对更加复杂,io

  • 首先,在 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

相关文章
相关标签/搜索