Django原始查询的执行次数超出预期
我在Django中完成了一个原始sql查询,并进行了一个测试,以确保执行的查询数减少到1。问题是,我检查返回对象的迭代会触发对该原始查询的重复调用Django原始查询的执行次数超出预期,django,django-orm,Django,Django Orm,我在Django中完成了一个原始sql查询,并进行了一个测试,以确保执行的查询数减少到1。问题是,我检查返回对象的迭代会触发对该原始查询的重复调用 class CategoryManager: .... @staticmethod def get_by_popularity(): return Category.objects.raw( """.........""" ) class CategoryManagerTestCase( TestCa
class CategoryManager:
....
@staticmethod
def get_by_popularity():
return Category.objects.raw( """.........""" )
class CategoryManagerTestCase( TestCase ):
....
with self.assertNumQueries( 1 ):
categories = CategoryManager.get_by_popularity( )
for c in categories:
if c.name == root_cat.name:
self.assertEqual( c.visitors_count, 14 )
# when I add this second iteration the query gets executed a second time
for c in categories:
self.assertTrue( hasattr( c, 'id' ) )
self.assertTrue( hasattr( c, 'name' ) )
self.assertTrue( hasattr( c, 'parent_id' ) )
self.assertTrue( hasattr( c, 'description' ) )
self.assertTrue( hasattr( c, 'visitors_count' ) )
self.assertTrue( hasattr( c, 'projects_count' ) )
不幸的是,原始查询是错误的 而RawQuerySet实例可以像普通实例一样进行迭代 QuerySet、RawQuerySet并没有实现您可以使用的所有方法 QuerySet。例如,bool()和len()未在中定义 RawQuerySet,因此所有RawQuerySet实例都被认为是真的。 这些方法没有在RawQuerySet中实现的原因是 在没有内部缓存的情况下实现它们将是一种性能提升 缺点和添加这样的缓存将是向后不兼容的
不幸的是,原始查询是错误的 而RawQuerySet实例可以像普通实例一样进行迭代 QuerySet、RawQuerySet并没有实现您可以使用的所有方法 QuerySet。例如,bool()和len()未在中定义 RawQuerySet,因此所有RawQuerySet实例都被认为是真的。 这些方法没有在RawQuerySet中实现的原因是 在没有内部缓存的情况下实现它们将是一种性能提升 缺点和添加这样的缓存将是向后不兼容的
如果将结果转换为列表,则将阻止附加查询:
categories = list(CategoryManager.get_by_popularity())
或者,您可能希望从方法返回列表:
@staticmethod
def get_by_popularity():
return list(Category.objects.raw( """.........""" ))
如果查询是Category.objects.filter(…)
而不是raw,那么多次循环查询集只会导致获取一次
但是,Django不会缓存原始查询集的结果。该警告表明,由于向后兼容的原因,未添加缓存
虽然可以像普通的QuerySet
一样迭代RawQuerySet
实例,RawQuerySet
并没有实现所有可用于QuerySet
的方法。例如,RawQuerySet
中未定义\uuuuu bool\uuuuu()
和\uuu len\uuuuu()
,因此所有RawQuerySet
实例都被视为True
。这些方法没有在RawQuerySet
中实现的原因是,在没有内部缓存的情况下实现它们将是一个性能缺陷,添加这样的缓存将是向后不兼容的
如果将结果转换为列表,则将阻止附加查询:
categories = list(CategoryManager.get_by_popularity())
或者,您可能希望从方法返回列表:
@staticmethod
def get_by_popularity():
return list(Category.objects.raw( """.........""" ))
如果查询是Category.objects.filter(…)
而不是raw,那么多次循环查询集只会导致获取一次
但是,Django不会缓存原始查询集的结果。该警告表明,由于向后兼容的原因,未添加缓存
虽然可以像普通的QuerySet
一样迭代RawQuerySet
实例,RawQuerySet
并没有实现所有可用于QuerySet
的方法。例如,RawQuerySet
中未定义\uuuuu bool\uuuuu()
和\uuu len\uuuuu()
,因此所有RawQuerySet
实例都被视为True
。这些方法没有在RawQuerySet
中实现的原因是,在没有内部缓存的情况下实现它们将是一个性能缺陷,添加这样的缓存将是向后不兼容的
如果将结果转换为
列表
,则将阻止附加查询:categories=list(CategoryManager.get\u by\u popularity()
有效。知道是什么引起的吗?能否将其添加为答案,以便我可以将其标记为已接受?如果将结果转换为列表
,您将阻止附加查询:categories=list(CategoryManager.get\u by\u popularity()
行得通。你知道是什么原因导致的吗?你能把它添加为一个答案,这样我就可以将它标记为已接受吗?因为向后不兼容而不支持非常重要的东西是疯狂的。因为向后不兼容而不支持非常重要的东西是疯狂的。