Py006-01-17基于对象的跨表查询

核心知识(重点)

跨表查询

  • 基于对象查询
  • 基于双下滑线查询
  • 聚合和分组查询
  • F 和 Q 查询

orm模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from django.db import models

# 作者表
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
age=models.IntegerField()
# 一对一 OneToOneField相当于指定 外间关联时设置 unique
'''
ad_id int unique,
foreign key(ad_id) references authorDetail(nid)
'''
authordetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)

# 作者详情表
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64)

# 出版社表
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
email=models.EmailField()

'''
Book ---- Publish 一对多
'''
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2)



# 一对多关系 一本书对应多个出版社
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE,)
'''
publish_id int,
foreign key(publish_id) references publish(nid)

'''

#多对多
authors =models.ManyToManyField(to="Author")

'''
# 书籍作者关系表
create table book_authors(
nid int primary key auto_increment,
book_id int,
author_id int,
foreign key(book_id) references book(nid),
foreign key(author_id) references author(nid)
);
'''

# 多对多关系时 不需要这个模型类 django会依据 authors =models.ManyToManyField(to="Author")帮我们生成这张表
# class Book2Author(models.Model):
#
# nid = models.AutoField(primary_key=True)
# book=models.ForeignKey(to="Book")
# author=models.ForeignKey(to="Author")

生成表如下:





基于对象跨表查询(子查询)

1
2
3
4
5
6
7
A-B
关联属性在A表中

正向查询: A------>B
反向查询: B------>A

基于对象的跨表查询(子查询)

一对多查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
正向查询:按字段
反向查询:表名小写_set.all()


book_obj.publish
Book(关联属性:publish)对象 --------------> Publish对象
<--------------
publish_obj.book_set.all() # queryset

# 一对多查询:正向查询 ==》查询金瓶梅这本书的出版社的名字
book_obj = Book.objects.filter(title='金瓶梅').first()
book_obj.publish # 与这本书关联的出版社对象
book_obj.publish.name


# 一对多查询:反向查询 ==》查询人民出版社出版的书籍名称
publish_obj = Publish.objects.filter(name='人民出版社').first()
publish_obj.book_set.all() # queryset 与出版社关联的书籍集合

多对多查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
正向查询:按字段
反向查询:表名小写_set.all()

book_obj.authors.all()
Book(关联属性:authors)对象 ------------------------> Author对象
<------------------------
author_obj.book_set.all() # queryset

# 多对多查询:正向查询 ==》查询金瓶梅这本书的所有作者的名字
book_obj = Book.objects.filter(title='金瓶梅').first()
author_list = book_obj.authors.all() # queryset 对象 [au1,au2,....]
for author in author_list:
print(author.name)

# 多对多查询:反向查询 ==》查询alex作者出版的所有书籍名称
author_obj = Author.objects.filter(name='alex').first()
book_list = author_obj.book_set.all() # queryset 与作者关联的书籍集合
for book in book_list:
print(book.name)

一对一查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
正向查询:按字段
反向查询:表名小写(不带_set了因为一对一了)

author.authordetail
Author(关联属性:authordetail)对象 ------------------------>AuthorDetail对象
<------------------------
authordetail.author

# 一对一查询:正向查询 ==》查询作者alex的手机号
alex = Author.objects.filter(title='alex').first()
alex.authordetail.telephone

# 多对多查询:反向查询 ==》查询手机号为110的作者姓名和年龄
ad = AuthorDetail.objects.filter(telephone=110).first()
ad.author.name
ad.author.age