数据准备
models.py
from django.contrib.auth.models import AbstractUser
from django.db import modelsclass 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.nameclass 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.nameclass 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_displayclass Meta:model = Authorfields = "__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 = Authorfields = "__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.addrclass Meta:model = Authorfields = "__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} ]