django ORM模型:创建表、数据添加、删除、跨表查询(子查询)

2022-10-0309:48:12后端程序开发Comments810 views字数 3887阅读模式

一、创建表

表说明:共有如下4张表,书籍表、出版社表、作者表、作者详细信息表,出版社表和书籍表的关系为一对多(外键写在多的书籍表中),即一个出版社可以有多本书;书籍和作者是多对多关系(多对多表需要另外一个关系表,外键写在任何一个表中都可以),即一本书可以有多本书,一本书也可以有多个作者;作者和作者详细信息表时一对一关系(外键写在任何一个表中都可以),即一个作者只能一个对应的作者详细信息,反之亦然。具体建表如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

classBook(models.Model):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

nid=models.AutoField(primary_key=True)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

title=models.CharField(max_length=32)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

publishDate=models.DateField()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

price=models.DecimalField(max_digits=5,decimal_places=2)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

publish=models.ForeignKey("Publish") #与Publish表建立多对一关系,会自动在此表中增加publish_id字段文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

authors=models.ManyToManyField("Author") #与Author表建立多对多关系,会自动创建一个book_authors对应关系表,包含id、book_id和authors_id字段文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

classPublish(models.Model):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

nid=models.AutoField(primary_key=True)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

name=models.CharField(max_length=32)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

email=models.EmailField()classAuthor(models.Model):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

nid=models.AutoField(primary_key=True)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

name=models.CharField(max_length=32)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

age=models.IntegerField()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

classAuthorDetail(models.Model):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

nid= models.AutoField(primary_key=True)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

adrr=models.CharField(max_length=32)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

email=models.EmailField()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

author = models.OneToOneField("Author") #与Author表建立一对一关系文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

二、数据添加

1、一对多文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

具体添加实例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#方式1:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

pub_obj = Publish.objects.get(name="沙河出版社") #获取要添加的出版社models对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

Book.objects.create(title="金品梅",publishDate="2001-12-12",price=122,publish=pub_obj)#方式2:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj=Book.objects.create(title="金品梅3",publishDate="2011-08-12",price=112,publish_id=1) #publish_id对应的值必须为已知publish表中已经存在的id文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

2、多对多文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

具体添加实例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例1:边创建book表信息,边绑定与作者信息的关系文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj = Book.objects.create(title="金品梅3", publishDate="2011-08-12", price=112, publish_id=1)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

alex=Author.objects.get(name="alex") #获取已知的作者models对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

egon=Author.objects.get(name="egon") #获取已知的作者models对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj.authors.add(alex,egon)#绑定关系文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例2:书籍信息已经创建,事后绑定与作者的关系(即追加作者信息):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj=Book.objects.filter(title="金品梅3").first() #查找书的models对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

wenzhou=Author.objects.get(name="文州")文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj.authors.add(wenzhou)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例3:将查询到的多个queryset对象添加:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj = Book.objects.create(title="金品梅5", publishDate="2011-08-12", price=112, publish_id=1)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

authors=Author.objects.all() #queryset对象,列表形式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj.authors.add(*authors) #*authors将列表形式的对象打散成位置参数形式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

三、数据删除

此处主要讲述多对多表的移除和清空操作,执行此操作后,关系表中的对应的关系也会跟着被移除或清空。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

1、删除一个作者文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

alex=Author.objects.get(name="alex")文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj= Book.objects.filter(title="金品梅3").first()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj.authors.remove(alex)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

2、清空所有作者文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj = Book.objects.filter(title="金品梅3").first()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj.authors.clear()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

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

1、一对多文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

对于一对多的情况,创建表的时候我们已经阐述,外键只能写在多的书籍表中,查询一本书的出版社称为正向查询,查询一个出版社所出版的所有书籍称为反向查询,具体查询规则和实例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

查询规则:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

.publish文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

(Book-------(查出版社)---------->Publish)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例一(正向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询python这本书的出版社的名字:(正向查询,按字段)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj=Book.objects.get(title="python")print(book_obj.publish.name)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例二(反向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询沙河出版社出版过的书籍名称:(反向查询按:表名_set)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

pub_obj=Publish.objects.get(name="沙河出版社")print(pub_obj.book_set.all()) #queryset对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

for book inpub_obj.book_set.all():print(book.title)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

2、多对多文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

对于多对多关系,在创建表的时候已经说明关联字段放在任何一个表类中都是可以的,本文放在Book表中,若查询一本书的所有作者称为正向查询,查询一个作者写的所有数据则称为反向查询,具体查询规则及实例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

查询规则:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

.authors.all()(Book------------(查所有相关的作者)--------------->Author)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例一(正向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询书籍名为红楼梦的所有作者姓名文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

book_obj=Book.objects.get(title="红楼梦")文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

print(book_obj.authors.all()) #为所有关联的作者queryset对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

for author inbook_obj.authors.all():print(author.name)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例二(反向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询alex作者所写过的所有书籍名称文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

author_obj=Author.objects.get(name="alex")print(author_obj.book_set.all()) #为所有关联的书籍queryset对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

for book inauthor_obj.book_set.all():print(book.title)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

3、一对一文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

对于一对一的关系,我们在建表的时候同样也说过,关联字段放在任何一个表类中都可以,本章以将关联字段author放在AuthorDetail表为例,通过作者详细信息表查询作者为正向查询,通过字段即可;通过作者表查询相应作者信息内容为反向查询,用表名即可。具体应用实例如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例一(正向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询的地址在沙河并且email是123的作者的名字 (正向查询,按字段)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

detail_obj=AuthorDetail.objects.get(adrr="沙河",email="123")print(detail_obj.author.name)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例二(反向查询):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询姓名为alex的作者的地址addr (反向查询,按表名)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

author_obj=Author.objects.get(name="alex")print(author_obj.authordetail.adrr)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

实例三(综合实例):文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

#查询住在沙河的作者出版过的所有书籍的名称以及出版社名称文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

authordetail=AuthorDetail.objects.get(addr="沙河")文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

author=authordetail.author #正向查询,得到author models对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

bookList=author.book_set.all() #反向查询,得到bookList queryset对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

for book inbookList:print(book.title,book.publish.name)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

总结:在上述的论述中,所有的反向的查询的表名均为小写,且需要提醒的是在一对一的反向查询中表名不需要跟set,因为它只有一个对象,通过“.表名”得到的是一个models对象,可以直接查询需要的字段。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/bc/28180.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/bc/28180.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定