django中的跨表查询梳理

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.总结

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

原文地址:https://www.cnblogs.com/oden/p/10771059.html

时间: 2024-08-06 19:28:48

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

Django 跨表查询--神奇的双下划线和点

我在django的moles中创建了两个calss,如下: class Project(models.Model):     name = models.CharField(u'项目名称',max_length=32,blank=True)     id = models.CharField(u'项目ID',max_length=32,unique=True,primary_key=True,blank=True)     create_date = models.DateTimeField(u

Django之跨表查询及添加记录

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

Django学习【第7篇】:Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)

django之跨表查询及添加记录 一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many). 创建一对一的关系:OneToOne("要绑定关系的表名") 创建一对多的关系:ForeignKey("要绑定关系的表名") 创建多对多的关系:ManyToMany(&qu

Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)

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

Django Mysql数据库-基于双下划线的跨表查询

一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的 model 为止.(相当于用sql语句用join连接的方式,可以在settings里面设置,可查看sql语句) 数据库模型: class Book(models.Model): nid = models.AutoField(primary_key=Tru

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

1.一对多跨表查询获取数据的三种形式:对象.字典.元组 例:有host与business两张表,host与business的id字段关联,business在host表中的对象名是b,  通过查询host表获取的querySet中的b来查询business表. 以下两种方式都是操作host表: a.以对象的形式跨表查询,查询business表的数据:row.b.caption,row.b.id b.以字典和元组的形式跨表查询,查询business表的数据,跨表查询的时候要用双下划线  'b__id

Django 【补充】ORM跨表查询补充

models.Book.objects.filter(**kwargs): querySet [obj1,obj2]models.Book.objects.filter(**kwargs).values(*args) : querySet [{},{},{}]models.Book.objects.filter(**kwargs).values_list(title) : querySet [(),(),()] 跨表查询总结: 1.创建表 class Book(models.Model): ti

django模型系统(三)--多对多,一对一以及跨表查询

-Many-to-Many*** 指定了中间表,add,remove,set 都不能用,必须用中间表 两端都可以自动获得另一端的自动API访问.跟一对多的反向访问类似.但是使用的是本字段的字段名 In [112]: Course.objects.create(name='python全栈') Out[112]: <Course: python全栈> In [113]: Course.objects.create(name='python全套') Out[113]: <Course: py

Django之跨表查询——正反向查询(ForeignKey)

1.正向查询和反向查询: 外键的查询操作: 正向查询: # 正向查询 # 基于对象,跨表查询 book_obj = models.Book.objects.all().first() ret = book_obj.publisher # 和我这本书关联的出版社对象 print(ret,type(ret)) ret = book_obj.publisher.name # 和我这本书关联的出版社对象的name属性 print(ret,type(ret)) # 查询id=1的书出版社名称 # 涉及到跨