Django多表查询(ORM)

1、建立表结构

三个表:book、Author、publisher。
书籍和作者是多对多的关系,一本书可以有多个作者,一个作者可以有多本书。
出版社和书籍是一对多的关系,一个出版社可以出版多本书(多方,多方定义外键),一本书只能由某一个出版社出版(现实情况可能不同,只是我们这里这样规定。)

from django.db import models# Create your models here.
class Book(models.Model):title = models.CharField(max_length=100, verbose_name='书名')authors = models.ManyToManyField('Author', verbose_name='作者')publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE, verbose_name='出版社')class Meta:verbose_name = '图书'verbose_name_plural = '图书'def __str__(self):return self.titleclass Author(models.Model):name = models.CharField(max_length=50, verbose_name='作者名')date_of_birth = models.DateField(verbose_name='出生日期', blank=True, null=True)class Meta:verbose_name = '作者'verbose_name_plural = '作者'def __str__(self):return self.nameclass Publisher(models.Model):name = models.CharField(max_length=100, verbose_name='出版社名')address = models.CharField(max_length=255, verbose_name='地址', blank=True, null=True)website = models.URLField(verbose_name='网站', blank=True, null=True)class Meta:verbose_name = '出版社'verbose_name_plural = '出版社'def __str__(self):return self.name

2、一对多(ForeignKey)

数据添加

一对多添加数据需要先添加“一”端,否则多端没有外键引用无法添加,所以需要先有出版社信息
我们这里手工添加一个:

Publisher.objects.create(name="中信出版社", address="河北省廊坊市", website="www.publisher.com")

添加书籍信息,所属”中信出版社“

# 先查询取得出版社的对象
publisher = Publisher.objects.get(id=1)
book = Book.objects.create(title="射雕英雄传",  publisher=publisher)
数据查询

查询数据有两个方向,根据多方查询一方称为“正向”,根据一方取得多方数据称为“反向”

正向:有了书籍(多方)数据,查询出版社数据(一方)

方式:直接用“.”关联数据

book = Book.objects.filter(title="射雕英雄传").first()
print(book) # 射雕英雄传
print(book.publisher) # 中信出版社
print(book.publisher.address) # 河北省廊坊市
反向:有了出版社,查询书籍

方式:小写类名_set.all(),book_set.all()

publisher = Publisher.objects.filter(name="中信出版社").first()
# 方式一:用两步,通过一个变量引用所有书籍
books = publisher.book_set.all()
for book in books:print(book)# 方式二,不要中间变量,直接输出
print(publisher.book_set.all()[0]) # 输出 queryset的第一个对象

3、多对多

在后台,多对多关系在Django里,实际上是将两个多方的表名作为字段名,新增了一个表,来维护多对多关系。

数据添加

多对多的情况下,虽然两个都是“多方”,是对称的。但是在models中构建的时候,是把一个对象名称+s,作为另一个对象的ManyToManyField字段

class Book(models.Model):authors = models.ManyToManyField('Author', verbose_name='作者')

这样在编程的时候就不是对称的,所以添加的时候两方添加方式是有区别的。

book.authors.add(author1, author2) # book 里面有authors字段,所以这样添加
author.book_set.add(book1, book2) # author里面没有books字段
正向,从定义对方字段的那一方开始
# 方式一,传单独的对象
rong = Author.objects.filter(name="黄蓉").first() # 这里必须用.first(),否则返回的是queryset,而不是对象
jing = Author.objects.filter(name="郭靖").first()
bird = Book.objects.filter(title="射雕英雄传").first()
bird.authors.add(rong, jing) # 将rong、jing两个Author对象关联到book# 方式二,传queryset
from django.db.models import Q
authors = Author.objects.filter(Q(name="黄蓉") | Q(name="郭靖"))
bird = Book.objects.filter(title="射雕英雄传").first()
bird.authors.add(*authors) # 注意前面要用*
# 或者传id列表,假设1、3为两个作者的id
bird.authors.add(*[1, 3]) # 注意前面要用*

删除所有关联关系,不会删除对象

bird.authors.clear()
反向,没有定义另一方字段的一方
bird = Book.objects.get(title="射雕英雄传")
rong = Author.objects.filter(name="黄蓉").first()
rong.book_set.add(bird) # 也可以添加多本书,如果有的话

创建新对象,并加入关联对象集

publisher = Publisher.objects.filter(name="中信出版社").first()
author = Author.objects.filter(name="黄蓉").first()
book = author.book_set.create(title="神雕侠侣", publisher=publisher) # 这里创建的是book类,也可以返回创建的对象

删除对象关联

author.book_set.remove(bird) # 删除其中一个对象的关联
author.book_set.clear() # 删除所有关联关系,不会删除对象
数据查询

多对多的数据查询根据“谁定义了以对方表名为名字的字段”也有正向、反向。方法同一对多。

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

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

相关文章

C# 集合表达式和展开运算符 (..) 详解

集合表达式 (Collection Expressions)基本语法支持的集合类型展开运算符 (..)基本用法实际应用示例创建新集合合并集合与现有API结合性能考虑高级用法多维集合自定义集合注意事项与传统方式的比较总结集合表达式 (Collection Expressions) C# 12 引入了集合表达式,…

数学视频动画引擎Python库 -- Manim Voiceover 安装 Installation

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。 Manim Voiceover 是一个为 Manim 打造的专注于语音旁白的插件: 直接在 Python 中添加语音旁白: 无需使用视频编辑器&…

Git安装避坑指南:新手村通关秘籍

Git安装避坑指南:新手村通关秘籍 刚学编程那会儿,Git安装差点让我砸键盘。满心欢喜打开官网下载,结果卡在配置上,命令行死活不认识git命令。看着教程里别人行云流水的操作,自己对着报错信息干瞪眼——这感觉&#xff…

如何修改Siteground max_execution_time值?

这个值在Siteground 上是修改不了的。 以下是来自Siteground 官网的解释: 由于服务器上全局定义的 PHP 限制,某些 PHP 设置无法更改。最常见的无法更改的 PHP 设置包括: memory_limit max_execution_time max_input_time post_max_size up…

【libm】 11 fmin函数 (fmin.rs)

一、源码 这段代码实现了一个符合 IEEE 754-2008 标准的 minNum 函数(在 Rust 中命名为 fmin),该功能在 IEEE 754-2019 标准中已被 minimumNumber 取代。 /* SPDX-License-Identifier: MIT OR Apache-2.0 */ //! IEEE 754-2008 minNum. Thi…

React 英语单词消消乐一款专为英语学习设计的互动式记忆游戏

📖 项目简介 英语单词消消乐 是一款专为英语学习设计的互动式记忆游戏。通过经典的消消乐玩法,让用户在轻松愉快的游戏中掌握英语单词,提高词汇量和记忆效果。 🎯 项目目标 让英语学习变得有趣且高效通过游戏化方式增强单词记忆…

Qt:QPushButton、QRadioButton、QCheckBox

目录 一、QPushButton 1.认识QPushButton 2.设置按钮图标 3.设置按钮的快捷键 二、QRadioButton 常用的信号 按钮的分组 三、QCheckBox 一、QPushButton 1.认识QPushButton QPushButton继承自QWidget,所以在上一篇文章中介绍的QWidget的属性,理…

docker 无法拉取镜像解决方法

目录 我在omv中通过后台页面拉取alist镜像总是失败,原因千奇百怪 今天再战终于解决首先,到dockerhub找镜像和wiki进入docker账号设置 找到里面提示了登录操作和密码命令行中执行后会提示成功之后按需配置代理,同时检查自己的配置检查 Docker …

安卓10.0系统修改定制化_____安卓9与安卓10系统文件差异 有关定制选项修改差异

在修改安卓10的rom之前。我们需要对rom有简单的了解。区分安卓10与安卓9之间的差异。了解不同安卓版本之间系统文件的变化以及权限的区别。对于修改一些定制化选项有很大的辅助作用. 通过博文了解💝💝💝 1💝💝💝-----安卓10与安卓9之间文件实例对比 了解差异 …

HTML表单元素全面指南:从基础到实践

引言 HTML表单是网页开发中不可或缺的一部分,它为用户提供了与网站交互的途径。无论是简单的登录页面还是复杂的数据提交界面,表单元素都扮演着关键角色。本文将详细介绍各种HTML表单元素及其使用方法。 输入框(input元素) input元素是最基础也是最灵…

深度学习的核心理论与技术

理解深度学习的基本原理、核心算法和关键技术 深度学习的核心理论与技术前言一、深度学习核心理论1. 神经网络基础核心内容练习资源2. 反向传播与梯度下降核心内容练习资源3. 卷积神经网络(CNN)核心内容练习资源4. 循环神经网络(RNN&#xff…

LinkedList 链表数据结构实现 (OPENPPP2)

🔍 LinkedList 链表数据结构实现 (OPENPPP2) 🧱 1. 数据结构设计 LinkedListNode 结构 #mermaid-svg-XDJqt6cHMKxodJLG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XDJqt6cHMKxodJLG .er…

RPC/gRPC入门学习

一、RPC 1.1 RPC概念 RPC Remote Procedure Call, 即远程过程调用,是一种用于构建分布式系统的理念,在一些资料中被称为“请求-响应”协议。两个进程可以位于同一系统中,也可以位于不同的系统中,通过网络相互连接。 RPC使程…

租车小程序电动车租赁小程序php方案

电动车租赁小程序源码,开发语言后端php,前端uniapp。四个端:用户端门店端分销商端小程序,pc管理后台。一 用户端:可以扫门店码,进入门店详情页。也可以通过地图找车。或者门店列表进入,或者快速…

Python数据分析基础04:预测性数据分析

相关章节: 《Python数据分析基础03:探索性数据分析》 《python数据分析基础02:数据可视化分析》 《Python数据分析基础01:描述性统计分析》 预测性数据分析(Predictive Analytics) 的深度解析&#xff0…

PFAE(Pyramidal Frequency Attention Extraction)通过频域注意力机制提高边界模糊、遮挡等场景的的检测能力

在伪装物体检测中,现有方法多依赖空间局部特征,难以捕捉全局信息,而 Transformer 类方法计算成本高昂。频率域特征因具备全局建模能力,可有效抑制背景噪声、提升伪装物体语义清晰度,但频域与空域的频繁转换会增加计算复…

AE插件安装方法

Adobe After Effects简称AE,是adobe公司开发的一个视频剪辑及设计软件,AE软件能够实现对素材的非线性编辑而完成画面的组接,同时还能对任何一部分进行修改,达到想要的结果。AE含有很多脚本、常用的表达式和插件,做动画…

舵轮时钟-STM32-28路PWM--ESP8266-NTP时间

1.STM32--PWM生成STM32不具备如此多的PWM,因此采用软件定时器的方案实现:使用hal库实现;main.c#include "main.h"#define close1 500#define open 1500#define close 2500// 定时器中断配置(以TIM2为例) voi…

Redis的单线程和多线程(单Worker线程)

Redis的单线程和多线程 Redis6.0之前是单线程的,6.0之后是多线程的,我们先了解6.0版本之前的单线程Redis。但其实无论6.0之前还是6.0之后,redis用于工作的线程也只有一个,所以也可以说redis一直是单线程的。 Redis单线程 Redis 6.…

OSPFv3基础

文章目录 OSPFv3基础OSPFv3的改进OSPFv2 v3相同OSPFv2 v3不同 🏡作者主页:点击! 🤖Datacom专栏:点击! ⏰️创作时间:2025年07月07日22点31分 OSPFv3基础 OSPFv3协议号依然为89,在I…