1.前言

	最近在写一个小项目,里面主要涉及的就是表与表之间复杂的关系。当真正开发起来的时候,才发现自己对复杂的表关系间的查询有点混乱,趁着这几天的时间,重新梳理了一下。

2.概念

在开始之前,先明确几个基础概念:

正向查询:关联字段所在的表查询其关联表叫正向查询

反向查询:未写关联字段的表查询其关联表叫反向查询
# 书籍表
class Book(models.Model):
name = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish')
def __str__(self):
return self.t_name # 出版社表
class Publish(models.Model):
name = models.CharField(max_length=32)
def __str__(self):
return self.t_name # 根据书籍表,查询其出版社,叫正向查询 # 根据出版社,查询书籍,叫反向查询

3.一对多

  • 正向查询(按字段)
book_obj=Book.objects.filter(pk=1).first() 		# 拿到书籍为1对对象

publish_name = book_obj.publish.name			# 根据字段查询
  • 反向查询(按表名)
# 查询a出版社出版的书籍

book_list = Publish.book_set.all()		# queryset对象

4.多对多

  • 正向查询(按字段)
author_list = Book.objects.filter(pk=1).first().author.all()

# 多对多的关系,一本书查出来的作者可能是多个,所以一定是一个queryset对象
  • 反向查询(按表名)
Author.objects.filter(pk=1).first().book_set.all()

# 多对多的关系,一作者查出来的书可能是多本,所以一定是一个queryset对象
注意:在ForeignKey()和ManyToManyField()可以设置related_name的值来赋值FOO_set
class Book(model.Model):
publish = ForeignKey(Book, related_name='bookList') # 查询
Publish.objects.filter(pk=1).first().bookList.all()

5.基于双下划线的查询

	django还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止,同样的,正向查询按字段,反向查询按表名小写。
  • 一对多
# 查询a出版社出版的书的名字(name)和数量(num)		正向查询,按字段

Book.objects.filter(publish__name='a出版社').values_list('naem','num')

# 查询a出版社出版的书的名字(name)和数量(num)		反向查询,按字段

Publish.objects.filter(name='a出版社').
values_lsit('book__name','book_num') # 其实本质是一样的,就是sql语句的select from的表不同而已
  • 多对多
# 查询a作者的书的名字(name)和数量(num)		正向查询,按字段

Book.objects.filter(author__name='a').values_list('naem','num')

# 查询a出版社出版的书的名字(name)和数量(num)		反向查询,按字段

Author.objects.filter(name='a').
values_lsit('book__name','book_num')

6.分组查询

	annotate()为调用QuerySet中每一个对象都生成一个独立的统计值,本质就是将关联的表用sql语句中的join成一张表,再按单表查询的方法进行操作。

7.django中的F查询和Q查询

	在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。而现实的需求中往往会有两个字段的值做比较这样的需求,django给我们提供了这两种查询方法。
  • F()
# 查询评论数大于收藏数的书籍
from django.db.models import F Book.objects.filter(commnetNum__lt=F('keepNum')) # 将每本书的价格提高30
Book.objects.all().update(price=F("price")+30) 
  • Q()
bookList=Book.objects.filter(Q(author__name="a")|Q(author__name="b"))

8.总结

	数据的操作,往往是项目中的关键一步,理清楚数据间的关系和查询方法,更有助于程序的开发。

django中的跨表查询梳理的更多相关文章

  1. Django中的跨表查询,多表查询。

    一:Django中的ORM进行操作. 必须掌握的十三条: <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 & ...

  2. django中orm多表查询,减少数据库查询操作

    .select_related()   的使用

  3. django之 使用views.py里面的函数对表进行增删改查 内容(models.py中表的创建、views.py中函数的使用,基于对象的跨表查询)

    models之对于表的创建有以下几种: 一对一:ForeignKey("Author",unique=True),  OneToOneField("Author" ...

  4. django(3) 一对多跨表查询、ajax、多对多

    1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询hos ...

  5. django models的点查询/跨表查询/双下划线查询

    django models 在日常的编程中,我们需要建立数据库模型 而往往会用到表与表之间的关系,这就比单表取数据要复杂一些 在多表之间发生关系的情形下,我们如何利用models提供的API的特性获得 ...

  6. django之跨表查询及添加记录

    一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出 ...

  7. python 全栈开发,Day73(django多表添加,基于对象的跨表查询)

    昨日内容回顾 多表方案: 如何确定表关系呢? 表关系是在2张表之间建立的,没有超过2个表的情况. 那么相互之间有2条关系线,先来判断一对多的关系. 如果其中一张表的记录能够对应另外一张表的多条记录,那 ...

  8. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  9. Django框架----跨表查询及添加记录

    一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出 ...

随机推荐

  1. pta总结3

    7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块 ...

  2. Vuejs自定义select2指令

    在做select2插件的时候遇到一些坑,最终解决如下: Vue.directive('select2', { inserted: function (el, binding, vnode) { var ...

  3. 【Idea】idea code style配置eclipse code formatter

    在eclipse中有自动配置code style的功能 ,但是idea上却没有,这个时候需要自己手工配置 1. 在idea中找到Preference->Plugins->Browse re ...

  4. Servlet校验密码之Mariadb篇

    Servlet校验密码之Mariadb篇 先放图-- 数据库: 效果图: 整体来说与上一篇差距不大,这次主要是采用数据库来进行校验,我使用的是Mariadb,安装与配置不用我说 主要有一点,导入连接器 ...

  5. java做图片点击文字验证码

    https://blog.csdn.net/qq_27721169/article/details/82769093

  6. 单个 js 文件禁用 ESLint 语法校验

    在代码顶部添加一行注释 /* eslint-disable */ ESLint 在校验的时候就会跳过后面的代码 还可以在注释后加入详细规则,这样就能避开指定的校验规则了 /* eslint-disab ...

  7. IDEA快捷键积累

    对于用习惯了eclipse快捷键或刚转用idea的用户,可以把idea的大部分快捷键设置成eclipse风格的. 设置方式:左上角 file--->setings--->keymap,如下 ...

  8. C++输出

    setiosflags 意思就是设置输入输出的标志iso::fixed 是操作符setiosflags 的参数之一,该参数指定的动作是以带小数点的形式表示浮点数,并且在允许的精度范围内尽可能的把数字移 ...

  9. C++ 用变量定义数组

    较早的编译器是不同意这样做的,所以一些书籍比方以Tc解说的书本都说数组的下标不能是变量.在vc6.0下亦是如此. 只是在一些较新的编译器如dev c++已经支持了,例如以下代码不会报错 #includ ...

  10. c# Exchange 收件箱获取。

    public List<Email> GetInbox() { try { List<Email> lstEmails = new List<Email>(); F ...