15、Django_rest framework_序列化器之自定

2019-12-07  本文已影响0人  猪儿打滚
一、外键序列化字段PrimaryKeyRelatedField

首先说明下当前的两个model类的关系:projectinterface的主表,也就是一个project有多个interface
在对子表进行序列化时,会默认产生一个关联主表模型类的外键字段PrimaryKeyRelatedField

from rest_framework import serializers
from interfaces.models import Interfaces

class InterfaceModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Interfaces
        fields = '__all__'
>>> from interfaces.serializer import InterfacesSerializer
>>> InterfacesSerializer()
# 下面是结果
InterfacesSerializer():
    id = IntegerField(help_text='id主键', label='Id主键', read_only=True)
    create_time = DateTimeField(help_text='创建时间', label='创建时间', read_only=True)
    update_time = DateTimeField(help_text='更新时间', label='更新时间', read_only=True)
    name = CharField(help_text='接口名称', label='接口名称', max_length=100, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=100)
    desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', max_length=500, required=False)
    project = PrimaryKeyRelatedField(help_text='所属项目', queryset=Projects.objects.all())
>>> from interfaces.models import Interfaces
>>> one = Interfaces.objects.get(id=1)
>>> one
<Interfaces: 项目1 - 接口1>
>>> serialzer = InterfacesSerializer(one)
>>> serialzer
InterfacesSerializer(<Interfaces: 项目1 - 接口1>):
    id = IntegerField(help_text='id主键', label='Id主键', read_only=True)
    create_time = DateTimeField(help_text='创建时间', label='创建时间', read_only=True)
    update_time = DateTimeField(help_text='更新时间', label='更新时间', read_only=True)
    name = CharField(help_text='接口名称', label='接口名称', max_length=100, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=100)
    desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', max_length=500, required=False)
    project = PrimaryKeyRelatedField(help_text='所属项目', queryset=Projects.objects.all())
>>> serialzer.data
# 结果
{'id': 1, 'create_time': '2020-07-15T18:31:00+08:00', 'update_time': '2020-07-15T18:32:01.070581+08:00', 'name': '项目1 - 接口1', 'tester': 'test1', 'desc': '这是项目1 - 接口1', 'project': 1}

二、外键字段序列化为关联模型对象的__str__方法:StringRelatedField

续上面,如果想要默认输出的是projectname,那么就要用到StringRelatedFiled字段。
StringRelatedFiled:此字段将会被序列化为关联对象的字符串表达形式(__str__方法)

def __str__(self):
    return self.name
class InterfaceModelSerializer(serializers.ModelSerializer):
    # StringRelatedFiled,此字段将会被序列化为关联对象的字符串表达形式(__str__方法)
    project = serializers.StringRelatedFiled(label='所属项目名称',read_only=True)
    class Meta:
        model = Interfaces
        fields = '__all__'
>>> from interfaces.serializer import InterfacesSerializer
>>> from interfaces.models import Interfaces
>>> one = Interfaces.objects.get(id=1)
>>> serialzer = InterfacesSerializer(one)
>>> serialzer.data
{'id': 1, 'project': '项目一', 'create_time': '2020-07-15T18:31:00+08:00', 'update_time': '2020-07-15T18:32:01.070581+08:00', 'name': '项目1 - 接口1', 'tester': 'test1', 'desc': '这是项目1 - 接口1'}
三、外键字段序列化为关联模型对象的指定字段:SlugRelatedField

此时想要得到关联project的描述desc字段的值,那么就使用serializers.SlugRelatedField
serializers.SlugRelatedField:此字段将会被序列化为关联对象的指定字段的值

class InterfaceModelSerializer(serializers.ModelSerializer):
    # SlugRelatedField,此字段将会被序列化为关联对象的指定字段的值
    project = serializers.StringRelatedFiled(slug_field='leader',read_only=True)

    class Meta:
        model = Interfaces
        fields = '__all__'
>>> from interfaces.serializer import InterfacesSerializer
>>> from interfaces.models import Interfaces
>>> one = Interfaces.objects.get(id=1)
>>> serialzer = InterfacesSerializer(one)
>>> serialzer.data
# 结果,第二个字段
{'id': 1, 'project': 'leader1', 'create_time': '2020-07-15T18:31:00+08:00', 'update_time': '2020-07-15T18:32:01.070581+08:00', 'name': '项目1 - 接口1', 'tester': 'test1', 'desc': '这是项目1 - 接口1'}

四、外键字段序列化为关联模型对象的序列化器

想要通过外键字段,得到关联模型对象的序列化器

from projects.serializer import ProjectSerializer
project = ProjectSerializer(label='所属项目', read_only=True)
one_interface = Interfaces.objects.get(id=1)
print(one_interface )
### 下面是结果
>>> from interfaces.serializer import InterfacesSerializer
>>> from interfaces.models import Interfaces
>>> one = Interfaces.objects.get(id=1)
>>> serialzer = InterfacesSerializer(one)
>>> serialzer.data
{'id': 1, 'project': OrderedDict([('id', 1), ('create_time', '2020-07-15T18:28:00+08:00'), ('update_time', '2020-07-15T18:29:38.245015+08:00'), ('name', '项目一'), ('tester', 'test1'), ('leader', 'leader1'), ('programmer', 'programmer1'), ('publish_app', 'app1'), ('desc', '第一个项目')]), 'create_time': '2020-07-15T18:31:00+08:00', 'update_time': '2020-07-15T18:32:01.070581+08:00', 'name': '项目1 - 接口1', 'tester': 'test1', 'desc': '这是项目1 - 接口1'}
五、反向指定序列化字段[子表模型类名小写_set]

从上面可以知道,在对子表进行序列化时,会默认产生一个关联主表模型类的外键字段PrimaryKeyRelatedField
但是如果对主表进行序列化的时候,并不会默认产生关联子表模型类的字段(比如查询一个id=1的project的信息,并不会默认查询该project的interface的信息)
此时,我们可以手动指定添加这个关联字段。
比如,我想要在查询一个project的同时,得到该projcet的所有interface信息

## 变量名需要是子表模型类名小写_set,并且传参many=True
interfeces_set = serializers.StringRelatedField(many=True)
from projects.serializer import ProjectModelSerializer from projects.models import Projects
p = Projects.objects.get(id=1)
ProjectModelSerializer(p).data
{'id': 1, 'name': '项目一', 'interfaces_set': ['Interfaces object (1)', 'Interfaces object (2)'], 'programer': 'lzl',  'desc': '我是项目一的描述'}
class Interfaces(BaseModel):
    ...
    # related_name='interfaces',则反向指定序列化字段的值也为interfaces
    project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE, related_name='interfaces', help_text='所属项目') 
  ...

那么,上面例子的interfeces_set应该改成interfaces

上一篇下一篇

猜你喜欢

热点阅读