1、建立表python
表说明:共有以下4张表,书籍表、出版社表、做者表、做者详细信息表,出版社表和书籍表的关系为一对多(外键写在多的书籍表中),即一个出版社能够有多本书;书籍和做者是多对多关系(多对多表须要另一个关系表,外键写在任何一个表中均可以),即一本书能够有多本书,一本书也能够有多个做者;做者和做者详细信息表时一对一关系(外键写在任何一个表中均可以),即一个做者只能一个对应的做者详细信息,反之亦然。具体建表以下:git
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("Publish") #与Publish表创建多对一关系,会自动在此表中增长publish_id字段 authors=models.ManyToManyField("Author") #与Author表创建多对多关系,会自动建立一个book_authors对应关系表,包含id、book_id和authors_id字段 class Publish(models.Model): nid=models.AutoField(primary_key=True) name=models.CharField(max_length=32) email=models.EmailField() class Author(models.Model): nid=models.AutoField(primary_key=True) name=models.CharField(max_length=32) age=models.IntegerField() class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) adrr=models.CharField(max_length=32) email=models.EmailField()
author = models.OneToOneField("Author") #与Author表创建一对一关系
2、数据添加code
一、一对多对象
具体添加实例以下:blog
#方式1: pub_obj = Publish.objects.get(name="沙河出版社") #获取要添加的出版社models对象 Book.objects.create(title="金品梅",publishDate="2001-12-12",price=122,publish=pub_obj) #方式2: book_obj=Book.objects.create(title="金品梅3",publishDate="2011-08-12",price=112,publish_id=1) #publish_id对应的值必须为已知publish表中已经存在的id
二、多对多ci
具体添加实例以下:rem
实例1:边建立book表信息,边绑定与做者信息的关系get
book_obj = Book.objects.create(title="金品梅3", publishDate="2011-08-12", price=112, publish_id=1) alex=Author.objects.get(name="alex") #获取已知的做者models对象 egon=Author.objects.get(name="egon") #获取已知的做者models对象 book_obj.authors.add(alex,egon) #绑定关系
实例2:书籍信息已经建立,过后绑定与做者的关系(即追加做者信息):it
book_obj=Book.objects.filter(title="金品梅3").first() #查找书的models对象 wenzhou=Author.objects.get(name="文州") book_obj.authors.add(wenzhou)
实例3:将查询到的多个queryset对象添加:class
book_obj = Book.objects.create(title="金品梅5", publishDate="2011-08-12", price=112, publish_id=1) authors=Author.objects.all() #queryset对象,列表形式 book_obj.authors.add(*authors) #*authors将列表形式的对象打散成位置参数形式
3、数据删除
此处主要讲述多对多表的移除和清空操做,执行此操做后,关系表中的对应的关系也会跟着被移除或清空。
一、删除一个做者
alex=Author.objects.get(name="alex") book_obj = Book.objects.filter(title="金品梅3").first() book_obj.authors.remove(alex)
二、清空全部做者
book_obj = Book.objects.filter(title="金品梅3").first() book_obj.authors.clear()
4、基于对象跨表查询(子查询)
一、一对多
对于一对多的状况,建立表的时候咱们已经阐述,外键只能写在多的书籍表中,查询一本书的出版社称为正向查询,查询一个出版社所出版的全部书籍称为反向查询,具体查询规则和实例以下:
查询规则:
.publish (Book-------(查出版社)---------->Publish) <-------(查出版的书籍)--------- .book_set.all()
实例一(正向查询):
#查询python这本书的出版社的名字:(正向查询,按字段) book_obj=Book.objects.get(title="python") print(book_obj.publish.name)
实例二(反向查询):
#查询沙河出版社出版过的书籍名称:(反向查询按:表名_set) pub_obj=Publish.objects.get(name="沙河出版社") print(pub_obj.book_set.all()) #queryset对象 for book in pub_obj.book_set.all(): print(book.title)
二、多对多
对于多对多关系,在建立表的时候已经说明关联字段放在任何一个表类中都是能够的,本文放在Book表中,若查询一本书的全部做者称为正向查询,查询一个做者写的全部数据则称为反向查询,具体查询规则及实例以下:
查询规则:
.authors.all() (Book------------(查全部相关的做者)--------------->Author) <--------(查做者写过全部相关的书籍)------------ .book_set.all()
实例一(正向查询):
#查询书籍名为红楼梦的全部做者姓名
book_obj=Book.objects.get(title="红楼梦") print(book_obj.authors.all()) #为全部关联的做者queryset对象 for author in book_obj.authors.all(): print(author.name)
实例二(反向查询):
#查询alex做者所写过的全部书籍名称 author_obj=Author.objects.get(name="alex") print(author_obj.book_set.all()) #为全部关联的书籍queryset对象 for book in author_obj.book_set.all(): print(book.title)
三、一对一
对于一对一的关系,咱们在建表的时候一样也说过,关联字段放在任何一个表类中均可以,本章以将关联字段author放在AuthorDetail表为例,经过做者详细信息表查询做者为正向查询,经过字段便可;经过做者表查询相应做者信息内容为反向查询,用表名便可。具体应用实例以下:
实例一(正向查询):
#查询的地址在沙河而且email是123的做者的名字 (正向查询,按字段) detail_obj=AuthorDetail.objects.get(adrr="沙河",email="123") print(detail_obj.author.name)
实例二(反向查询):
#查询姓名为alex的做者的地址addr (反向查询,按表名) author_obj=Author.objects.get(name="alex") print(author_obj.authordetail.adrr)
实例三(综合实例):
#查询住在沙河的做者出版过的全部书籍的名称以及出版社名称 authordetail=AuthorDetail.objects.get(addr="沙河") author=authordetail.author #正向查询,获得author models对象 bookList=author.book_set.all() #反向查询,获得bookList queryset对象 for book in bookList: print(book.title,book.publish.name)
总结:在上述的论述中,全部的反向的查询的表名均为小写,且须要提醒的是在一对一的反向查询中表名不须要跟set,由于它只有一个对象,经过“.表名”获得的是一个models对象,能够直接查询须要的字段。