博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
084:QuerySet API详解prefetch_related方法
阅读量:6875 次
发布时间:2019-06-26

本文共 2185 字,大约阅读时间需要 7 分钟。

QuerySet API详解prefetch_related方法:

prefetch_related :这个方法和 select_related 非常的类似,就是在访问多个表中的数据的时候,减少查询的次数。这个方法是为了解决 多对一 和 多对多 的关系的查询问题。比如要获

取标题中带有 hello 字符串的文章以及他的所有标签,示例代码如下:

from django.db import connectionarticles = Article.objects.prefetch_related("tag_set").filter(title__contains='hello')print(articles.query) # 通过这条命令查看在底层的SQL语句for article in articles:  print("title:",article.title)  print(article.tag_set.all())# 通过以下代码可以看出以上代码执行的sql语句
print(connection.queries)

但是如果在使用 article.tag_set 的时候,如果又创建了一个新的 QuerySet 那么会把之前的 SQL 优化给破坏掉。比如以下代码:

tags = Tag.obejcts.prefetch_related("articles")for tag in tags:  articles = tag.articles.filter(title__contains='hello') #因为filter方法会重新生成一个QuerySet,因此会破坏掉之前的sql优化# 通过以下代码,我们可以看到在使用了filter的,他的sql查询会更多,而没有使用filter的,只有两次sql查询
print(connection.queries)

那如果确实是想要在查询的时候指定过滤条件该如何做呢,这时候我们可以使用 django.db.models.Prefetch 来实现, Prefetch 这个可以提前定义好 queryset 。示例代码如下:

tags = Tag.objects.prefetch_related(Prefetch("articles",queryset=Article.objects.filter(title__contains='hello'))).all()for tag in tags:  articles = tag.articles.all()  for article in articles:    print(article)
print(connection.queries)

因为使用了 Prefetch ,即使在查询文章的时候使用了 filter ,也只会发生两次查询操作。

实例代码和截图:

# books = Book.objects.all()    # books = Book.objects.prefetch_related("bookorder_set")    # for book in books:    #     print("#"*30)    #     print(book.name)    #     orders = book.bookorder_set.all()    #     for order in orders:    #         print(order.id)    # books = Book.objects.prefetch_related("author")    # for book in books:    #     print(book.author.name)    # books = Book.objects.prefetch_related("bookorder_set")    # for book in books:    #     print(book.name)    #     orders = book.bookorder_set.filter(price__gte=90)    #     for order in orders:    #         print(order.id)    prefetch = Prefetch("bookorder_set", queryset=BookOrder.objects.filter(price__gte=90))    books = Book.objects.prefetch_related(prefetch)    for book in books:        print("#"*30)        print(book.name)        orders = book.bookorder_set.all()        for order in orders:            print(order.id)    print(connection.queries)

 

转载于:https://www.cnblogs.com/zheng-weimin/p/10281861.html

你可能感兴趣的文章
jquery利用sort方法对json数据排序
查看>>
要复习内容
查看>>
【Qt笔记】使用流处理 XML
查看>>
指针的使用
查看>>
5-pandas基础运算
查看>>
php判断IP跳转区域二级域名
查看>>
百度webupload--上传图片功能---插件使用
查看>>
Java深、浅克隆(clone)
查看>>
如何在View上不用UIImageView重新绘制一张图片?
查看>>
实现控制器(Controller)
查看>>
好多年前写的一个C++事件回调工具
查看>>
python3使用logging日志记录
查看>>
servlet3中jar的web资源携带
查看>>
3D打印将对零售模式产生颠覆影响,能否抓住机遇
查看>>
不用加减乘除实现加法
查看>>
Android SD卡 文件或目录拷贝、复制、粘贴
查看>>
git命令与github使用(转主要看向远程仓库推内容)
查看>>
JAVA生成四位数的验证码
查看>>
讯飞语音错误码大全
查看>>
编译器错误消息: CS0433: The type 'global_asax' exists in both 'App_global.asax
查看>>