django框架学习五:djangorestframework中ModelSerializer的关联字段的生成

表结构:

projects:项目表

interfaces:接口表,关联项目表的主键ID,在接口表中的字段为:project_id

创建接口序列化器时,关联字段project的创建可以分为以下几种情况:

1、默认为:PrimaryKeyRelatedField

from rest_framework import serializers
from .models import Interfaces


class InterfacesModelSerializer(serializers.ModelSerializer):
    # 默认情况是PrimaryKeyRelatedField
    class Meta:
        model = Interfaces
        fields = "__all__"

打开ipython:python manage.py shell -i ipython

可以看到序列化后的结果为:project的值为projects表的主键ID

In [1]: from interfaces.serializers import InterfacesModelSerializer

In [2]: InterfacesModelSerializer()
Out[2]: 
InterfacesModelSerializer(): id
= IntegerField(label='ID', read_only=True) name = CharField(help_text='接口名称', label='接口名称', max_length=50, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>]) tester = CharField(help_text='测试人员', label='测试人员', max_length=10) desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', required=False, style={'base_template': 'textarea .html'}) project = PrimaryKeyRelatedField(help_text='所属项目', label='所属项目', queryset=Projects.objects.all()) In [3]: from interfaces.models import Interfaces In [4]: one_data = Interfaces.objects.get(id=1) In [5]: InterfacesModelSerializer(one_data).data Out[5]: {'id': 1, 'name': '登录', 'tester': '小李', 'desc': '登录接口', 'project': 1}

2、使用StringRelatedField,代码为:

from rest_framework import serializers
from .models import Interfaces


class InterfacesModelSerializer(serializers.ModelSerializer):
    project = serializers.StringRelatedField(label="所属项目")
    class Meta:
        model = Interfaces
        fields = "__all__"

打开ipython:python manage.py shell -i ipython

可以看到序列化后的结果为:project的值为projects表的name

In [1]: from interfaces.serializers import InterfacesModelSerializer

In [2]: from interfaces.models import Interfaces

In [3]: InterfacesModelSerializer()
Out[3]: 
InterfacesModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    project = StringRelatedField(label='所属项目')
    name = CharField(help_text='接口名称', label='接口名称', max_length=50, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=10)
    desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', required=False, style={'base_template': 'textarea
.html'})

In [4]: one_data = Interfaces.objects.get(id=1)

In [5]: InterfacesModelSerializer(one_data).data
Out[5]: {'id': 1, 'project': '电子胶片项目', 'name': '登录', 'tester': '小李', 'desc': '登录接口'}

3、使用SlugRelatedField:

from rest_framework import serializers
from .models import Interfaces
from projects.models import Projects


class InterfacesModelSerializer(serializers.ModelSerializer):
    # project = serializers.SlugRelatedField(slug_field='tester', queryset=Projects.objects.all())
    # 或者
    project = serializers.SlugRelatedField(slug_field='tester', read_only=True)
    class Meta:
        model = Interfaces
        fields = "__all__"

打开ipython:python manage.py shell -i ipython

可以看到序列化后的结果为:project的值为projects表的指定的字段值(tester)

In [1]: from interfaces.serializers import InterfacesModelSerializer

In [2]: from interfaces.models import Interfaces

In [3]: InterfacesModelSerializer()
Out[3]: 
InterfacesModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    project = SlugRelatedField(read_only=True, slug_field='tester')
    name = CharField(help_text='接口名称', label='接口名称', max_length=50, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=10)
    desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', required=False, style={'base_template': 'textarea
.html'})

In [4]: one_data = Interfaces.objects.get(id=1)

In [5]: InterfacesModelSerializer(one_data).data
Out[5]: {'id': 1, 'project': '奔奔', 'name': '登录', 'tester': '小李', 'desc': '登录接口'}

4、使用关联对象的序列化器:

from rest_framework import serializers
from .models import Interfaces
from projects.serializers import ProjectsModelSerializer


class InterfacesModelSerializer(serializers.ModelSerializer):
    project = ProjectsModelSerializer(label="所属项目", read_only=True)

    class Meta:
        model = Interfaces
        fields = "__all__"

打开ipython:python manage.py shell -i ipython

可以看到序列化后的结果为:

In [1]: from interfaces.models import Interfaces

In [2]: from interfaces.serializers import InterfacesModelSerializer

In [3]: InterfacesModelSerializer()
Out[3]: 
InterfacesModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    project = ProjectsModelSerializer(label='所属项目', read_only=True):
        id = IntegerField(label='ID', read_only=True)
        name = CharField(error_messages={'max_length': '最长只能输入50个字符'}, help_text='项目名称', label='项目名称', max_length=200, validator
s=[<UniqueValidator(queryset=<QuerySet [<Projects: 电子胶片项目>]>)>, <function is_unique_project_name>])
        leader = CharField(help_text='负责人', label='负责人', max_length=50)
        tester = CharField(help_text='测试人员', label='测试人员', max_length=50)
        programer = CharField(help_text='开发人员', label='开发人员', max_length=50)
        publish_app = CharField(help_text='发布应用', label='发布应用', max_length=100)
        desc = CharField(allow_blank=True, allow_null=True, help_text='简要描述', label='简要描述', required=False, style={'base_template': 'text
area.html'})
    name = CharField(help_text='接口名称', label='接口名称', max_length=50, validators=[<UniqueValidator(queryset=Interfaces.objects.all())>])
    tester = CharField(help_text='测试人员', label='测试人员', max_length=10)
    desc = CharField(allow_blank=True, allow_null=True, help_text='接口描述', label='接口描述', required=False, style={'base_template': 'textarea
.html'})

In [4]: one_data = Interfaces.objects.get(id=1)

In [5]: InterfacesModelSerializer(one_data).data
Out[5]: {'id': 1, 'project': OrderedDict([('id', 1), ('name', '电子胶片项目'), ('leader', '小雨'), ('tester', '奔奔'), ('programer', '小安'), ('p
ublish_app', '微信公众号'), ('desc', '实时获取影像和检查报告')]), 'name': '登录', 'tester': '小李', 'desc': '登录接口'}

 5、在主表的序列化模型类中加上从表的模型类名小写_set,可以获取从表中的信息:

class ProjectsModelSerializer(serializers.ModelSerializer):
    # 父表中默认不会生成关联字段(从表字段), 可以手动指定, 字段名默认为 子表模型类名小写_set
    interfaces_set = serializers.StringRelatedField(many=True)

运行结果:

In [1]: from projects.models import Projects

In [2]: from projects.serializers import ProjectsModelSerializer

In [3]: ProjectsModelSerializer()
Out[3]: 
ProjectsModelSerializer():
    id = IntegerField(label='ID', read_only=True)
    interfaces_set = StringRelatedField(many=True)
    name = CharField(error_messages={'max_length': '最长只能输入50个字符'}, help_text='项目名称', label='项目名称', max_length=200, validators=[<
UniqueValidator(queryset=<QuerySet [<Projects: 电子胶片项目>]>)>, <function is_unique_project_name>])
    leader = CharField(help_text='负责人', label='负责人', max_length=50)
    tester = CharField(help_text='测试人员', label='测试人员', max_length=50)
    programer = CharField(help_text='开发人员', label='开发人员', max_length=50)
    publish_app = CharField(help_text='发布应用', label='发布应用', max_length=100)
    desc = CharField(allow_blank=True, allow_null=True, help_text='简要描述', label='简要描述', required=False, style={'base_template': 'textarea
.html'})

In [4]: one_data = Projects.objects.get(id=1)

In [5]: ProjectsModelSerializer(one_data).data
Out[5]: {'id': 1, 'interfaces_set': ['登录'], 'name': '电子胶片项目', 'leader': '小雨', 'tester': '奔奔', 'programer': '小安', 'publish_app': '
信公众号', 'desc': '实时获取影像和检查报告'}
原文地址:https://www.cnblogs.com/benben-wu/p/12494354.html