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

相關文章
相關標籤/搜索