广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Django ORM 多表查询示例代码
  • 443
分享到

Django ORM 多表查询示例代码

2024-04-02 19:04:59 443人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录数据准备正向查询与反向查询基于对象的跨表查询正向查询一对多多对多一对一反向查询 一对多多对多一对一正向查询反向查询基于双下线的跨表查询正向查询一对一一对多多对多反向查询一对一一对

数据准备

moduls.py

# 构建表结构
from Django.db import models
 
# 表app01_publish
class Publish(models.Model):
    name = models.CharField(max_length=20)
    addr = models.CharField(max_length=20)
 
# 表app01_author_detail
class Author_Detail(models.Model):
    tel = models.CharField(max_length=20)
 
# 表app01_author
class Author(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
 
    # 表app01_author一对一表app01_authordetail
    detail = models.OneToOneField(to='Author_Detail',to_field='id',unique=True,on_delete=models.CASCADE)
 
# 表app01_book
class Book(models.Model):
    title = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    pub_date = models.DateField(auto_now_add=True)
 
    # 表app01_book多对一表app01_publish,参数to指定模型名,参数to_field指定要关联的那个字段
    publish = models.ForeignKey(to='Publish',to_field='id',on_delete=models.CASCADE)
 
    # 我们自己写sql时,针对书籍表与作者表的多对关系,需要自己创建新表,而基于djanGoORM,下面这一行代码可以帮我们自动创建那张关系表
    authors=models.ManyToManyField(to='Author')
    # 变量名为authors,则新表名为app01_book_authors,若变量名为xxx,则新表名为app01_book_xxx
 

tests.py

# 添加数据
 
import os
 
if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "book_sys.settings")
    import django
    django.setup()
 
    from app01.models import *
    # 1、先添加没有外键字段的 author_detail表 pubulish表
    Author_Detail.objects.create(tel='123456789')
    Author_Detail.objects.create(tel='987654321')
    Author_Detail.objects.create(tel='000000000')
 
    Publish.objects.create(name='北方出版社',addr='北京')
    Publish.objects.create(name='南方出版社',addr='南京')
    Publish.objects.create(name='东方出版社',addr='上海')
    Publish.objects.create(name='西方出版社',addr='西安')
 
    # 2、添加 author表 book表
    Author.objects.create(name='frank',age=31 ,detail_id=1)
    Author.objects.create(name='lili',age=29 ,detail_id=2)
    Author.objects.create(name='tank',age=42 ,detail_id=3)
 
    Book.objects.create(title='三国演义',price=200 ,publish_id=1)
    Book.objects.create(title='三国志',price=198.5 ,publish_id=2)
    Book.objects.create(title='红楼梦',price=255.43 ,publish_id=2)
    Book.objects.create(title='西游记',price=300.5 ,publish_id=3)
    Book.objects.create(title='西厢记',price=213.4 ,publish_id=4)
    Book.objects.create(title='水浒传',price=199 ,publish_id=1)
 
    # 3、最后操作 author_book表,由于使用的是 ManyToMany 字段自动生成的,所以要基于外键所在的表进行操作
    book_obj1=Book.objects.filter(pk=1).first()
    book_obj1.authors.add(1,2)
 
    book_obj2 = Book.objects.filter(pk=2).first()
    book_obj2.authors.add(1)
 
    book_obj3 = Book.objects.filter(pk=3).first()
    author_obj1 = Author.objects.filter(pk=1).first()
    author_obj2 = Author.objects.filter(pk=2).first()
    book_obj3.authors.add(author_obj1,author_obj2)
 
    book_obj4 = Book.objects.filter(pk=4).first()
    book_obj4.authors.add(3,2)
 
    book_obj5 = Book.objects.filter(pk=5).first()
    book_obj5.authors.add(3)
 
    book_obj6 = Book.objects.filter(pk=6).first()
    book_obj6.authors.add(1,3)

正向查询与反向查询

一出版社和书籍为例, 书记表含有出版社表的外键字段

正向查询>>> 书籍查询出版社

反向查询>>> 出版社查询书籍

总结: 当前查询对象是否含有外键字段, 有就是正向查询, 没有就是反向查询

正向查询按照字段查询, 反向查询按照表名查询

基于对象的跨表查询

相当于Mysql中的子查询: 将一张表的查询结果用括号括起来, 当作另一条SQL语句的条件 . 

正向查询

一对多

查询书籍主键为5 的出版社名称

1. 查主键为5的书籍对象

2. 根据书籍对象的外键字段 publish 获取到出版社对象

3. 由出版社对象获取到名称

book_obj = Book.objects.filter(pk=5).first()
res = book_obj.publish
print(res)
# Publish object
print(res.name)
# 西方出版社

多对多

查询书籍主键为3的作者姓名

1. 查询书籍主键为3的书籍对象

2. 外键字段在书籍表中, 同样是正向查询,那么只需要按照字段autjors查询即可

3. 获取作者对象的姓名

book_obj = Book.objects.filter(pk=3).first()
res = book_obj.authors
print(res)
# app01.Author.None

注意: 由于字段authors 是多对多的外键字段, 此时拿到的对象还需要进一步的操作

book_obj = Book.objects.filter(pk=3).first()
res = book_obj.authors
 
res1 = book_obj.authors.all()
print(res1)
# <QuerySet [<Author: Author object>, <Author: Author object>]>

然后再for循环各自的姓名即可

一对一

查询作者lili的号码

1.查询作者对象

2,外键字段再作者表中, 同样是正向查询,那么只需要按照字典detail查询即可

3. 获取详情对象的tel

author_obj = Author.objects.filter(name='lili').first()
res = author_obj.detail
print(res)
print(res.tel)

反向查询 一对多

查询东方出版社出版的书籍

1. 先获取东方出版社的对象

2. 出版社没有外键字段, 去查书籍是反向查询

3. 表名小写_set.all()

4. 获取书籍名称

publish_obj=Publish.objects.filter(name='东方出版社').first()
print(publish_obj)
# Publish object
 
res = publish_obj.book_set
print(res)
# app01.Book.None
 
res1 = res.all()
print(res1)
# <QuerySet [<Book: Book object>]>
for obj in res1:
  print(obj.title)

多对多

查询作者lili写过的书籍

1.获取作者对象

2. 作者表中没有书籍表的外键, 所以是反向查询

3. .book_set.all()获取书籍对象

4. 再获取书籍对象的名称

author_obj = Author.objects.filter(name='lili').first()
res = author_obj.book_set
print(res)
# app01.Book.None
res1 = res.all()
print(res1)
# <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
for obj in res1:
  print(obj.title, end='')
# 三国演义,红楼梦,西游记,

一对一

查询号码为0000000的作者

1. 查询作者对象详情

2.外键字段在作者表中, 同样是证词昂查询, 那么只需要按照字段detail 查询即可

3. 获取详情对象的tel 

detail_obj = Author_Detail.objects.filter(tel='000000000').first()
print(detail_obj)
# Author_Detail object
res = detail_obj.author
print(res)
# Author object
print(res.name)
# tank

方法总结

正向查询

一对一, 一对多的方法是一样的, 按照字段查询就能够直接找到对象 --- author_obj.detail

一对多 , 按照字段查询后会返回一个.None的对象, 需要在字段后面加上.all()>>> book_obj.authors.all()

反向查询

一对多,多对多的方法是一样的, 按照表名小写, 在跟上_set.all()>>>author_obj.book_set.all()

一对一, 则直接按照表明小写, 能够直接拿到>> > detail_obj.author

当查询到的结果中最后以.None结尾, 都需要在原来的查询方法后面在跟上.all()才能获得想要的结果

基于双下线的跨表查询

相当于MySQL中的连表查询: 将两张表或者对账表连成一张表进行查询

正向查询

正向查询, 按照关联字段+双下线>>> .values('关联字段__被关联表中的字段'), 返回的是一个QuerySet对象

一对一

查询作者frank的手机号

res = Author.objects.filter(name='frank').values('detail__tel')
print(res)
# <QuerySet [{'detail__tel': '123456789'}]>
 
print(res.first())
# {'detail__tel': '123456789'}

一对多

查询三国演义的出版社名字

res = Book.objects.filter(title='三国演义').values('publish__name')
print(res)
print(res.first())
 
# <QuerySet [{'publish__name': '北方出版社'}]>
# {'publish__name': '北方出版社'}

多对多

查询三国演义的所有作者

res = Book.objects.filter(title='三国演义').values('authors__name')
print(res)
# <QuerySet [{'authors__name': 'frank'}, {'authors__name': 'lili'}]>

反向查询

按模型名(小写)+双下线>>> .values('表名小写__被关联表中的字段'), 返回的是一个QuerySet对象. 

一对一

查询手机号为'123456789'的作者名

res = Author_Detail.objects.filter(tel='123456789').values('author__name')
print(res)
# <QuerySet [{'author__name': 'frank'}]>

一对多

查询北方出版社出版的所有书籍名字

res = Publish.objects.filter(name='北方出版社').values('book__title')
print(res)
# <QuerySet [{'book__title': '三国演义'}, {'book__title': '水浒传'}]>

多对多

查询lili出版的所有书籍

res = Author.objects.filter(name='lili').values('book__title')
print(res)
# <QuerySet [{'book__title': '三国演义'}, {'book__title': '红楼梦'}, {'book__title': '西游记'}]>

方法总结:

正向查询,按关联字段: .values('关联字段__被关联表中的字段'), 返回的是一个QuerySet对象

按模型名(小写)+双下线: .values('表名小写__被关联表中的字段'), 返回的是一个QuerySet对象, 对象中保存的是字典类型的数据

双下高阶正反向查询

使用filter()的双下线查询

首先需要考虑的是正向查询还是反向查询, 确定括号内使用的方法, 但是括号外面不是使用values,而是使用filter!!!

注意: 使用filter方法字段是不能加引号的, values需要加引号

查询书籍主键为反向, 使用.filter('表名小写__被关联表中的字段')

res = Publish.objects.filter(book__pk= 4)
print(res)
 
# <QuerySet [<Publish: Publish object>]>
res = Publish.objects.filter(book__title= '西游记')
print(res)
# 结果相同

连续跨多张表查询

套路与上面的案例都是一样的, 可以练习n个双下划线, 只需要在每次双下线的时候, 确定是每个双下线后面是正向查询还是反向查询即可

# 需求1:查询北京出版社出版过的所有书籍的名字以及作者的姓名、手机号
# 方式一:基表为Publish
res=Publish.objects.filter(name='北方出版社').values_list('book__title','book__authors__name','book__authors__author_detail__tel')
 
# 方式二:基表为Book
res=Book.objects.filter(publish__name='北方出版社').values_list('title','authors__name','authors__author_detail__tel')
 
# 循环打印结果均为
for obj in res:
    print(obj)
 
 
 
# 需求2:查询手机号以186开头的作者出版过的所有书籍名称以及出版社名称
# 方式一:基表为AuthorDetail
res=AuthorDetail.objects.filter(tel__startswith='186').values_list('author__book__title','author__book__publish__name')
 
# 方式二:基表为Book
res=Book.objects.filter(authors__author_detail__tel__startswith='186').values_list('title','publish__name')
 
# 方式三:基表为Publish
res=Publish.objects.filter(book__authors__author_detail__tel__startswith='186').values_list('book__title','name')
 
# 循环打印结果均为
for obj in res:
    print(obj)
 

到此这篇关于Django ORM 多表查询的文章就介绍到这了,更多相关Django ORM 多表查询内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Django ORM 多表查询示例代码

本文链接: https://www.lsjlt.com/news/120259.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Django ORM 多表查询示例代码
    目录数据准备正向查询与反向查询基于对象的跨表查询正向查询一对多多对多一对一反向查询 一对多多对多一对一正向查询反向查询基于双下线的跨表查询正向查询一对一一对多多对多反向查询一对一一对...
    99+
    2022-11-11
  • oracle多表简单查询实例代码
    目录多表查询基本语法oracle多表查询总结多表查询基本语法 笛卡尔积在SQL中的实现方式既是交叉连接(Cross Join)。所有连接方式都会先生成临时笛卡尔积表,笛卡尔积是关系代...
    99+
    2022-11-13
  • Layui实现多条件查询的示例代码
    最近做一个档案系统,发现字段超多 带分页的多条件查询(分页需要后端分页,传page给后端才可实现,前端无法直接实现) 当我们点击搜索按钮时会筛选出输入值的相关数据,多条件查询是建立在...
    99+
    2022-11-12
  • Django中ORM表的创建和增删改查方法示例
    前言 Django作为重量级的Python web框架,在做项目时肯定少不了与数据库打交道,编程人员对数据库的语法简单的还行,但过多的数据库语句不是编程人员的重点对象。因此用ORM来操作数据库相当快捷。今天...
    99+
    2022-06-04
    示例 方法 Django
  • Mysql多层子查询示例代码(收藏夹案例)
    用户表 create table if not exists tb_book ( book_id char(10) not null comment 'book主键...
    99+
    2022-11-13
  • sqlserver多表联合查询和多表分页查询的代码讲解
    这篇文章主要为大家详细介绍了sqlserver多表联合查询和多表分页查询的方法,图文详解容易学习,配合代码阅读理解效果更佳,非常适合初学者入门,感兴趣的小伙伴们可以参考一下。多表联查:select...
    99+
    2022-10-18
  • MyBatis 和 jeesite多表查询示例详解
    有时候经常碰到多级联查,比如通过某个功能A表查角色信息,但是A表和角色表没有直接的关联关系,需要通过用户表进行关联,所以就需要多级关联查询出来了(下面的只是举例,实际应用用户和角色不...
    99+
    2022-11-13
  • django admin实现动态多选框表单的示例代码
    背景 借助django-admin,可以快速得到CRUD界面,但若需要创建多选标签字段时,需要对表单进行调整 示例 model.py 一个tag(标签类),一个boo...
    99+
    2022-11-12
  • springboot 使用mybatis查询的示例代码
    目录示例1示例2返回数据源代码示例1 项目结构 代码controller中 UserController.java package com.example.demo1110.con...
    99+
    2022-11-13
  • java使用es查询的示例代码
    众所周知,elasticsearch简称es,它是基于基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放...
    99+
    2023-05-30
  • MybatisPlus实现分页查询和动态SQL查询的示例代码
    目录一、描述二、实现方式三、 总结一、描述 实现下图中的功能,分析一下该功能,既有分页查询又有根据计划状态、开始时间、公司名称进行动态查询。 二、实现方式 Controller层...
    99+
    2022-11-12
  • MySQL实现查询分位值的示例代码
    目录背景业务背景思考效果参考背景 分位值的概念 分位值:分位值(Quartile)是一种用于描述数据分布的统计概念,在统计学和数据分析中经常被用到。一般情况下,分位值分成四个等份,分别为第一分位数(Q1)、第二分位数(Q...
    99+
    2023-04-24
    MySQL 查询分位值 MySQL 分位值
  • 常用的MongoDB查询语句的示例代码
    目录背景方法查询示例示例一示例二示例三示例四尾言背景 最近做了几个规则逻辑。用到mongo查询比较多,就是查询交易信息跑既定规则筛选出交易商户,使用聚合管道进行统计和取出简单处理后的...
    99+
    2022-11-12
  • spring中mybatis多表查询处理的示例分析
    这篇文章将为大家详细讲解有关spring中mybatis多表查询处理的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。package com.swhy.bw.advisor.center....
    99+
    2023-06-02
  • LyScript实现指令查询功能的示例代码
    目录搜索内存中的机器码搜索内存反汇编代码通过对LyScript自动化插件进行二次封装,实现从内存中读入目标进程解码后的机器码,并通过Python代码在这些机器码中寻找特定的十六进制字...
    99+
    2022-11-11
  • ES结合java代码聚合查询详细示例
    思路不清晰的小伙伴可以先在es中把聚合代码写出来 { "aggs": { "brandAgg": { "terms": { "field"...
    99+
    2023-05-19
    java es聚合查询 es聚合算法 java查询es数据
  • Mybatis一对多查询列表属性处理示例详解
    目录一、说明1.<collection>标签属性说明2. 示例代码二、平铺查询三、 嵌套查询(Nested Select for Collection)3.1 ...
    99+
    2023-05-20
    mybatis 一对多查询 mybatis 1对多查询 mybatis 查询列表属性
  • Mysql查询时间区间日期列表实例代码
    目录1、查询时间区间日期列表,不会由于数据表数据影响2、创建视图可以公共使用3、创建为视图之后,可以通过视图查询时间区间列表日期4、查询时间区间按月附:在对mysql的时间进行区间查...
    99+
    2022-11-13
  • MySQL数据库中多表查询之内连接,外连接,子查询的示例分析
    小编给大家分享一下MySQL数据库中多表查询之内连接,外连接,子查询的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!多表...
    99+
    2022-10-18
  • Oracle查看表结构的几种方法示例代码
    1,DESCRIBE 命令 使用方法如下: SQL> describe nchar_tst(nchar_tst为表名) ...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作