多表操作
--
models下创建模型
class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField() # 阅读数 # reat_num=models.IntegerField(default=0) # 评论数 # commit_num=models.IntegerField(default=0) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() 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()
1.增删改
在Python脚本中直接运行sql
正向:关联关系在当前表中,从当前表去另一个表;正向查询按字段名
反向:关联关系不在当前表,从当前表去另一个表;反向查询按表名小写
一对一:
--
一对一增加(create)
authordetail=models.AuthorDatail.objects.create(addr='南京') # author=models.Author.objects.create(name='恩公',age=17,author_detail=authordetail) author=models.Author.objects.create(name='小猴',age=16,author_detail_id=authordetail.pk)
一对多:
--
一对多增加(2种create)
# publish:可以传一个publish对象 publish=models.Publish.objects.get(pk=1) print(publish.name) ret=models.Book.objects.create(name='西游记',price=88,publish_date='2018-09-12',publish=publish)
# publish_id:传一个id ret=models.Book.objects.create(name='三国演义',price=32,publish_date='2018-07-12',publish_id=publish.pk) print(type(ret.publish))
一对多修改(3种save,update)
book=models.Book.objects.get(pk=2) book.publish_id=2 # book.publish=出版社对象 book.save()
ret=models.Book.objects.filter(pk=2).update(publish=publish对象)
ret=models.Book.objects.filter(pk=2).update(publish_id=2)
多对多:
--
多对多增加(add)
#给红楼梦这本书添加两个作者(lqz,egon) book = models.Book.objects.get(pk=1) #相当于拿到了第三张表 往第三章表中添加纪录(问题来了?要传对象还是传id),都支持 book.authors.add(1,2) lqz = models.Author.objects.get(pk=1) egon = models.Author.objects.get(pk=2) book.authors.add(lqz,egon)
book.authors.add(*[lqz,egon])
多对多删除(remove)
#remove字段authors的id和名字都可以(名字为通过id获取的) book.authors.remove(2) book.authors.remove(egon,lqz) book.authors.remove(1,2) book.authors.remove(*[1,2]) book.authors.remove(*[lqz,egon])
多对多修改(set)
#修改红楼梦这本书的作者为lqz和egon #先清空(清空这本的所有作者记录) book.authors.clear() book.authors.add(1,2) book.authors.set(*[6,]) #这样不行 book.authors.set([6,]) #需要这样传 lqz=models.Author.objects.get(pk=2) set 必须传一个可迭代对象 book.authors.set([lqz,]) #需要这样传
(二):多表查询(基于对象,双下划线)
基于对象的跨表查询(多次查询) 一对一: -正向查询按字段 -反向查询按表名小写 一对多: -正向查询按字段(正向查询一定会查出一个来) -反向查询按表名小写_set.all()(返回结果是queryset对象) 多对多: -正向查询按字段.all()(正向查询一定会查出多个来) -反向查询按表名小写_set.all()(返回结果是queryset对象) 基于双下划线的跨表查询 -在filter和values中都可以做连表操作(也就是都可以写 __) -正向查询按字段 -反向查询按表名小写 无论以谁做基表,没有效率之分
基于对象跨表查询
正向查询按字段,反向查询:表名小写_set
-
一对一
#查询lqz作者的地址(正向查询,按字段) lqz=models.Author.objects.filter(name='lqz').first() # 作者详情对象 print(lqz.author_detail.addr) #查询地址为上海的,作者的名字(反向查询,按表名小写) authordetail=models.AuthorDatail.objects.filter(addr='上海').first() #拿到的是作者对象authordetail.author print(authordetail.author.name)
-
一对多
#查询红楼梦这本书的出版社名字(正向,按字段) book=models.Book.objects.get(pk=1) #出版社对象 book.publish print(book.publish.name) #查询北京出版社出版的所有书名(反向查询按 表名小写_set.all()) publish=models.Publish.objects.get(pk=1) #结果是queryset对象 books=publish.book_set.all() for book in books: print(book.name) #查询以红开头的 books=publish.book_set.all().filter(name__startswith='红') for book in books: print(book.name)
-
多对多
#红楼梦这本书所有的作者(正向 字段) book=models.Book.objects.get(pk=1) # book.authors.all()拿到所有的作者,是一个queryset对象 authors=book.authors.all() for author in authors: print(author.name) #查询egon写的所有书(反向 表名小写_set.all()) egon=models.Author.objects.get(pk=2) #拿到的是queryset对象 books=egon.book_set.all() for book in books: print(book.name)
基于双下滑线跨表查询
正向查询按字段,反向查询:表名小写__字段名
-
一对一
#查询lqz作者的名字,地址(正向查询,按字段) ret=models.Author.objects.filter(name='lqz').values('name','author_detail__addr') print(ret) #查询地址为上海的作者的名字(反向,按表名小写) ret=models.AuthorDatail.objects.filter(addr='上海').values('addr','author__name','author__age') print(ret.query) print(ret)
-
一对多
#查询红楼梦这本书的出版社的名字(正向 按字段) ret=models.Book.objects.filter(name='红楼梦').values('name','publish__name') print(ret) #查询北京出版社出版的所有书的名字(反向 按表名小写) ret=models.Publish.objects.filter(name='北京出版社').values('book__name') print(ret)
-
多对多
#红楼梦这本书所有的作者名字(正向 按字段) ret=models.Author.objects.filter(book__name='红楼梦').values('name') print(ret) ret=models.Book.objects.filter(name='红楼梦').values('authors__name') print(ret) #egon出版的所有书的名字(反向 表名小写) ret=models.Book.objects.filter(authors__name='egon').values('name') print(ret) ret=models.Author.objects.filter(name='egon').values('book__name') print(ret) #查询北京出版社出版过的所有书籍的名字以及作者的姓名 ret=models.Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name') print(ret) ret=models.Book.objects.filter(publish__name='北京出版社').values('name','authors__name') print(ret) ret=models.Author.objects.filter(book__publish__name='北京出版社').values('book__name','name') print(ret)
#地址是以北开头的作者出版过的所有书籍名称以及出版社名称
#以authordetial为基表 ret = models.AuthorDatail.objects.filter(addr__startswith='北').values('author__book__name', 'author__book__publish__name') print(ret) #以book为基表 ret=models.Book.objects.filter(authors__author_detail__addr__startswith='北').values('name','publish__name') print(ret.query)
#以author为基表 ret=models.Author.objects.filter(author_detail__addr__startswith='北').values('book__name','book__publish__name') print(ret.query)
所有评论(0)