在 for 循环之后对查询集进行排序

MHB*_*MHB 0 python django django-queryset

我想对查询集中的所有对象应用一种方法,然后对它们进行排序。

products = Product.objects.all()
for product in products:
    product.update_exist_flag()

products = products.order_by('-exist_flag')
Run Code Online (Sandbox Code Playgroud)

它会引发此错误:

AssertionError:获取切片后无法重新排序查询。

我该如何修复它?

Dip*_*iya 5

您可能想阅读:当查询集被评估时

for product in products::这里查询的gets evaluated是数据库中的ie数据。此后,您无法对查询重新排序。


理想情况下,您应该再次执行相同的查询:

products = Product.objects.all()

for product in products:
    product.update_exist_flag()

products = Product.objects.all().order_by('-exist_flag')
Run Code Online (Sandbox Code Playgroud)

然而,有一个技巧可以做到这一点,而无需再次执行相同的查询(不接触数据库):

products = Product.objects.all()

for product in products:
    product.update_exist_flag()

# This will return a list.
products = sorted(products, key=lambda p: p.exist_flag, reverse=True)    
Run Code Online (Sandbox Code Playgroud)

正如@heemayl在评论中提到的,如果exist_flag是一个相关对象(数据库表中的条目),那么它将再次访问数据库。在这种情况下,仍然可以进行一种优化,if您想根据exist_flag进行排序id,那么我们可以使用p.exist_flag_id而不是p.exist_flag,这样,它就不会影响数据库。