古之立大事者,不惟有超世之才,亦必有坚忍不拔之志。

django ORM 高阶操作–跨表查询

Python admin 413℃ 0评论

一. 创建表

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

一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

创建一对一的关系:OneToOne(“要绑定关系的表名”)

创建一对多的关系:ForeignKey(“要绑定关系的表名”)

创建多对多的关系:ManyToMany(“要绑定关系的表名”)  会自动创建第三张表

注意:临时添加的字段,首先你得考虑之前的数据有没有。设置一个默认值。 wordNum  = models.IntegerField(default=0)    

通过logging可以查看翻译成的sql语句

注意事项:

  1. 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称;;
  2. id 字段是自动添加的;
  3. 对于外键字段,Django 会在字段名上添加”_id” 来创建数据库中的列名
  4. 这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句;
  5. 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称;
  6. 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None ;

字段选项

每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

一旦你建立好数据模型之后,django会自动生成一套数据库抽象的API,可以让你执行关于表记录的增删改查的操作。

二. 添加记录

一对多添加记录:

多对多添加记录:

书和作者是多对多的关系:一个书可以有多个作者,一个作者可以出版多本书,步骤如下:

  • 先找到书对象
  • 再找到需要的作者对象
  • 给书对象绑定作者对象(用add方法),也就是绑定多对多的关系

解除绑定:remove:# 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])

清除绑定:clear”#清空被关联对象集合。

总结:remove和clear的区别
  remove:得吧你要清除的数据筛选出来,然后移除
  clear:不用查,直接就把数据都清空了。
  各有应用场景

三. 基于对象的查询记录(相当于sql语句的where子查询)

一对一查询记录

author和authordetile是一对一的关系

正向查询(按字段author)

反向查询(按表名authordeital):因为是一对一的关系了,就不用_set了。

一对多查询记录:

正向查询(按字段:publish):

反向查询(按表名:book_set):

多对多查询记录:

正向查询(按字段authorlist)

反向查询(按表名book_set)

你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Article model 中做一下更改: publish = ForeignKey(Blog, related_name=’bookList’),那么接下来就会如我们看到这般:

四. 基于双下划线的跨表查询

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

一对多查询:

练习1、查询人民出版社出版过的所有的书的价格和名字

练习2、查询linux这本书的出版社的地址:filer先过滤,,values显示要求的字段

多对多查询:

练习1、查询egon出过的所有书的名字

练习2、查询手机号以151开头的作者出版过的所有书的名称以及出版社的名称

五. 聚合查询与分组查询(很重要!!!)

聚合查询

aggregate(*args, **kwargs),只对一个组进行聚合

aggregate()是QuerySet 的一个终止子句(也就是返回的不再是一个QuerySet集合的时候),意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

分组查询

annotate():为QuerySet中每一个对象都生成一个独立的汇总值。是对分组完之后的结果进行的聚合

1、统计每一本书的作者个数

2、统计每一个出版社最便宜的书

3、统计每一本以py开头的书籍的作者个数:

(4)统计不止一个作者的图书:

(5)根据一本图书作者数量的多少对查询集QuerySet进行排序:

(6)查询各个作者出的书的总价格:

六. F查询和Q查询

在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?

F查询

Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

1、查看评论数大于阅读数的书

2、修改操作也可以使用F函数,比如将id大于1的所有的书的价格涨价100元

3、Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。

Q查询

filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。

1、查询id大于1并且评论数大于100的书

2、查询评论数大于100或者阅读数小于200的书

3、查询年份等于2017年或者价格大于200的书

4、查询年份不是2017年或者价格大于200的书

注意:查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将”AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

转载请注明:北凉柿子 » django ORM 高阶操作–跨表查询

喜欢 (0)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址