drf之定制返回样式SerializerMethodField与在表模型中定制

发布时间 2023-04-21 16:09:13作者: 树苗叶子

SerializerMethodField

定制返回的样式为person:{name:xxx,age:xxx}或person:[{name:xxx, age:xxx},{name:yyy, age:yyy}...]等,就可以使用到SerializerMethodField

语法

  • 在序列化类中进行定义
    序列化字段名 = serializers.SerializerMethodField()
    def get_序列化字段名(self, obj) 这里的obj其实就是models.py中定义的表名
    return {} 最后return什么,前端就收到什么

示例

  • models.py中定义表
from django.db import models

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    # 图书与出版社外键字段,一对多
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    # 图书与作者外键字段,多对多
    authors = models.ManyToManyField(to='Author')

class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)

class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=11)

serializer.py中定义序列化类

class BookSerializers(serializers.Serializer):
    game_name = serializers.CharField(source='name')
    game_price = serializers.CharField(source='price')

    publish = serializers.SerializerMethodField()
    # obj其实就是序列化对象所在的表的表名
    # 定义函数时必须是  get_字段名 ,这里面的字段名指的是SerializerMethodField所在的字段
    # get_字段名 中的字段名是什么,前端拿到的字段名就是什么
    def get_publish(self, obj):
        # 这里的obj其实就相当于Book.publish.name中的Book
        return {'name': obj.publish.name, 'phone': obj.publish.addr}

    # 多对多关系的字定义
    authors = serializers.SerializerMethodField()
    def get_authors(self, obj):
        author_list = []
        for author in obj.authors.all():
            author_list.append({'name': author.name, 'phone': author.phone})
        return author_list
  • 如图查看返回结果的样式:

表模型中定制

from django.db import models


# Create your models here.
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    # 图书与出版社外键字段,一对多
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    # 图书与作者外键字段,多对多
    authors = models.ManyToManyField(to='Author')

    # 在模型表中定制序列化类
    # 注意一点:函数名不能与模型类中的字段名一致,否则会报错
    @property  # @property可以不加
    def publish_detail(self): # 定义的名字需要与serializer.py中定义的序列化类中的名字相同
        return {'name': self.publish.name, 'addr': self.publish.addr}

    @property
    def authors_detail(self): # 定义的名字需要与serializer.py中定义的序列化类中的名字相同
        list = []
        for author in self.authors.all():
            list.append({'name': author.name, 'phone': author.phone})
        return list


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)


class Author(models.Model):
    name = models.CharField(max_length=32)
    phone = models.CharField(max_length=11)

serializer.py

from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    game_name = serializers.CharField(source='name')
    game_price = serializers.CharField(source='price')
    # 接收一个字典则使用DictField,字段名需要与models.py中定义的函数一致
    publish_detail = serializers.DictField()
    # 接收一个列表,则使用ListField,字段名需要与models.py中定义的函数一致
    authors_detail = serializers.ListField()