Django一分钟:DRF模型序列化器处理关联关系的示例与注意事项
DRF的ModelSerializer序列化器与Django的Model模型紧密映射,本文将通过简单的示例介绍几种处理关联关系的方法。
1. 创建模型和初始数据
创建模型
from django.db import modelsclass Product(models.Model):product_name = models.CharField(max_length=255)quantity = models.IntegerField()class Component(models.Model):product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='components')component_name = models.CharField(max_length=255)code = models.CharField(max_length=255)quantity = models.IntegerField()class Meta:ordering = ['product']def __str__(self):return f'{self.code}-{self.component_name}'
创建数据
>>> from api.models import Product, Component
>>> p1 = Product.objects.create(product_name="盖子", quantity=30)
>>> Component.objects.create(product=p1, component_name='纤维板', code='XYB', quantity=5)
>>> Component.objects.create(product=p1, component_name='螺丝', code='LS', quantity=10)
>>> Component.objects.create(product=p1, component_name='密封条', code='MFT', quantity=20)
2. 字符串关系字段
使用StringRelatedField
from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components = serializers.StringRelatedField(many=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']
执行查询和序列化
>>> from api.models import Product
>>> p1 = Product.objects.prefetch_related('components').get(pk=1)
>>> from api.serializers import ProductSerializer
>>> ps = ProductSerializer(p1)
>>> ps.data
# {'product_name': '盖子', 'quantity': 30, 'components': ['XYB-纤维板', 'LS-螺丝', 'MFT-密封条']}
效果如下:
{'product_name': '盖子', 'quantity': 30, 'components': ['XYB-纤维板', 'LS-螺丝', 'MFT-密封条']
}
注意观察获取查询集的代码:Product.objects.prefetch_related('components').get(pk=1)不难发现我们使用了prefetch_related来获取查询集,如果一次查询大量的Product,不使用prefetch_related将会导致严重的性能问题(N+1问题)。DRF的序列化器不会为你自动优化。当然我们的示例中影响不大,因为只获取了一个查询集。
3. 主键关系字段
使用PrimaryKeyRelatedField
from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components = serializers.PrimaryKeyRelatedField(many=True, read_only=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']
效果如下:
{'product_name': '盖子', 'quantity': 30, 'components': [1, 2, 3]
}
4. 指定关系字段
使用SlugRelatedField可以指定字段来表示关联关系:
from rest_framework import serializers
from .models import Productclass ProductSerializer(serializers.ModelSerializer):components = serializers.SlugRelatedField(many=True,read_only=True,slug_field='code')class Meta:model = Productfields = ['product_name', 'quantity', 'components']
效果如下:
{'product_name': '盖子', 'quantity': 30, 'components': ['XYB', 'LS', 'MFT']
}
5. 嵌套序列化器
from rest_framework import serializers
from .models import Product, Componentclass ComponentSerializer(serializers.ModelSerializer):class Meta:model = Componentfields = ['component_name', 'code', 'quantity']class ProductSerializer(serializers.ModelSerializer):components = ComponentSerializer(many=True, read_only=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']
效果如下:
{"product_name": "盖子","quantity": 30,"components": [{"component_name": "纤维板","code": "XYB","quantity": 5},{"component_name": "螺丝","code": "LS","quantity": 10},{"component_name": "密封条","code": "MFT","quantity": 20}]
}
6. 可写嵌套
默认上面创建的嵌套序列化器是只读的,可写嵌套需要实现update、create两者或其一:
from rest_framework import serializers
from .models import Product, Componentclass ComponentSerializer(serializers.ModelSerializer):class Meta:model = Componentfields = ['component_name', 'code', 'quantity']class ProductSerializer(serializers.ModelSerializer):components = ComponentSerializer(many=True)class Meta:model = Productfields = ['product_name', 'quantity', 'components']def create(self, validated_data):components_data = validated_data.pop('components')product = Product.objects.create(**validated_data)for component_data in components_data:Component.objects.create(product=product, **component_data)return product
可以使用此序列化器创建实例:
>>> data = {"product_name": "电机","quantity": 1,"components": [{"component_name": "铝型材","code": "LXC","quantity": 5},{"component_name": "螺栓","code": "LSHUN","quantity": 10},]
}
>>> from api.serializers import ProductSerializer
>>> s = ProductSerializer(data=data)
>>> s.is_valid()
# True
>>> s.save()
# <Product: Product object (2)>
7. 总结注意事项
- 关联关系注意使用
prefetch_related获取查询集。 - 可写嵌套序列化器必须自己实现
create方法update方法两者或其一。
相关文章:
Django一分钟:DRF模型序列化器处理关联关系的示例与注意事项
DRF的ModelSerializer序列化器与Django的Model模型紧密映射,本文将通过简单的示例介绍几种处理关联关系的方法。 1. 创建模型和初始数据 创建模型 from django.db import modelsclass Product(models.Model):product_name models.CharField(max_length255)quant…...
Python爬虫selenium框架基本使用
一、安装导入 使用包管理器安装 pip3 install selenium 二、WebDriver工具 要使用这个工具我们需要保证安装了一个浏览器的驱动器。 Python的WebDriver是一个用于自动化Web浏览器操作的工具,它属于Selenium的一部分,特别是Selenium 2.0及以后版本中…...
sql 时间交集
任务(取时间交集) 前端输入开始时间和结束时间,通过sql筛选出活动开始时间和活动结束时间再开时时间和结束时间有交集的活动 想法: 前后一段时间内遇到了类似取交集的,从网上找到了两种写法,再结合GPT等…...
【深度学习】05-Rnn循环神经网络-01- 自然语言处理概述/词嵌入层/循环网络/文本生成案例精讲
循环神经网络(RNN)主要用于自然语言处理的。 循环神经网络(RNN)、卷积神经网络(CNN)和全连接神经网络(FCN)是三种常见的神经网络类型,各自擅长处理不同类型的数据。下面…...
基于JAVA+SpringBoot+Vue的电商平台的设计与实现
基于JAVASpringBootVue的电商平台的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接🍅…...
CSS盒模型-怪异盒模型笔记-思维导图-案例等
文章目录 一、盒模型(重点)二、怪异盒模型三、块级元素和行内元素区别汇总四、块级元素和行内元素的转换(显示方式)||元素的显示和隐藏五、思维导图六、笔记资料 一、盒模型(重点) 所有HTML元素可以看作盒子。 CSS盒模型本质上是…...
thinkphp6开发的通用网站系统源码
thinkphp6开发的通用网站系统源码。 基于ThinkPHP6框架开发的通用后台权限管理系统,底层采用国内最流行的ThinkPHP6框架, 支持内容管理、文章管理、用户管理、权限管理、角色管理等功能。 代码下载百度网盘...
Junit 5 - 理解Mockito,提高UT 覆盖率
前言 当我是1个3年初级程序员时, 我被面试者问到1个问题: 如何保证你的开发任务交付质量 当我是1个7年开发组长时, 我被面试者问到另1个问题:如何保证你的团队的代码质量, 减少rework。 又若干年后, 我才…...
微服务sentinel解析部署使用全流程
sentinel源码地址: 介绍 alibaba/Sentinel Wiki GitHub sentinel官方文档: https://sentinelguard.io/zh-cn/docs/introduction.html Sprong Cloud alibaba Sentinel文档【小例子】 : Sentinel alibaba/spring-cloud-alibaba Wiki GitHub 目录 1、…...
YOLO11震撼发布!
非常高兴地向大家介绍 Ultralytics YOLO系列的新模型: YOLO11! YOLO11 在以往 YOLO 模型基础上带来了一系列强大的功能和优化,使其速度更快、更准确、用途更广泛。主要改进包括 增强了特征提取功能,从而可以更精确地捕捉细节以更…...
机器学习框架(含实例说明)
机器学习框架是用于开发和部署机器学习模型的软件库和工具集。它们提供了一系列的算法、工具和基础设施,帮助开发者更高效地构建、训练和部署机器学习模型。以下是一些主要的机器学习框架及其详细介绍: 1. TensorFlow TensorFlow 是由Google开发的开源…...
vue2与vue3知识点
1.vue2(optionsAPI)选项式API 2.vue3(composition API)响应式API vue3 setup 中this是未定义(undefined)vue3中已经开始弱化this vue2通过this可以拿到vue3setup定义得值和方法 setup语法糖 ref > …...
从源码中学习动态代理模式
动态代理模式 动态代理是 Java 反射(Reflection)API 提供的一种强大机制,它允许在运行时创建对象的代理实例,而不需要在编译时静态地创建。 Java 提供了两种主要的方式来实现动态代理: 基于接口的动态代理:…...
谷歌浏览器完美清除缓存
1.在页面上按下键盘的F12,打开控制台。 2.鼠标放到刷新图标上,点击鼠标右键,选择‘清空缓存并硬性重新加载’。 这样浏览器对网站页面的缓存就彻底被清理干净了。 目前支持该操作方式的浏览器有谷歌和Edge浏览器。 有的浏览器不支持该方式操…...
《如何高效学习》
有道云笔记 第一部分 整体性学习策略 结构 结构就像思想中的一座城市,有很多建筑物,建筑物之间有道路相连,有高大而重要的与其他建筑有上百条路相连,无关紧要的建筑只有少数泥泞的小道与外界相通。 建立良好的知识结构就是绘制…...
阿里云ACP认证考试题库
最近有好些同学,考完阿里云ACP了,再来跟我反馈:自己花700买的阿里云ACP题库,结果答案是错的! 或者考完后发现,买的阿里云ACP题库覆盖率只有50%! 为避免大家继续踩坑,给大家分享一个阿…...
学习经验分享【38】YOLOv11解读——最新YOLO版本
YOLO算法更新速度很快,已经出到V11版本,后续大家有想发论文或者搞项目可更新自己的baseline了。后续将改进YOLOv11算法,有需要的朋友可关注,我会持续进行更新。 YOLO11是Ultralytics YOLO系列实时目标检测器的最新迭代版本&#x…...
电商选品/分析| 亚马逊常见插件爬虫实战之-helium插件
说明 插件爬虫相当于二次爬虫,二次加工信息,因为大部分插件信息也是从正规网上去获取数据,这次列举helium插件爬虫案例,其他插件爬虫也是类似这个方式. 需求 1、⽤⾕歌浏览器,下载chrome extension:“Helium 10 2、登录helium10 3、打开 打开Amazo…...
遇到慢SQL、SQL报错,应如何快速定位问题 | OceanBase优化实践
在数据库的使用中,大家时常会遇到慢SQL,或执行出错的SQL。对于某些SQL问题,其错误原因显而易见,但也有不少情况难以直观判断。面对这类问题,我们应当如何应对?如何准确识别SQL错误的根源?是否需…...
postgresql僵尸进程的处理思路
简介 僵尸进程(zombie process)是指一个已经终止但仍然在进程表中保留条目的进程。正常情况下,当一个进程完成执行并退出时,操作系统会通过父进程调用的wait()或waitpid()系统调用来收集该子进程的退出状态。如果父进程未及时调用…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
