• day 48 ORM 进阶 多表连接 创建 以及 html模板继承


        多表的一对多创建

       多表的多对多创建

       多表的一对多修改

       多表的多对多修改

    前情提要:  

      最近认识了不少大佬,大佬开着保时捷. .一顿狂奔..我连车尾灯都看不到..

      本次内容  ORM 的多表链接  查询    ,  html的模板继承

     

       2、添加表记录

          方式一:

            通过类实例化对象的方式。注意:一定要对象.save()

    1
    2
    book = models.Book(title="吸星大法", price=200, publisher="明教出版社", pub_date="2018-12-12")
    book.save()

          方式二:

            通过ORM提供的objects提供的方法 create来实现。

    1
    book = models.Book.objects.create(title="独孤九剑", price=150, publisher="华山出版社", pub_date="2019-1-12")
        3、查询表记录

          1、查询API

    复制代码
    <1> all():                  查询所有结果
      
    <2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
      
    <3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
                                如果符合筛选条件的对象超过一个或者没有都会抛出错误。
      
    <4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
     
    <5> order_by(*field):       对查询结果排序
      
    <6> reverse():              对查询结果反向排序
      
    <7> count():                返回数据库中匹配查询(QuerySet)的对象数量。
      
    <8> first():                返回第一条记录
      
    <9> last():                返回最后一条记录
      
    <10> exists():              如果QuerySet包含数据,就返回True,否则返回False
     
    <11> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                                model的实例化对象,而是一个可迭代的字典序列
    <12> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
     
    <13> distinct():            从返回结果中剔除重复纪录
    复制代码

          2、基于双下划线的模糊查询

    1
    2
    3
    4
    5
    6
    7
    8
    Book.objects.filter(price__in=[100,200,300])
    Book.objects.filter(price__gt=100)
    Book.objects.filter(price__lt=100)
    Book.objects.filter(price__range=[100,200])
    Book.objects.filter(title__contains="法")
    Book.objects.filter(title__icontains="python")  # 不区分大小写
    Book.objects.filter(title__startswith="九")
    Book.objects.filter(pub_date__year=2018)
        4、删除表记录

          删除方法就是 delete()。它运行时立即删除对象而不返回任何值。例如:

    1
    model_obj.delete()

          你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

          例如,下面的代码将删除 pub_date 是2018年的 Book 对象:

    1
    Book.objects.filter(pub_date__year=2018).delete()

          在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。例如:

    1
    2
    3
    = Book.objects.get(pk=1)
    # This will delete the Blog and all of its Entry objects.
    b.delete()

    要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

    1
    Book.objects.all().delete()  
        5、修改表记录

          方式一:

            通过修改实例对象的属性方式。注意:一定要对象.save()

    1
    2
    3
    book = models.Book.objects.get(title="吸星大法")
    book.price = 180
    book.save()

          方式二:

            通过ORM提供的objects提供的方法 update来实现。

    1
    models.Book.objects.filter(title="吸星大法").update(price=190)

            此外,update()方法对于任何结果集(QuerySet)均有效,这意味着你可以同时更新多条记录update()方法会返回一个整型数值,表示受影响的记录条数。 

         

    一:  html 模板继承

            模板继承主要使用在几个界面大体类似 只是 地方做修改的时候的操作

            1:首先先建立一个公共模板

            

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6     <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/bootstrap/css/bootstrap.css">
     7     <link rel="stylesheet" href="/static/css/dsb.css">
     8     {% block css %}
     9     {% endblock css %}
    10 </head>
    11 <body>
    12 
    13     <nav class="navbar navbar-inverse navbar-fixed-top">
    14       <div class="container-fluid">
    15         <div class="navbar-header">
    16           <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
    17             <span class="sr-only">Toggle navigation</span>
    18             <span class="icon-bar"></span>
    19             <span class="icon-bar"></span>
    20             <span class="icon-bar"></span>
    21           </button>
    22           <a class="navbar-brand" href="#">图书管理系统</a>
    23         </div>
    24         <div id="navbar" class="navbar-collapse collapse">
    25           <ul class="nav navbar-nav navbar-right">
    26             <li><a href="#">Dashboard</a></li>
    27             <li><a href="#">Settings</a></li>
    28             <li><a href="#">Profile</a></li>
    29             <li><a href="#">Help</a></li>
    30           </ul>
    31           <form class="navbar-form navbar-right">
    32             <input type="text" class="form-control" placeholder="Search...">
    33           </form>
    34         </div>
    35       </div>
    36     </nav>
    37 
    38     <div class="container-fluid">
    39       <div class="row">
    40         <div class="col-sm-3 col-md-2 sidebar">
    41           <ul class="nav nav-sidebar">
    42             <li class="active"><a href="{% url 'book_list' %}">书籍列表 <span class="sr-only">(current)</span></a></li>
    43             <li><a href="#">Reports</a></li>
    44             <li><a href="#">Analytics</a></li>
    45             <li><a href="#">Export</a></li>
    46           </ul>
    47         </div>
    48         <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
    49           <div class="panel panel-primary">
    50       <div class="panel-heading">
    51         {% block title %}
    52         {% endblock title %}
    53       </div>
    54       <div class="panel-body">
    55 
    56           {% block content %}
    57                 <a class="btn btn-primary" href="{% url 'add_book' %}">新增书籍</a>
    58           {% endblock content %}
    59       </div>
    60     </div>
    61         </div>
    62       </div>
    63     </div>
    64 
    65 
    66 
    67 </body>
    68 {% block js %}
    69 {% endblock js %}
    70 </html>
    View Code

     css 模板继承

     html 继承

     

     js 继承:

    前面是在模板层定义大体框架,之后设计具体的内容

      

    {% extends 'layout.html' %}
    
    {% block title %}
    <h3 class="panel-title">书籍列表</h3>
    {% endblock title %}
    
    {% block content %}
        {{ block.super }}
    <table class="table table-hover">
                <thead>
            <tr>
                <th>序号</th>
                <th>id</th>
                <th>书名</th>
                <th>价格</th>
                <th>出版社</th>
                <th>出版日期</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for book in all_book %}
            <tr>
                <td>{{ forloop.counter }}</td>
                <td>{{ book.pk }}</td>
                <td>{{ book.title }}</td>
                <td>{{ book.price }}</td>
                <td>{{ book.publish }}</td>
                <td>{{ book.pub_date|date:"Y-m-d" }}</td>
                <td>
                    <a class="btn btn-info btn-sm" href="{% url 'edit_book' book_id=book.nid %}">编辑</a>
                    |
                    <a class="btn btn-danger btn-sm" href="{% url 'del_book' book.nid %}">删除</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
            </table>
    {% endblock content %}

          二:  ORM 多表链接

        1:创建模型

          >1: 创建图书管理系统的模型

        1.1分析:  

    由 上可知 :  

      模型创建以后有5个表  

        其中  book 中的 book_id 与 book_author 是一对多的关系 ,即一本书可能会有好几个作者

        publish 表中的id 与book 表中的publish 是一对多的关系 ,即一个出版社可能会有好几个书

         author表与book_author  是一对多的关系 ,即一个作者可能会有好几个书,

        所以book_author 是多对多关系. 是第第三方表.

    通过上面分析.:  Django 中可以创建4个模型. 即可实现5个表的关系

      book 模型

    from django.db import models
    
    
    # Create your models here.
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        pub_date = models.DateField
        publish = models.ForeignKey("Publish", on_delete=models.CASCADE)  # 一对多
        authors = models.ManyToManyField("Author")  # 多对多
    View Code

        publish 模型

    class Publish(models.Model):
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=64)
        email = models.EmailField()
    View Code

      author 模型

    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        au_detail = models.OneToOneField("AuthorDeail", on_delete=models.CASCADE)  # 一对一
    View Code

      AuthorDeail 模型

    class AuthorDeail(models.Model):
        tel = models.CharField(max_length=32)
        addr = models.CharField(max_length=255)
        birthday =models.DateField()
    View Code

    创建一对多关系时  对应的id Django 会自动帮填写id

     

    整理 : 首先是普通方法

        正向:调用字段名  ,反向: 调用小写的表明 

        1:一对多

        正向: (在model 内写关系的为正向)

    代码:

    # book_obj=models.Book.objects.filter(pk=1).first()
        # print(book_obj.publish.city)

      反向:

    # pub_obj =models.Publish.objects.filter(id=2).first()
        # print(pub_obj.book_set.all(),type(pub_obj.book_set.all()))
        # for i in pub_obj.book_set.all():
        #     print(i.title)

       2:多对多

      正向:

     

        # book_obj =models.Book.objects.filter(id=2).first()
        # for i in book_obj.authors.all():
        #     print(i.name,i.au_detail.tel)

       反向:

      # au_obj =models.Author.objects.filter(id=3).first()
        # for j in au_obj.book_set.all():
        #     print(j.title)

    3:一对一

    一对一没有正反向, 两端一样

       # 一对一查询
        # au_obj = models.Author.objects.filter(id=3).first()
        # print(au_obj.au_detail.tel)
        # au_addr = models.AuthorDetail.objects.filter(id=2).first()
        # print(au_addr.author.name)

     双下 方法的使用

      正向: 直接调用他对应的内容的字段

      反向: 反向找到其父级,调用其对应内容的字段

      

    关联管理器(RelatedManager)

     

    一、class RelatedManager

      "关联管理器"是在一对多或者多对多的关联上下文中使用的管理器。它存在于下面两种情况:

      1、一对多

        ForeignKey关系的“另一边”。像这样:

    1
    2
    3
    4
    5
    6
    7
    from django.db import models
      
    class Publish(models.Model):
        pass
      
    class Book(models.Model):
        publish = models.ForeignKey("Publish", on_delete=models.CASCADE)

        在上面的例子中,管理器publish_obj.book_set  会拥有下面介绍的方法。

      2、多对多

        ManyToManyField关系的两边:

    1
    2
    3
    4
    5
    6
    class Author(models.Model):
        pass
     
     
    class Book(models.Model):
        authors = models.ManyToManyField("Author")

        在这个例子中,book_obj.authors 和author_obj.book_set 都拥有下面的方法。

      3、方法合集

        1、add(obj1[, obj2, ...])
    复制代码
    把指定的模型对象添加到关联对象集中。
    
    例如:
    
    >>> author_obj = Author.objects.get(id=1)
    >>> book_obj = Book.objects.get(id=2)
    >>> author_obj .book_set.add(e) 
    在上面的例子中,对于ForeignKey关系,book_obj.save()由关联管理器调用,执行更新操作。然而,在多对多关系中使用add()并不会调用任何 save()方法,而是由QuerySet.bulk_create()创建关系。
    
    延伸:
    
    # 1 *[]的使用
    >>> book_obj = Book.objects.get(id=1)
    >>> author_list = Author.objects.filter(id__gt=2)
    >>> book_obj.authors.add(*author_list)
    
    
    # 2 直接绑定主键
    book_obj.authors.add(*[1,3])  # 将id=1和id=3的作者对象添加到这本书的作者集合中
                                  # 应用: 添加或者编辑时,提交作者信息时可以用到.
    复制代码
        2、create(**kwargs)
    复制代码
    创建一个新的对象,保存对象,并将它添加到关联对象集之中。返回新创建的对象:
    
    >>> author_obj = Author.objects.get(id=1)
    >>> book = author_obj.book_set.create(
        ...
        title='挤奶龙爪手',
        ...
    )
    
    # No need to call e.save() at this point -- it's already been saved.
    这完全等价于(不过更加简洁于):
    
    >>> author_obj = Author.objects.get(id=1)
    >>> book = Book(
        ...
        title='挤奶龙爪手',
        ...
    )
    >>> author_obj.save(force_insert=True)
    要注意我们并不需要指定模型中用于定义关系的关键词参数。在上面的例子中,我们并没有传入author_obj参数给create()。Django会明白新的 Book对象author_obj 应该添加到author_obj中。
    复制代码
        3、remove(obj1[, obj2, ...])
    复制代码
    从关联对象集中移除执行的模型对象:
    
    >>> author_obj = Author.objects.get(id=1)
    >>> book_obj = Book.objects.get(id=2)
    >>> author_obj .book_set.remove(book_obj) 
    对于ForeignKey对象,这个方法仅在null=True时存在。
    复制代码
        4、clear()
    复制代码
    从关联对象集中移除一切对象。
    
    >>> author_obj = Author.objects.get(id=1)
    >>> author_obj.book_set.clear()
    注意这样不会删除对象 —— 只会删除他们之间的关联。
    
    就像 remove() 方法一样,clear()只能在 null=True的ForeignKey上被调用。
    复制代码
        5、set()方法

        先清空,在设置,编辑书籍时即可用到。

    book = models.Book.objects.filter(title="独孤九剑").first()
    book.authors.set([1, 3])  

    注意:

    对于所有类型的关联字段,add()、create()、remove()和clear(),set()都会马上更新数据库。换句话说,在关联的任何一端,都不需要再调用save()方法。

    二、操作表记录

      1、添加一些简单的数据

        1、publish表:

        2、author表:

        3、authordatail表:

      2、一对多

    复制代码
    # 方式一 传对象的形式
    pub_obj = models.Publish.objects.get(pk=1)
    book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish=pub_obj)
    
    # 方式二 传对象id的形式
    book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish_id=1)
    复制代码

        核心:明白book.publish 和 book.publish_id 的区别?

      3、多对多

    复制代码
    # 方式一 传对象的形式
    book = models.Book.objects.filter(title="独孤九剑").first()
    ling = models.Author.objects.filter(name="令狐冲").first()
    ying = models.Author.objects.filter(name="任盈盈").first()
    book.authors.add(ling, ying)
    
    # 方式二 传对象id的形式
    book = models.Book.objects.filter(title="独孤九剑").first()
    ling = models.Author.objects.filter(name='令狐冲').first()
    ying = models.Author.objects.filter(name='任盈盈').first()
    book.authors.add(ling.pk, ying.pk)
    复制代码

        核心:book.authors.all()是什么?

        多对多其他常用API:

    1
    2
    3
    book_obj.authors.remove()      # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
    book_obj.authors.clear()       #清空被关联对象集合
    book_obj.authors.set()         #先清空再设置

      more

      2、基于对象的跨表查询

        1、一对多查询(Publish 与 Book)

        正向查询(按字段 publish)

    1
    2
    3
    4
    # 查询主键为1的书籍的出版社所在的城市
    book_obj=Book.objects.filter(pk=1).first()
    # book_obj.publish 是主键为1的书籍对象关联的出版社对象
    print(book_obj.publish.city)

        反向查询(按book表)

    1
    2
    3
    4
    5
    6
    # 查询明教出版社出版的书籍名
    publish=Publish.objects.get(name="明教出版社")
    #publish.book_set.all() : 与明教出版社关联的所有书籍对象集合
    book_list=publish.book_set.all()   
    for book_obj in book_list:
           print(book_obj.title)
        2、一对一查询(Author 和 AuthorDetail)

        正向查询(按字段:au_detail):

    1
    2
    # 查询令狐冲的电话<br>ling=Author.objects.filter(name="令狐冲").first()
    print(ling.au_detail.tel)

        反向查询(按表名:author):

    1
    2
    3
    4
    5
    # 查询所有住址在黑木崖的作者的姓名
      
    authorDetail_list=AuthorDetail.objects.filter(addr="黑木崖")
    for obj in authorDetail_list:
         print(obj.author.name)
        3、多对多查询 (Author 与 Book)

        正向查询(按字段:authors):

    1
    2
    3
    4
    5
    6
    # 独孤九剑所有作者的名字以及手机号
     
    book_obj = Book.objects.filter(title="独孤九剑").first()
    authors = book_obj.authors.all()
    for author_obj in authors:
        print(author_obj.name, author_obj.au_detail.tel)

        反向查询(按表名:book_set):

    1
    2
    3
    4
    5
    6
    # 查询令狐冲出过的所有书籍的名字
     
        author_obj=Author.objects.get(name="令狐冲")
        book_list=author_obj.book_set.all()        #与令狐冲作者相关的所有书籍
        for book_obj in book_list:
            print(book_obj.title)

        注意:

          你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Book model 中做一下更改:

    1
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE, related_name="book_list")

        那么接下来就会如我们看到这般:

    1
    2
    3
    4
    # 查询 明教出版社出版过的所有书籍
     
    publish=Publish.objects.get(name="明教出版社")
    book_list=publish.book_list.all()  # 与明教出版社关联的所有书籍对象集合

       3、基于双下划线的跨表查询

        Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。

    '''
        正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
    '''
        1、一对多查询
    复制代码
    # 练习:  查询明教出版社出版过的所有书籍的名字与价格(一对多)
    
        # 正向查询 按字段:publish
    
        queryResult=Book.objects.filter(publish__name="明教出版社").values_list("title","price")
    
        # 反向查询 按表名:book
    
        queryResult=Publish.objects.filter(name="明教出版社").values_list("book__title","book__price")
    复制代码
        2、多对多查询 
    复制代码
    # 练习: 查询令狐冲出过的所有书籍的名字(多对多)
    
        # 正向查询 按字段:authors:
        queryResult=Book.objects.filter(authors__name="令狐冲").values_list("title")
    
        # 反向查询 按表名:book
        queryResult=Author.objects.filter(name="令狐冲").values_list("book__title","book__price")
    复制代码
        3、一对一查询
    复制代码
    # 查询令狐冲的手机号
        
        # 正向查询
        ret=Author.objects.filter(name="令狐冲").values("au_detail__tel") 

      #
    反向查询
      ret=AuthorDetail.objects.filter(author__name="令狐冲").values("tel")
    复制代码
        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")
    
    
    # 练习: 手机号以132开头的作者出版过的所有书籍名称以及出版社名称

    # 方式1: queryResult=Book.objects.filter(authors__au_detail__tel__startswith="132").values_list("title","publish__name")

       # 方式2:
       ret=Author.objects.filter(au_detail__tel__startswith="132").values("book__title","book__publish__name")
    复制代码

    二、操作表记录

      1、添加一些简单的数据

        1、publish表:

        2、author表:

        3、authordatail表:

      2、一对多

    复制代码
    # 方式一 传对象的形式
    pub_obj = models.Publish.objects.get(pk=1)
    book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish=pub_obj)
    
    # 方式二 传对象id的形式
    book = models.Book.objects.create(title="独孤九剑", price=180, pub_date="2018-10-23", publish_id=1)
    复制代码

        核心:明白book.publish 和 book.publish_id 的区别?

      3、多对多

    复制代码
    # 方式一 传对象的形式
    book = models.Book.objects.filter(title="独孤九剑").first()
    ling = models.Author.objects.filter(name="令狐冲").first()
    ying = models.Author.objects.filter(name="任盈盈").first()
    book.authors.add(ling, ying)
    
    # 方式二 传对象id的形式
    book = models.Book.objects.filter(title="独孤九剑").first()
    ling = models.Author.objects.filter(name='令狐冲').first()
    ying = models.Author.objects.filter(name='任盈盈').first()
    book.authors.add(ling.pk, ying.pk)
    复制代码

        核心:book.authors.all()是什么?

        多对多其他常用API:

    1
    2
    3
    book_obj.authors.remove()      # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
    book_obj.authors.clear()       #清空被关联对象集合
    book_obj.authors.set()         #先清空再设置

      more

      2、基于对象的跨表查询

        1、一对多查询(Publish 与 Book)

        正向查询(按字段 publish)

    1
    2
    3
    4
    # 查询主键为1的书籍的出版社所在的城市
    book_obj=Book.objects.filter(pk=1).first()
    # book_obj.publish 是主键为1的书籍对象关联的出版社对象
    print(book_obj.publish.city)

        反向查询(按book表)

    1
    2
    3
    4
    5
    6
    # 查询明教出版社出版的书籍名
    publish=Publish.objects.get(name="明教出版社")
    #publish.book_set.all() : 与明教出版社关联的所有书籍对象集合
    book_list=publish.book_set.all()   
    for book_obj in book_list:
           print(book_obj.title)
        2、一对一查询(Author 和 AuthorDetail)

        正向查询(按字段:au_detail):

    1
    2
    # 查询令狐冲的电话<br>ling=Author.objects.filter(name="令狐冲").first()
    print(ling.au_detail.tel)

        反向查询(按表名:author):

    1
    2
    3
    4
    5
    # 查询所有住址在黑木崖的作者的姓名
      
    authorDetail_list=AuthorDetail.objects.filter(addr="黑木崖")
    for obj in authorDetail_list:
         print(obj.author.name)
        3、多对多查询 (Author 与 Book)

        正向查询(按字段:authors):

    1
    2
    3
    4
    5
    6
    # 独孤九剑所有作者的名字以及手机号
     
    book_obj = Book.objects.filter(title="独孤九剑").first()
    authors = book_obj.authors.all()
    for author_obj in authors:
        print(author_obj.name, author_obj.au_detail.tel)

        反向查询(按表名:book_set):

    1
    2
    3
    4
    5
    6
    # 查询令狐冲出过的所有书籍的名字
     
        author_obj=Author.objects.get(name="令狐冲")
        book_list=author_obj.book_set.all()        #与令狐冲作者相关的所有书籍
        for book_obj in book_list:
            print(book_obj.title)

        注意:

          你可以通过在 ForeignKey() 和ManyToManyField的定义中设置 related_name 的值来覆写 FOO_set 的名称。例如,如果 Book model 中做一下更改:

    1
    publish = models.ForeignKey("Publish", on_delete=models.CASCADE, related_name="book_list")

        那么接下来就会如我们看到这般:

    1
    2
    3
    4
    # 查询 明教出版社出版过的所有书籍
     
    publish=Publish.objects.get(name="明教出版社")
    book_list=publish.book_list.all()  # 与明教出版社关联的所有书籍对象集合

       3、基于双下划线的跨表查询

        Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。

    '''
        正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表
    '''
        1、一对多查询
    复制代码
    # 练习:  查询明教出版社出版过的所有书籍的名字与价格(一对多)
    
        # 正向查询 按字段:publish
    
        queryResult=Book.objects.filter(publish__name="明教出版社").values_list("title","price")
    
        # 反向查询 按表名:book
    
        queryResult=Publish.objects.filter(name="明教出版社").values_list("book__title","book__price")
    复制代码
        2、多对多查询 
    复制代码
    # 练习: 查询令狐冲出过的所有书籍的名字(多对多)
    
        # 正向查询 按字段:authors:
        queryResult=Book.objects.filter(authors__name="令狐冲").values_list("title")
    
        # 反向查询 按表名:book
        queryResult=Author.objects.filter(name="令狐冲").values_list("book__title","book__price")
    复制代码
        3、一对一查询
    复制代码
    # 查询令狐冲的手机号
        
        # 正向查询
        ret=Author.objects.filter(name="令狐冲").values("au_detail__tel") 

      #
    反向查询
      ret=AuthorDetail.objects.filter(author__name="令狐冲").values("tel")
    复制代码
        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")
    
    
    # 练习: 手机号以132开头的作者出版过的所有书籍名称以及出版社名称

    # 方式1: queryResult=Book.objects.filter(authors__au_detail__tel__startswith="132").values_list("title","publish__name")

       # 方式2:
       ret=Author.objects.filter(au_detail__tel__startswith="132").values("book__title","book__publish__name")
    复制代码
    # book_obj =models.Book.objects.filter(id=2).first()
    # for i in book_obj.authors.all():
    # print(i.name,i.au_detail.tel)



      '''1、查询丐帮出版社出版的所有书名和作者名称;
        2、查询独孤九剑的作者名称和出版社名称;
        3、查询吸星大法的作者的姓名、电话和地址;
        4、查询令狐冲写的书籍,在哪些出版社出版过,获取其出版社名称和地址;
        5、查询出版社地址为黑木崖,在该出版社出版过书籍的作者姓名和邮箱;
       '''
        # 正向查询按字段, 反向查询按小写表名。
        # 1方式1 正向 双下
        # books1 =models.Book.objects.filter(publish__id=2).values("title","authors__name")
        # print(books1)
        # print(">>>>>>>>>>>>>>>>>")
        # # 1方式2 反向 双下
        # books2 =models.Publish.objects.filter(id=2).values("book__title","book__authors__name")
        # print(books2)
        # # 1 方式3 反向
        # pub1 =models.Publish.objects.filter(id=2).first()
        # for i in pub1.book_set.all():
        #     for j in i.authors.all():
        #
        #         print(i.title,j.name)
    
    
        # 2 方法1
        # books1 =models.Book.objects.filter(id=2).values("authors__name","publish__name")
        # print(books1)
        # #2 方法2
        # books2 =models.Author.objects.filter(book__id=2).values("name","book__publish__name")
        # print(books2)
        # #2 方法3
        # books3 =models.Book.objects.filter(id=2)
    
        # for i in books3:
        #     name,pub=i.authors.all(),i.publish.name
        #     for j in name:
        #         print(j.name,i.publish)
        # 3、查询吸星大法的作者的姓名、电话和地址;
    
        # 3 方法1:
        # books1=models.Book.objects.filter(id=3).values("authors__name","authors__au_detail__tel","authors__au_detail__addr")
        #
        # print(books1)
        # #3 方法2:
        # books2 =models.Author.objects.filter(book__id=3).values("name","au_detail__tel","au_detail__addr")
        # print(books2)
        # # 3 方法3:
        # books3 =models.Book.objects.filter(id=3).first().authors.all()
        # for i in books3:
        #     print(i.name,i.au_detail.tel,i.au_detail.addr)
        # 4、查询令狐冲写的书籍,在哪些出版社出版过,获取其出版社名称和地址;
        # 4 方法1:
        # books1 =models.Author.objects.filter(id=3).values("book__title","book__publish__name","book__publish__city")
        # print(books1)
        # # 4 方法2:
        # books2 =models.Book.objects.filter(authors__id=3).values("title","publish__name","publish__city")
        # print(books2)
        # #4 方法3 :
        # books3 =models.Author.objects.filter(id=3).first()
        # for i in books3.book_set.all():
        #     print(i.title,i.publish.name,i.publish.city)
        #
        # 5     5、查询出版社地址为黑木崖,在该出版社出版过书籍的作者姓名和邮箱;
        # 5 方法1 :
        books1 =models.Publish.objects.filter(id=2).values("book__title","book__authors__name","book__authors__au_detail__addr")
        print(books1)
        # 5 方法2:
        books2 =models.Book.objects.filter(publish_id=2).values("title","authors__name","authors__au_detail__addr")
        print(books2)
        # 5 方法3:
        books3 =models.Publish.objects.filter(id=2).first()
        for i in books3.book_set.all():
            for j in i.authors.all():
                print(i.title,j.name)
    
    
    
     
  • 相关阅读:
    软工个人阅读作业3
    阅读作业2
    代码复审
    pair project elevator
    读《移山之道——VSTS软件开发指南》
    软件工程作业--词频统计
    个人阅读作业3
    个人阅读作业2
    代码复审
    结对项目电梯吐血总结
  • 原文地址:https://www.cnblogs.com/baili-luoyun/p/10555216.html
Copyright © 2020-2023  润新知