当前位置:首页 > 编程笔记 > 正文
已解决

Django系列之Serializer的source参数使用、自定义序列化方法

来自网友在路上 164864提问 提问时间:2023-11-05 12:47:29阅读次数: 64

最佳答案 问答题库648位专家为你答疑解惑

数据准备

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参数:

  1. get_xxx_display 用于显示 choices 参数对应的文本信息。
    serializers.py

    class 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()
    '男'
    >>>
    
  2. 显示 一对一一对多多对多 字段对应的文本信息。
    serializers.py

    class 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}
    ]
    
  3. 自定义序列化输出方法

    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}
    ]
    
查看全文

99%的人还看了

相似问题

猜你感兴趣

版权申明

本文"Django系列之Serializer的source参数使用、自定义序列化方法":http://eshow365.cn/6-32705-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!