Django--DRf---序列化器:序列化器嵌套

news2024/12/23 17:35:16

模型表:

from django.db import models

# Create your models here.

class StudentModel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32,verbose_name='姓名')
    age = models.SmallIntegerField(verbose_name='年龄')
    class_mate_f = models.ForeignKey(to='ClassMateModel',on_delete=models.SET_NULL,null=True,
                                     related_name='students',related_query_name='students',db_constraint=False)

class ClassMateModel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=64,verbose_name='班级名')

class ClassMateDetail(models.Model):
    id = models.AutoField(primary_key=True)
    address = models.CharField(max_length=32,verbose_name='地址')
    class_mate_f = models.ForeignKey(to='ClassMateModel',on_delete=models.CASCADE,null=True,
                                     related_name='detail',related_query_name='detail',db_constraint=False)

class TeacherModel(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32,verbose_name='姓名')
    age = models.SmallIntegerField(verbose_name='年龄')
    phone = models.CharField(max_length=13,verbose_name='手机号码')
    class_mate_f = models.ManyToManyField(to='ClassMateModel',null=True,
                                          related_name='teachers',related_query_name='teachers',db_constraint=False)

#通过其他三张表的related_name 后,ClassMateModel就多了三个虚拟字段:students,teachers,detail

请添加图片描述

一、外键在的一方

1、方式一:通过source来获取指定字段数据 【一对多和一对一的】

1.1、一对多 外键方
序列化器:
class StudentModelSerializer(serializers.ModelSerializer):
    class_mate_pk = serializers.CharField(source='class_mate_f.id')
    class_mate_name = serializers.CharField(source='class_mate_f.name')
    class Meta:
        model = models.StudentModel
        fields = ['id','name','class_mate_pk','age','class_mate_name']
        
 
视图函数:
#学生创建
class StudentGenericAPIView(GenericAPIView):
    authentication_classes = []
    queryset = models.StudentModel.objects.all()
    serializer_class = serializer.StudentModelSerializer
    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})
1.2、多对多 外键方 【不适应】

2、方式二:通过外键=序列化类() 【适用所有关系】

2.1、多对多:外键在这里

序列化器:

class ClassMateForTeacherModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.ClassMateModel
        fields = ['id','name']

class TeacherModelSerializer(serializers.ModelSerializer):
    class_mate_f = ClassMateForTeacherModelSerializer(many=True)
    class Meta:
        model = models.TeacherModel
        fields = ['id','name','age','phone','class_mate_f']

视图类:

class TeacherGenericAPIView(GenericAPIView):
    queryset = models.TeacherModel.objects.all()
    serializer_class = serializer.TeacherModelSerializer

    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})
2.2、一对多,外键方 【学生表,嵌套班级】
序列化器:
class ClassMateForStudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.ClassMateModel
        fields = ['id','name']

class StudentModelSerializer(serializers.ModelSerializer):
    class_mate_f = ClassMateForStudentModelSerializer(read_only=True)
    class Meta:
        model = models.StudentModel
        fields = ['id','name','class_mate_f','age']
        
        
视图:
class StudentGenericAPIView(GenericAPIView):
    authentication_classes = []
    queryset = models.StudentModel.objects.all()
    serializer_class = serializer.StudentModelSerializer
    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})

3、方式三:通过depth 【适用所有关系】

起始表–外键-------------> 表1-外键--------------> 表2–外键------------->表3

这样,depth=4 ,会一直追踪外键,直达表中没有外键字段。

3.1、一对多:学生表- -外键----->班级表
#序列化器
class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.StudentModel
        fields = ['id','name','class_mate_f','age']
        depth = 2 #等于表数

#视图 
class StudentGenericAPIView(GenericAPIView):
    authentication_classes = []
    queryset = models.StudentModel.objects.all()
    serializer_class = serializer.StudentModelSerializer
    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})
3.2、多对多:老师-外键------->班级
#序列化器
class TeacherModelSerializer(serializers.ModelSerializer):
    # class_mate_f = ClassMateForTeacherModelSerializer(many=True,read_only=True)
    class Meta:
        model = models.TeacherModel
        fields = ['id','name','age','phone','class_mate_f']
        depth =2 #涉及到的表数量
   
#视图
class TeacherGenericAPIView(GenericAPIView):
    queryset = models.TeacherModel.objects.all()
    serializer_class = serializer.TeacherModelSerializer

    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})
        

二、外键不在的一方[查询班级为例子]

【只能使用序列化器嵌套的方式】

注意:反向查询,都是通过反向查询字段=序列化器(many=True)

在这四张表中:ClassMateModel是没有一个外键字段,但是其他三张表都有ClassMateModel外键,

通过related_name, 在子查询时,就可以通过设置好的名字进行跨表,而且也查询结果是多个时也不需要使用_set了;

query_related_name 在联表查询时,通过设置好的名字进行跨表操作。

在查询班级信息时,需要班级详情信息、学生信息、老师信息;下面通过序列化器嵌套来实现

视图:

class ClassMateGenericAPIView(GenericAPIView):
    authentication_classes = []
    queryset = models.ClassMateModel.objects.all()
    serializer_class = serializer.ClassMateModelSerializer
    def get(self,request):
        ser = self.get_serializer(instance = self.get_queryset(),many=True)
        return Response({'code':200,'data':ser.data})

序列化器:

#老师
class TeacherForClassMateMdoelserializer(serializers.ModelSerializer):
    class Meta:
        model = models.TeacherModel
        fields = ['id','name','phone']

#班级详情
class ClassDetailForClassMateModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.ClassMateDetail
        fields =['address']

#学生
class StudentForClassMate(serializers.ModelSerializer):
    class Meta:
        model = models.StudentModel
        fields = ['name','age']

#班级
class ClassMateModelSerializer(serializers.ModelSerializer):
    teachers = TeacherForClassMateMdoelserializer(many=True,read_only=True)
    detail = ClassDetailForClassMateModelSerializer(many=True,read_only=True)
    students = StudentForClassMate(many=True,read_only=True)
    class Meta:
        model = models.ClassMateModel
        fields =['id','name','teachers','students','detail']
        extra_kwargs = {
            'id':{'read_only':True},
            'teachers':{'read_only':True},
            'detail':{'read_only':True},
            'students':{'read_only':True},
        }

总结
1、通过related_name , ClassMateModel 相当于多了,students、teachers和detail 三个字段。
2、使用这三个字段来接收序列器对象,就可以实现序列化嵌套了。
3、注意,在实例化序列化器时,必须带上many=True 不然会报错。【因为外键不在当前模型类中,所有可能会有多个数据,即使是一对一的关系表,也要加many=true】
4、加上read_only=True ,不参与到反序列化中。如果该序列化器不参与反序列就无须写。

总结
1、通过related_name , ClassMateModel 相当于多了,students、teachers和detail 三个字段。
2、使用这三个字段来接收序列器对象,就可以实现序列化嵌套了。
3、注意,在实例化序列化器时,必须带上many=True 不然会报错。【因为外键不在当前模型类中,所有可能会有多个数据,即使是一对一的关系表,也要加many=true】
4、加上read_only=True ,不参与到反序列化中。如果该序列化器不参与反序列就无须写。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/449563.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人人可用的开源数据可视化分析工具-DataEase

DataEase 介绍 DataEase是一种开源的关系型数据库管理系统,旨在帮助用户创建和管理各种类型的数据。它是一种易于使用的工具,适用于各种规模的企业和组织,从个人使用到大型公司使用。 Github 地址:GitHub - dataease/dataease: …

2023年4月份上新的Transformer模型设计系列论文(附下载链接)

来源:投稿 作者:王老师 编辑:学姐 论文1 论文标题: Slide-Transformer: Hierarchical Vision Transformer with Local Self-Attention** 滑动Transformer:具有局部自注意的分层视觉Transformer 论文链接:h…

ChatGPT 克隆方案,开源了!开箱即用

什么是 ChatGPT ChatGPT是一种基于人工智能技术的大型语言模型,它能够理解和处理人类自然语言,并且在回答问题、生成文本和模拟对话等方面表现出色。ChatGPT使用的是GPT-3.5架构,它在训练过程中接触了大量的语言数据,并利用这些数…

机器学习算法系列(四)-- 决策树

机器学习算法之–决策树 最经典的机器学习模型之一,成树型结构,决策树的目的是为了产生一颗泛化能力强,处理未见实例能力强的树,通过特征判断不断分类,基本流程遵循“分而治之”的递归分类策略。 一、算法原理 1.1、特…

《C++程序设计原理与实践》笔记 第17章 向量和自由空间

本章和后面四章介绍C标准库的容器和算法部分(通常称为STL)。本章和后面两张的重点是最常用、最有用的STL容器——向量的设计和实现。 17.1 引言 C标准库中最有用的容器是vector。vector提供了给定类型的元素序列。标准库vector是一个方便、灵活、&…

Redis从零上手

文章目录 NoSQL概述互联网发展史单机MySQL的年代(90年代)缓存时代: Memcached MySQL 垂直拆分(读写分离)分库分表 水平拆分(MySQL集群)如今最近的年代 为什么要用NoSQL什么是NoSQLNoSQL特点阿里巴巴演进分析阿里巴巴中文站架构发展历程简单分析 NoSQL…

MySQL架构设计其实很简单

一、概述 我们很多互联网项目首选的数据库就是MySql5.7,因为免费,支持数据库主从复制,读写分离,且语法简单,容易上手,虽然对sql的函数、触发器、存储过程有一定的了解,也能说出一些优化sql语句…

基于SpringBoot+Vue的前后端分离的博客管理系统

菜单 首页写文章内容管理 博客管理相册管理归档登录、注册(项目整合了shiro+jwt+redis,用户未登录不能发布博客、内容管理、相册、归档等功能) 文章​​​​​​​末尾赋前后端代码以及数据库文件链接!!! 1 首页 首页包括菜单、博客、登录用户、推荐博客排行、博客分类…

Autosar-Interface接口

文章目录 一、Autosar接口1、AUTOSAR Interface2、Standardized Interface3、Standardized AUTOSAR Interface二、AUTOSAR接口的通用规则三、示例-存储四、总结一、Autosar接口 在Autosar里规定了三类接口,分别是AUTOSAR接口,标准AUTOSAR接口和标准接口。 下图将所有的接口…

【Linux】I/O复用

概述 I/O复用使得程序能同时监听多个文件描述符,看文件上是否有用户感兴趣的事件发生,提高程序性能。 使用I/O复用技术的情况: 客户端同时处理多个套接字 客户端同时处理用户输入和网络连接 同时监听多个端口 同时处理TCP和UDP请求 TCP服务器…

【JavaEE】文件操作(InputStream、OutputStream)

博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE初阶 在Java中总会用到文件操作,比如从盘符读写文件,按字节和字符进行数据读写,那么你真的认识什么是文件路径吗?平时谈到的“文件”,…

mybatis实现CRUD详解(使用mapper映射文件实现增删改查)

mybatis实现CRUD详解(使用mapper映射文件实现增删改查) 创建maven项目&#xff1a;项目结构如图所示 准备数据库表&#xff1a; 准备pom.xml所需的依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.…

快速弄懂RPC

快速弄懂RPC 常见的远程通信方式远程调用RPC协议RPC的运用场景和优势 常见的远程通信方式 基于REST架构的HTTP协议以及基于RPC协议的RPC框架。 远程调用 是指跨进程的功能调用。 跨进程可以理解为一个计算机节点的多个进程或者多个计算机节点的多个进程。 RPC协议 远程过…

C++string类

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解了C中的string类以及类内的一些常用函数 Cstring类 文章…

k8s_3节点集群部署

背景 近期想在自己电脑上部署一套3节点K8s 作为自己平时的学习测试环境。 本来想看一下有没有比较便捷的部署方式如&#xff1a; rancherdesktop: https://docs.rancherdesktop.io/zh/next/getting-started/installation/ sealos: https://www.sealos.io/docs/getting-started…

【超算/先进计算学习】日报3

目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记作业管理系统 slurm作业管理系统及常用用户命令节点状态查询/作业提交命令作业队列查询/作业取消命令任务练习 调试器 GDB实时调试core 文件调试 对自己的表现是否满意简述下次计划其他反馈 今日已完成任务列表 4-…

Spring的体系结构

Spring的体系结构 一、Spring简介1. Spring介绍1.1 为什么要学1.2 学什么1.3 怎么学 2. 初识Spring2.1 Spring家族2.2 Spring发展史 3. Spring体系结构3.1 Spring Framework系统架构图3.2 Spring Framework课程学习路线 4. Spring核心概念4.1 目前我们代码存在的问题4.2 核心概…

『Linux从入门到精通』第 ⑫ 期 -深入了解冯诺依曼体系结构与操作系统(Operator System)

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f337;计算机之父——冯诺依曼&#x1f337;冯诺依曼体系结构&#x1f33a;木桶效应 &#x1f337;操作系统(Operator System)&#x1f33a;如何理解操作系统&#x1f33a;系统调用和库函数概念 &#x1f490;专栏导…

论文结构商讨

论文查重 pass软件 提出问题 1、由于选取的算法太多了&#xff0c;不知道是简单介绍&#xff0c;还是深入介绍 希望找到一个具体的模板 2、数据库要是用一个就在前面介绍&#xff0c;用不一样的就在每章里面分别介绍 4、数据集介绍放在那个具体位置&#xff1f; 如果可以画出…

蓝精灵事件来袭: 深受喜爱的蓝色角色来 Web3 啦!

起源于漫画并成为国际知名的卡通和电影明星的蓝色x小家伙正在进入 NFT 舞台。 作者&#xff1a;Coindesk——Toby Bochan 因漫画、卡通片和电影而闻名的热门动画系列“蓝精灵”正在展开新的冒险&#xff0c;由蓝精灵协会推出一系列新的非同质化通证&#xff08;NFT&#xff09;…