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
使用默认的序列化器时,视图函数访问 具有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.py
class 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.py
class 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
}
]