【Django学习】(十)模型序列化器_关联字段序列化

简介: 【Django学习】(十)模型序列化器_关联字段序列化

这篇文章是针对模型类序列化器以及如何关联字段序列化 进行深入讲解的;

class ProjectModelSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(write_only=True)
    interfaces = InterfaceModelSerializer(label='所属接口的信息', help_text='所属接口的信息',
                                          read_only=True, many=True)
    class Meta:
        model = ProjectsModel
        fields = ('name', 'leader', 'tester','programmer','publish_app','email','interfaces')
        extra_kwargs = {
            'id': {
                'read_only': True},
            'name': {'max_length': 10, 'min_length': 5,
                     'validators': [UniqueValidator(ProjectsModel.objects.all(), message="项目名称不可重复!"),
                                    is_contain_project_word]},
            'tester': {
                'max_length': 10, 'min_length': 5,
                'error_messages': {"min_length": "tester长度不能少于5位", "max_length": "tester长度不能大于10位",
                                   "required": "tester字段为必填项"}
            },
            'desc': {
                'allow_null': True, 'default': 'desc默认值'
            },
            'programmer':{'write_only': True},
            'publish_app':{'write_only': True}
        }
    def create(self, validated_data):
        validated_data.pop('email')
        return super().create(validated_data)
    def update(self, instance, validated_data):
        return super().update(instance, validated_data)

一、模型类序列化器的使用

在上面的模型序列化类中:

  • 可以继承ModelSerializer类或者ModelSerializer的子类,来创建模型序列化器类;
  • 模型序列化器类中可以重新定义序列化器字段,优先级大于自动生成的同名字段
  • 如果新定义的字段不需要存储,则需要在调用create()方法时候删除掉该字段,比如上面的email字段

内部类 class Meta:

  • model=指定的模型类
  • 必须得在Meta内部类中使用model属性指定,参考的模型类;
  • 通过指定的模型类,来自动生成序列化器字段以及相关校验规则;
  • fields
  • 可以使用fields属性来指定哪些模型类中的字段,需要自动生成序列化器字段;
  • 指定一些个字段,例如  fields = ('name', 'leader')

如果fields中没有'programmer','publish_app',前端可以不传这些字段,即使前端传递了这两个参数,也不会进行校验,最后也不会存到数据库中

fields中有'programmer','publish_app',

若前端传递了这两个参数

如果属性为只读模式,则不会校验,返回为空,数据库为null

如果属性为只写模式,则会进行校验,最后也会存到数据库中,不会返回给前端

如果属性为读写模式,则会进行校验,最后也会存到数据库中和返回给前端

fields中有'programmer','publish_app',若前端没有传递这两个参数

如果属性为只读模式,则不会校验,返回为空

如果属性为只写模式,则校验不通过,报错 需要传这些参数

如果属性为读写模式,则校验不通过,报错 需要传这些参数

  • 指定全部字段,例如 fields = '__all__'
  • 排除某些字段,例如 exclude=('name','leader')
  • extra_kwargs
  • 字典类型;可以设置模型类字段的属性
  • 自定义的create方法与update方法
  • 我们可以调用父类的create方法与update方法来代替自己写的方法
def create(self, validated_data):
        validated_data.pop('email')
        return super().create(validated_data)
    def update(self, instance, validated_data):
        return super().update(instance, validated_data)

二、关联字段序列化

class InterfacesModel(BaseModel):
    id = models.IntegerField(primary_key=True, verbose_name="id主键", help_text="id主键")
    name = models.CharField(unique=True,max_length=200, verbose_name="接口名称", help_text="接口名称")
    tester = models.CharField(max_length=200, verbose_name="测试人员", help_text="测试人员")
    desc = models.CharField(max_length=200, verbose_name="简要描述", help_text="简要描述")
    # 数据表中,会创建名称为外键字段_id的字段名
    # project = models.ForeignKey("projects.ProjectsModel", on_delete=models.CASCADE)
    project = models.ForeignKey(ProjectsModel, on_delete=models.CASCADE,related_name="interfaces")
    # models.OneToOneField指定一对一的外键字段
    # models.ManyToManyField指定多对多的外键字段
    class Meta:
        db_table = "tb_interfaces"
        verbose_name = "接口表"
    def __str__(self):
        return self.name

1、主表序列化器类中关联从表字段

主表序列化器类默认是不会添加从表字段的,这时候需要我们手动定义要关联的从表字段

  • 一对多:父表序列化器类中如果定义从表关联字段,有多条从表数据,那么必须的添many=True,并且interfaces要加到fields里
  • 直接在主表的序列化对象中创建从表的序列化器类的对象,并赋值给字段名为“从表模型类名小写_set”的字段,然后将“从表模型类名小写_set”的字符名添加到Meta子类的fields属性中
  • 如果在从表定义了主表关联字段related_name
  • 在主表的序列化器类中,将外键字段名称“从表模型类名小写_set”更改为related_name属性的值
# interfaces = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
  • 如果在从表没有定义主表关联字段related_name
  • 则字段名为: 从表模型类名小写_set
# interfaces_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True)

1、输出的是主表id关联从表对应的从表id

       interfaces = serializers.PrimaryKeyRelatedField(read_only=True, many=True)

2、输出的是主表id关联从表的对应从表名

       interfaces=serializers.StringRelatedField(many=True)

会调用关联从表的序列化器类里定义的__str__方法,然后输出

3、输出的是主表id关联从表的从表查询集

       interfaces = InterfaceModelSerializer(label='所属接口的信息', help_text='所属接口的信息',read_only=True, many=True)

4、自定义输出关联从表的某一个字段属性值

interfaces=serializers.SlugRelatedField(slug_field='tester',read_only=True,many=True)

在这里推荐指定唯一键,比如name或者id之类的 ,这样才能够区分开到底关联的是父表的哪条数据

2、从表序列化器类中关联主表字段

从表因为模型类里定义了主表关联字段,所以从表序列化器类默认是创建主表关联字段的

1、输出的是从表关联主表id的对应主表id

  • project=serializers.PrimaryKeyRelatedField(queryset=ProjectsModel.objects.all())
  • 并且project要加到fields里

创建从表数据

查询从表数据

2、【StringRelatedField】输出的是从表关联父表id的对应主表名

       project=serializers.StringRelatedField(many=True)

 会调用关联主表的序列化器类里定义的__str__方法,然后输出

备注:

StringRelatedField只能用于序列化输出;

3、【主表序列化器类】输出的是从表关联主表id的主表查询集

       如果从表---主表是多对一的关系,则不需要添加属性many=True,否则会报错

      project = ProjectModelSerializer(label='接口所属项目的信息', help_text='接口所属项目的信息',read_only=True)

4、【SlugRelatedField】指定父表模型类中的某一个字段(尽量使用具有唯一约束的字段)进行输入或输出

4.1只输出该字段

  • 如果仅仅只需要输出那么添加read_only=True即可
  • project = serializers.SlugRelatedField(slug_field='desc', read_only=True)

在这里推荐指定唯一键,比如name或者id之类的 ,这样才能够区分开到底关联的是父表的哪条数据

4.2既要输入又要输出

  • 如果需要进行反序列化器输入(校验),必须得指定queryset
  • project = serializers.SlugRelatedField(slug_field='desc', queryset=ProjectsModel.objects.all())

如果不是唯一字段,可能会报错 :

projects.models.ProjectsModel.MultipleObjectsReturned: get() returned more than one ProjectsModel -- it returned 9!

【这个报错是说返回的模型类对象超过了1个,实际返回了9个】

所以我们最好设置唯一键

相关文章
|
3月前
|
XML 存储 JSON
Twaver-HTML5基础学习(19)数据容器(2)_数据序列化_XML、Json
本文介绍了Twaver HTML5中的数据序列化,包括XML和JSON格式的序列化与反序列化方法。文章通过示例代码展示了如何将DataBox中的数据序列化为XML和JSON字符串,以及如何从这些字符串中反序列化数据,重建DataBox中的对象。此外,还提到了用户自定义属性的序列化注册方法。
50 1
|
2月前
|
机器学习/深度学习 前端开发 网络架构
Django如何调用机器学习模型进行预测
Django如何调用机器学习模型进行预测
75 5
|
2月前
|
机器学习/深度学习 监控 数据挖掘
基于Django和百度飞桨模型的情感识别Web系统
基于Django和百度飞桨模型的情感识别Web系统
45 5
|
2月前
|
机器学习/深度学习 算法 搜索推荐
django调用矩阵分解推荐算法模型做推荐系统
django调用矩阵分解推荐算法模型做推荐系统
43 4
|
2月前
|
存储 开发框架 JSON
【查漏补缺】Django模型字段类型及其应用
【查漏补缺】Django模型字段类型及其应用
29 0
|
4月前
|
机器学习/深度学习 PyTorch 编译器
PyTorch 与 TorchScript:模型的序列化与加速
【8月更文第27天】PyTorch 是一个非常流行的深度学习框架,它以其灵活性和易用性而著称。然而,当涉及到模型的部署和性能优化时,PyTorch 的动态计算图可能会带来一些挑战。为了解决这些问题,PyTorch 引入了 TorchScript,这是一个用于序列化和优化 PyTorch 模型的工具。本文将详细介绍如何使用 TorchScript 来序列化 PyTorch 模型以及如何加速模型的执行。
166 4
|
4月前
|
API 数据库 开发者
【独家揭秘】Django ORM高手秘籍:如何玩转数据模型与数据库交互的艺术?
【8月更文挑战第31天】本文通过具体示例详细介绍了Django ORM的使用方法,包括数据模型设计与数据库操作的最佳实践。从创建应用和定义模型开始,逐步演示了查询、创建、更新和删除数据的全过程,并展示了关联查询与过滤的技巧,帮助开发者更高效地利用Django ORM构建和维护Web应用。通过这些基础概念和实践技巧,读者可以更好地掌握Django ORM,提升开发效率。
47 0
|
4月前
|
SQL Shell API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
python Django教程 之 模型(数据库)、自定义Field、数据表更改、QuerySet API
|
4月前
|
Java
JDK序列化原理问题之在JDK序列化中不同JDK版本字段不一致的情况如何解决
JDK序列化原理问题之在JDK序列化中不同JDK版本字段不一致的情况如何解决
|
4月前
|
SQL 关系型数据库 MySQL
如何创建 Django 模型
如何创建 Django 模型
30 0