zoukankan      html  css  js  c++  java
  • 多表操作

    多表操作

     --

    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()
    models.py

    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)
  • 相关阅读:
    操作系统基础知识与常见问题记录
    String
    Function
    HelloWorld
    替换空格
    二维数组中的查找
    建造者模式(Builder Pattern)
    单例模式(Singleton Pattern)
    工厂方法(Factory Pattern)
    设计模式概述
  • 原文地址:https://www.cnblogs.com/xuechengeng/p/10461521.html
Copyright © 2011-2022 走看看