Django REST Framework 获得外键的值

本文介绍了在Django REST框架中如何将外键字段序列化为更具可读性的字符串形式,通过两种方法实现:一是利用CharField并设置source属性;二是通过@property装饰器创建新字段并使用ReadOnlyField。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:外键序列化,只显示 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

转载于:https://my.oschina.net/liuyuantao/blog/1806603

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值