有一段代码,它从DB中获取一些QuerySet,然后将新的计算字段附加到查询集中的每个对象。通过注释添加此字段不是一个选项(因为它是遗留的,因为这个计算基于另一个已经预先获取的数据)。
像这样:
from django.db import models
class Human(models.Model):
name = models.CharField()
surname = models.CharField()
def calculate_new_field(s):
return len(s.name)*42
people = Human.objects.filter(id__in=[1,2,3,4,5])
for s in people:
s.new_column = calculate_new_field(s)
# people.somehow_reorder(new_order_by=new_column)
所以现在QuerySet中的所有人都有一个新列。我希望通过new_column字段对这些对象进行排序。 order_by()
显然不起作用,因为它是一个数据库选项。我知道我可以将它们作为一个排序列表传递,但是有很多模板和其他逻辑,它们希望从这个对象开始使用类似QuerySet的方法等等。
所以问题是:是否有一些非常糟糕和肮脏的方法通过dinamically添加字段重新排序现有QuerySet或使用此数据创建新的类QuerySet对象?我相信我不是唯一一个遇到这个问题的人,而且已经用django解决了。但我找不到任何东西(除了添加第三方库,这也不是一个选项)。
答案 0 :(得分:0)
你能试试functions.Length:
from django.db.models.functions import Length
qs = Human.objects.filter(id__in=[1,2,3,4,5])
qs.annotate(reorder=Length('name') * 42).order_by('reorder')
答案 1 :(得分:0)
从概念上讲,QuerySet不是结果列表,而是"指令来获取这些结果"。它被懒惰地评估并缓存。保存缓存结果的QuerySet的内部属性为Command+Option+Shift+K
因此,qs._result_cache
句子强制评估查询并缓存结果。
之后,您可以通过执行以下操作对结果进行排序:
for s in people
但是,在评估QuerySet之后,(在我看来)保留QuerySet接口没有多大意义,因为许多操作都会导致重新评估查询。从这一点开始,您应该处理模型列表