数据准备
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class Publish(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=8)
email = models.CharField(max_length=32)
def __str__(self):
return self.name
class AuthorDetail(models.Model):
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=64)
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
gender = models.IntegerField(choices=(('1', '男'), ('0', '女')))
ad = models.OneToOneField(AuthorDetail, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
pub_date = models.DateField()
publish = models.ForeignKey(Publish, on_delete=models.CASCADE, null=True)
authors = models.ManyToManyField(Author, db_table="book2author")
def __str__(self):
return self.title
serializers字段的source参数
使用默认的序列化器时,视图函数访问 具有choices参数
的字段或 一对一
或 一对多
或 多对多
字段时,返回的数据只有 id
值,就像下面这种方式,性别是0或1,居住地址是居住详情表中的id值:
[
{
"id": 1,
"name": "阿明",
"age": 16,
"gender": 1,
"ad": 1
},
{
"id": 3,
"name": "阿美",
"age": 21,
"gender": 0,
"ad": 3
}
]
对上面这些场景使用source参数:
-
get_xxx_display
用于显示 choices 参数对应的文本信息。
serializers.pyclass AuthorSerializer(serializers.ModelSerializer): gender_txt = serializers.CharField(source='get_gender_display') # 使用get_xxx_display class Meta: model = Author fields = "__all__"
返回的结果:
[ { "id": 1, "gender_txt": "男", "name": "阿明", "age": 16, "gender": "1", "ad": 1 }, { "id": 2, "gender_txt": "男", "name": "阿伟", "age": 25, "gender": "1", "ad": 2 }, { "id": 3, "gender_txt": "男", "name": "阿华", "age": 21, "gender": "1", "ad": 3 }, { "id": 4, "gender_txt": "女", "name": "阿美", "age": 16, "gender": "0", "ad": 4 } ]
注意:为什么添加了
source=get_xxx_display
还是没有显示出对应文本信息?把choices=(('1', '男'), ('0', '女'))
的 0 和 1 改成字符串形式再试试。当然,也可以在视图函数中,使用
obj.get_xxx.display()
来获取choices文本值。>>> Author.objects.get(id=1).gender '1' >>> Author.objects.get(id=1).get_gender_display() '男' >>>
-
显示
一对一
或一对多
或多对多
字段对应的文本信息。
serializers.pyclass AuthorSerializer(serializers.ModelSerializer): gender_txt = serializers.CharField(source='get_gender_display') address_txt = serializers.CharField(source='ad.addr') # 支持连表查询 class Meta: model = Author fields = "__all__"
返回的结果:
[ { "id": 1, "gender_txt": "男", "address_txt": "beijing", "name": "阿明", "age": 16, "gender": "1", "ad": 1 }, { "id": 2, "gender_txt": "男", "address_txt": "shanghai", "name": "阿伟", "age": 25, "gender": "1", "ad": 2 }, { "id": 3, "gender_txt": "男", "address_txt": "shanghai", "name": "阿华", "age": 21, "gender": "1", "ad": 3 }, { "id": 4, "gender_txt": "女", "address_txt": "guangzhou", "name": "阿美", "age": 16, "gender": "0", "ad": 4 } ]
-
自定义序列化输出方法
class AuthorSerializer(serializers.ModelSerializer): gender_txt = serializers.CharField(source='get_gender_display') address_zidingyi = serializers.SerializerMethodField() # 自定义序列化方法, 会寻找并执行'get_xxx'的方法。 def get_address_zidingyi(self, obj): return obj.ad.addr class Meta: model = Author fields = "__all__"
返回的结果:
[ { "id": 1, "gender_txt": "男", "address_zidingyi": "beijing", "name": "阿明", "age": 16, "gender": "1", "ad": 1 }, { "id": 2, "gender_txt": "男", "address_zidingyi": "shanghai", "name": "阿伟", "age": 25, "gender": "1", "ad": 2 }, { "id": 3, "gender_txt": "男", "address_zidingyi": "shanghai", "name": "阿华", "age": 21, "gender": "1", "ad": 3 }, { "id": 4, "gender_txt": "女", "address_zidingyi": "guangzhou", "name": "阿美", "age": 16, "gender": "0", "ad": 4 } ]