按模型的属性(而不是字段)对 Django QuerySet 进行排序 [英] Sorting a Django QuerySet by a property (not a field) of the Model
本文介绍了按模型的属性(而不是字段)对 Django QuerySet 进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我的(简化)模型:
class Stop(models.Model):
EXPRESS_STOP = 0
LOCAL_STOP = 1
STOP_TYPES = (
(EXPRESS_STOP, 'Express stop'),
(LOCAL_STOP, 'Local stop'),
)
name = models.CharField(max_length=32)
type = models.PositiveSmallIntegerField(choices=STOP_TYPES)
price = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
def _get_cost(self):
if self.price == 0:
return 0
elif self.type == self.EXPRESS_STOP:
return self.price / 2
elif self.type == self.LOCAL_STOP:
return self.price * 2
else:
return self.price
cost = property(_get_cost)
我的目标:我想按 cost
属性排序.我尝试了两种方法.
My Goal: I want to sort by the cost
property. I tried two approaches.
Stops.objects.order_by('cost')
这产生了以下模板错误:
That yielded the following template error:
Caught FieldError while rendering: Cannot resolve keyword 'cost' into field.
使用 dictsort 模板过滤器
{% with deal_items|dictsort:"cost_estimate" as items_sorted_by_price %}
收到以下模板错误:
Caught VariableDoesNotExist while rendering: Failed lookup for key [cost] in u'Union Square'
所以...
我应该怎么做?
推荐答案
使用 QuerySet.extra()
与 CASE ... END
一起定义一个新字段,并对其进行排序.
Use QuerySet.extra()
along with CASE ... END
to define a new field, and sort on that.
Stops.objects.extra(select={'cost': 'CASE WHEN price=0 THEN 0 '
'WHEN type=:EXPRESS_STOP THEN price/2 WHEN type=:LOCAL_STOP THEN price*2'},
order_by=['cost'])
那个,或者将从其余部分返回的 QuerySet
转换为列表,然后在其上使用 L.sort(key=operator.attrgetter('cost'))
.
That, or cast the QuerySet
returned from the rest to a list, then use L.sort(key=operator.attrgetter('cost'))
on it.
这篇关于按模型的属性(而不是字段)对 Django QuerySet 进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文