• ORM模型里连接数据库常用方法和QuerySet API


    模型.objects:

    这个对象是django.db.models.manager.Manager的对象,这个类是一个空壳类,他上面的所有方法都是从'QuerySet'这个类上面拷贝过来的。因此我们只要学会了'QuerySet',这个‘objects’也就知道如何使用了。

    'Manage'源码解析:

    、、、python

    class_name = 'BaseManagerFromQuerySet'
    
    
    Class_dict = {
        '_queryset_class':QuerySet      
    }
    
    
    Class_dict.update(cls.get_queryset_methods(QuerySet))

    #type动态的时候创建类

    #第一个参数是用来指定创建的类的名字。 创建的类名是:BaseManagerFromQuerySet

    #第二个参数是用来指定这个类的父类。

    #第三个参数是用来指定这个类的一些属性和方法

    return type(class_name,(cls,),class_dict)

    _get_query_methods:这个方法就是将Queryset中的一些方法拷贝出来

    ##filter/exclude.annotate:过滤/排除满足条件的/给模型添加新的字段。

    ##order_by:

    #根据创建的时间正序排序
    articles = Article.objects.order_by("create_time")
    # 根据创建的时间倒序排序
    articles = Article.objects.order_by("-create_time")
    # 根据作者的名字进行排序
    articles = Article.objects.order_by("author__name")
    # 首先根据创建的时间进行排序,如果时间相同,则根据作者的名字进行排序
    articles = Article.objects.order_by("create_time",'author__name')

    一定要注意的是,多个‘order_by’,会把前面排序的规则给打乱,而使用后面的排序方式。如:

    articles = Article.objects.order_by("create_time").order_by("author__name")

    它会根据作者的名字进行排序,而不是使用文章的创建时间。

    当然,也可以在模型定义的在‘Meta’类中定义'ordering'来指定默认的排序方式。如

        class Meta:
            db_table = 'book_order'
            ordering = ['create_time','-price']

    还可以根据`annotate`定义的字段进行排序。比如要实现图书的销量进行排序,那么示例代码如下:

    books = Book.objects.annotate(order_nums=Count("bookorder")).order_by("-order_nums")
        for book in books:
            print('%s/%s'%(book.name,book.order_nums))

    values:

    有时候我们在表中查找数据的时候,并不是想要把所有的字段都提取出来,
    有可能只想要其中的几个字段,这时候就可以使用`values`来实现,需要什么字段,就把这个字段的名字传到这个方法中

    books = Book.object.values('id',‘name)

    `values`的返回值同样也是一个`QuerySet`对象,但是里面装的不再是模型,而是字典

    如果我们想要提取的使者模型上关联的对象的属性,也是可以的,查找方法跟`filter`的用法是一样的

    books=Book.object.values('id','name','author__name')


    以上会提取`author`的`name`字段,如果想要更改这个默认的名字那么可以使用关键字参数

    books=Book.objects.values('id','name',author_name=F('author__name'))

    自定义的名字,不能和模型上本身拥有的字段一样,比如以上‘author_name’如果取名叫做'author'就会报错,因为“Book‘表里本身就拥有一个字段叫做’author‘

    在’vialues‘中,也可以使用聚合函数来形成一个新的字段,比如想要获取每本书的销量

    books=Book.objects.values('id','name',order_nums=Count('bookorder'))

    如果调用'values'方法的时候,没有传递任何的参数,name会获取这个模型上的所有字段以及对应的值形成的字典

    books=Book.objects.values
    #bookS值如下:
    ###{'id':1,'name':'三国演义','pages':987,'price':108,rating:3.9,'author_id':3,'publisher_id':1}

    values_list

    跟value是一样的作用,只不过这个方法返回的是’QuerySet‘中,装的不是字典而是元组

    books = Book.objects.values_list('id','name')
    
    ##结果是:(1,’三国演义‘)

     如果给`values_list`只指定一个字段,那么可以指定`flat=True`这样返回的结果就不在是一个元组,而是这个字段的值

    books=Book.objects.values_list('name',flat=True)

    ###结果是 '三国演义'

    flat只能用在只有一个字段的情况下,否则会报错

    all方法

    这个返回简单的一个`QuerySet`对象,这个对象没有经过任何修改(比如:过滤等)

    ## select_related

    在查找某个表的数据的时候,可以一次性把相关联的其他表的数据都提取出来,这样可以在以后访问相关联的数据的时候,不用再次查找数据库,可以节省一些开销

    books=Book.objects.select_related('author','publisher')
    for book in books:
        print(book.author.name)d
        #因为在提取Book的时候,使用了select_related,那么以后再访问book_author的时候,不会再次向数据库重新发起查询了

     注意:


    注意:这个方法只能用在外键关联的对象上,对于那种多对多,或者一对多的情况,不能使用它来实现,而应该使用`perfetch_related`来实现

    prefetch_related:

    这个方法类似于select_related方法,也是用在查询语句的时候,提前将指定的数据查找出来,只不过这个方法是是用来解决多对多或者多对一的情况,这个方法会产生两个查询语句,所以,如果在这个方法中查询使用外键关联的模型的时候,也会产生两个查询语句,因此如果查询的是外键关联的模型,建议使用`select_related`方法。在查询多对多或者多对一的关联的队形的时候,在使用模型怎么访问这个多对多,就在这方法中传递什么字符串,比如要获取图书上的所有订单,代码如下

    books=Book.objects.prefetch_related('bookorder_set')

    需要注意的是:在使用`prefetch_related`查找出来的`bookorder_set`建议不要在对它进行任何操作,比如`filter`,不然又会产生N多查询语句

  • 相关阅读:
    封装组件发布到npm上,项目中可以npm install ,使用vue+wwebpack+dotenv搭建项目,.env配置多个环境.这套命令主要是为了封装npm组件(不同环境也许用不到),最简单的搭建没有冗余的代码和依赖(第一步)
    封装组件发布到npm上,项目中可以npm install,这里做一个简单的封装例子(第二步)
    封装组件发布到npm上,项目中可以npm install 然后直接使用(第三步)
    jenkins 搭建
    fastadmin 链接打开新tab页面
    fastadmin 的多表关联查询
    【Linux】Linux下安装node及npm
    在PhpStrom中配置Docker作为本地开发环境
    OpenResty 使用介绍
    TVM:Python 创建 Relay 表达式
  • 原文地址:https://www.cnblogs.com/nihao2/p/12158278.html
Copyright © 2020-2023  润新知