【发布时间】:2016-09-23 15:50:32
【问题描述】:
所以我试图将一个临时属性添加到来自同一模型的两个单独的 QuerySet,但似乎一旦我尝试将它们合并在一起,新字段就会消失。
例子:
class IndexView(View):
def get(self, request):
q1 = MyModel.objects.filter(points=0)
q2 = MyModel.objects.filter(points=100)
for q in q1:
q.title = 'Loser'
print(q.title) # Prints 'Loser'
for q in q2:
q.title = 'Winner'
print(q.title) # Prints 'Winner'
q = q1 | q2 # Merges the two QuerySets together
for item in q:
print(item.title) # ERROR: "Title" is not a field anymore apparently...
return render(request, 'index.html', {})
我尝试了另一种使用.chain()(在另一个线程中提到)的方法,但这会将类型从QuerySet 更改为List,这是我不想要的。我将在下面发布。有没有办法在获得相同结果的同时将列表保留为 QuerySet?请注意,我希望 title 属性是临时的,以便我可以分隔模板中的项目。此外,points 过滤器不是真正的过滤器,实际上要复杂得多,因此模板标签和模型方法不是一个选项。
from itertools import chain
feed = sorted(
chain(q1, q2),
key=lambda instance: instance.created)
Django v1.9.6Python v3.4.3
【问题讨论】:
-
q = q1 | q2这将创建一个全新的查询集,它将选择q1和q2的联合。然后,当您通过q时,您会触发一个新查询并再次从数据库中加载对象。 -
有趣 - 那么是否有替代方法可以避免擦除我定义的临时属性?
-
理想情况下,您可以使用
annotate将这些属性添加为查询本身的一部分,也可以使用Case子句。您甚至不需要两个查询集和合并,只需说明数据库如何自行计算字段。 -
或者,因为这是一个非常简单的计算,所以在模型方法中甚至直接在模板中进行:
{% if q.points == 0 %}loser{else %}winner{% endif %}。同样,您只需要一个查询。 -
@spectras:嗯,我不知道该怎么做。同样,这是示例代码,我的实际代码在过滤过程中使用
GenericRelations到GenericForeignKeys,所以有点太疯狂了。如果这是一个可行的选择,我想了解更多关于注释的信息。
标签: python django list filter django-queryset