Python 按动态添加的字段对Django QuerySet重新排序
have代码段,它从数据库中获取一些查询集,然后将新的计算字段附加到查询集中的每个对象。不能通过注释添加此字段(因为它是遗留的,并且此计算基于另一个已预取的数据) 像这样:Python 按动态添加的字段对Django QuerySet重新排序,python,django,django-queryset,Python,Django,Django Queryset,have代码段,它从数据库中获取一些查询集,然后将新的计算字段附加到查询集中的每个对象。不能通过注释添加此字段(因为它是遗留的,并且此计算基于另一个已预取的数据) 像这样: from django.db import models class Human(models.Model): name = models.CharField() surname = models.CharField() def calculate_new_field(s): return len(s
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中的所有人都有了一个新专栏。我想按新列字段对这些对象进行排序order_by()
显然不起作用,因为它是一个数据库选项。我知道我可以将它们作为一个排序列表传递,但是有很多模板和其他逻辑,它们期望从这个对象QuerySet获得像interface一样的方法等等
所以问题是:是否有一些不太坏和肮脏的方法通过添加字段重新排序现有的QuerySet,或者用这些数据创建新的类似QuerySet的对象?我相信我不是唯一一个面对这个问题的人,而且这个问题已经通过django解决了。但是我找不到任何东西(除了添加第三方LIB,这也不是一个选项)。你能试试吗:
从概念上讲,查询集不是结果列表,而是“获取这些结果的说明”。它被惰性地计算和缓存。保存缓存结果的查询集的内部属性是
qs.\u result\u cache
因此,people中s的语句强制执行查询的求值并缓存结果
之后,您可以通过执行以下操作对结果进行排序:
people.\u result\u cache.sort(key=attrgetter('new\u column'))
但是,在评估QuerySet之后,保留QuerySet接口(在我看来)没有什么意义,因为许多操作都会导致重新评估查询。从这一点开始,你应该处理一个模型列表实际上,我不是按长度排序列,而是计算出的百分比。我只是用长度来表示,添加的列基本上只是一个经过计算的数字。很抱歉,我误导了你们。你们可以看到,你们可以把计算添加到注释中,并将其用于订单,试着显示你们的真实代码
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')