一、创建模型
书籍(Book)和书籍详细(BookDetail)是一对一关系
出版社(Publish)和书籍(Book)是一对多的关系
作者(Author)和书籍(Book)是多对多的关系
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)
bookDetail=models.OneToOneField(to="BookDetail",on_delete=models.CASCADE)
'''
OneToOneField相当于:
publish=models.ForeignKey(to="Publish",on_delete=models.CASCADE,unique=True)
'''
authors=models.ManyToManyField(to='Author')
'''
自动创建一张名为:应用名称_表名_字段的表,比如我应用为app01,上面这句代码生成的表名为app01_book_authors
存储Book表的id主键字段和Author表的id主键字段之间的关系
'''
- 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
注意事项:
-
多对多,创建的表的名称:
应用名称_表名_字段
,是根据模型中的元数据自动生成的,也可以覆写为别的名称
-
一个表的主键id字段可以自动添加
,也可以自己指定,一般都不自己指定!
-
对于
外键字段
,Django 会在
字段名后添加"_id" 来创建数据库中的列名
,比如上面的publish、bookDetail,实际数据库存储的字段名publish_id、bookDetail_id
给大家看下
ManyToManyField生成的表
:
二、添加表记录
1、一对多
方式1:
publish_obj=Publish.objects.get(nid=1)
book_obj=Book.objects.
create(title="金瓶眉",publishDate="2012-12-12",price=100,publish=publish_obj)
方式2(推荐):
book_obj=Book.objects.create(title="金瓶眉",publishDate="2012-12-12",price=100,publish_id=1)
核心:book_obj.publish与book_obj.publish_id是什么?
答:
1. 书和出版社是多对一的关系,一个书对象book_obj,应该通过外键对应Publish表的一个出版社。
2. book_obj.publish(就是publish=models.ForeignKey()这里的publish)
它代表的是该书对象相对应的一个publish出版社对象
我们可以用book_obj.publish.name这种方法,获取出版社名等其他出版社信息
3. book_obj.publish_id就是取到了书对象的publish_id外键字段值
2、多对多
book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1)
1. 方式一:拿到作者对象再add
yuan=Author.objects.filter(name="yuan").first()
egon=Author.objects.filter(name="alex").first()
book_obj.authors.add(yuan,egon)
2. 方式二(推荐):拿到作者表的主键id字段的值再add(如下图)
book_obj.authors.add(1)
最后一条记录就是了
authors=models.ManyToManyField()中的
authors并不是真正的字段
,只是一个
操作系统自建关系表的一个接口!
三、修改、删除表记录
1、删除表记录
不论是一对一、多对一还是多对多,删除表记录都是
Book.objects.filter(过滤条件).delete()
,一对一、多对一有
on_delete保证级联删除
。多对多,只要删除了一个book对象,那么
这个对象相应关系表中的相应记录也会被级联删除
!
2、修改表记录
一对一,多对一不用说,直接
Book.objects.update(name=name, price=price, pub_date=pub_date, publish_id=publisher_id)
把外键字段重新赋值就行了,
注意外键赋值的是主键id字段的值!
多对多有点特别,多对多你要先把字段重新赋值更新了,如:
Book.objects.update(name=name, price=price, pub_date=pub_date, publish_id=publisher_id)
,再修改关系表记录!
修改关系表记录方法:
1. 方法一
book_obj.authors.clear()
book_obj.authors.add()
2. 方法二(推荐,用的多)
book_obj.authors.set()
3. 方法三
book_obj.authors.remove(
)
四、跨表查询
基于对象的跨表查询和基于双下划线的跨表查询并没有谁好谁撇
,但是基于双下划线的跨表查询肯定更加简单简洁!不同情况有不同的使用,
联表是会占内存资源的
!
1、基于对象的跨表查询
注意:基于
一、创建模型
来看下面!
对象的跨表查询是基于子查询的!
(1)一对多查询(例如:Publish 与 Book)
book_obj=Book.objects.filter(pk=1).first()
print(book_obj.publish.city)
publish_obj=Publish.objects.get(name="苹果出版社")
book_list=publish.book_set.all()
(2)一对一查询(例如:Book 与 BookDetail)
book_obj=Book.objects.filter(title="金瓶眉").first()
print(book_obj.bookDetail.pagenum)
bookDetail_list=BookDetail.objects.filter(writed_addr="beijing")
for obj in bookDetail_list:
print(obj.book.title)
一对多查询:一个出版社一般会查到多本书,'因此加个_set表示得到的是一个集合!'
(3)多对多查询 (Book 与 Author)
book_obj=Book.objects.filter(title="金瓶眉").first()
authors_list=book_obj.authors.all()
for author_obj in authors_list:
print(author_obj.name)
author_obj=Author.objects.get(name="egon")
book_list=author_obj.book_set.all()
for book_obj in book_list:
print(
book_obj.title)
'多对多嘛,同样可能查到多个,因此需要加_set'
2、基于双下划线的跨表查询
双下划线的跨表查询是
基于join拼表实现的
!比如左连接(LEFT JOIN)、内连接(INNER JOIN)等
要点:正向查询按字段,反向查询按表名小写
上面这句话是对怎么告诉ORM引擎join哪张表的高度概括,无论是下面三种那种都脱离不了这句话!
(1)一对多查询
queryResult=Book.objects
.filter(publish__name="苹果出版社")
.values_list("title","price")
queryResult=Publish.objects
.filter(name="苹果出版社")
.values_list("book__title","book__price")
(2)多对多查询
queryResult=Book.objects
.filter(authors__name="yuan")
.values_list("title")
queryResult=Author.objects
.filter(name="yuan")
.values_list("book__title","book__price")
(3)一对一查询
ret=Book.objects.filter(name="天龙八部").values("bookDetail__pagenum")
ret=BookDetail.objects.filter(book__name="天龙八部").values("pagenum")
(4)进阶练习(连续跨表)
queryResult=Book.objects
.filter(publish__name="人民出版社")
.values_list("title","authors__name")
queryResult=Publish.objects
.filter(name="人民出版社")
.values_list("book__title","book__authors__age","book__authors__name")
queryResult=Book.objects
.filter(authors__authorDetail__telephone__regex="151")
.values_list("title","publish__name")
ret=Author.objects
.filter(authordetail__telephone__startswith="151")
.values("book__title","book__publish__name")
- 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