zoukankan      html  css  js  c++  java
  • 表名小写_set.all()再根据字段过滤

    orm - 为什么django的prefetch_related()只能用于all()而不能用于filter()?

    假设我有这个模型:

    class PhotoAlbum(models.Model):
        title = models.CharField(max_length=128)
        author = models.CharField(max_length=128)
    
    class Photo(models.Model):
        album = models.ForeignKey('PhotoAlbum')
        format = models.IntegerField()

    现在,如果我想有效地查看相册子集中的一部分照片。 我这样做:

    someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related("photo_set")
    for a in someAlbums:
        somePhotos = a.photo_set.all()

    这只做了两个查询,这是我所期望的(一个是获得专辑,然后是一个像`SELECT * IN photos WHERE photoalbum_id IN()。

    一切都很棒。

    但如果我这样做:

    someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related("photo_set")
    for a in someAlbums:
        somePhotos = a.photo_set.filter(format=1)

    然后它用WHERE format = 1进行了大量的查询! 我做错了什么或django不够聪明,意识到它已经取出所有的照片并可以在python中过滤它们? 我发誓我在文档中的某个地方读到它本应该这样做......

    2个解决方案
    142 votes

    在Django 1.6及更早版本中,无法避免额外的查询。 prefetch_related呼叫有效地缓存了查询集中每个专辑的filter(spicy=True)的结果。 但是,a.photoset.filter(format=1)是一个不同的查询集,因此您将为每个专辑生成一个额外的查询。

    这在prefetch_related文档中有解释。 prefetch_related相当于filter(spicy=True)

    请注意,您可以通过在python中过滤照片来减少数量或查询:

    someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related("photo_set")
    for a in someAlbums:
        somePhotos = [p for p in a.photo_set.all() if p.format == 1]

    在Django 1.7中,有一个prefetch_related对象,允许您控制prefetch_related的行为。

    from django.db.models import Prefetch
    
    someAlbums = PhotoAlbum.objects.filter(author="Davey Jones").prefetch_related(
        Prefetch(
            "photo_set",
            queryset=Photo.objects.filter(format=1),
            to_attr="some_photos"
        )
    )
    for a in someAlbums:
        somePhotos = a.some_photos
    每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)
  • 相关阅读:
    23.C++- 继承的多种方式、显示调用父类构造函数、父子之间的同名函数、virtual虚函数
    22.C++- 继承与组合,protected访问级别
    LeetCode-391. 完美矩形(使用C语言编译,详解)
    LeetCode-101.对称二叉树
    STM32-对芯片启动读保护,实现加密(详解)
    21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数
    20.C++- "&&","||"逻辑重载操作符的缺陷、","逗号重载操作符的分析
    19.C++-(=)赋值操作符、初步编写智能指针
    18.C++-[ ]操作符使用 、函数对象与普通函数区别(详解)
    ECMAScript 6.0基础入门教程
  • 原文地址:https://www.cnblogs.com/kylin5201314/p/15099597.html
Copyright © 2011-2022 走看看