我将Django对象设置为:
class Example(models.Model):
count = models.CharField(default="0")
因此,如果我有一些对象ex1
,ex2
,ex3
,ex4
,其计数分别为-1、0、5,-6。我希望能够查询对象并将它们按[0, 5, -6, -1]
的顺序进行排序,其中任何零先出现,然后是正数,然后是负数,同时每个部分也按升序排列。我当时正在考虑使用类似Example.objects.order_by('count')
的东西,但是找不到一种使用诸如this这样的自定义函数的方法。
我正在寻找的另一条路线如下:
objs = Example.objects.all()
sorted_objs = sorted(objs, key = lambda o: int(o.count))
有没有一种方法可以使用sorted方法首先对零进行排序?我找不到一个。
我使用的最后一种方法是:
objs = Example.objects.all()
zero_objs = []
positive_objs = []
negative_objs = []
for obj in objs:
if obj.count == 0:
zero_objs.append(obj)
elif obj.count < 0:
negative_objs.append(obj)
else:
postitive_objs.append(obj)
sorted_objs = zero_objs + sorted(postitive_objs) + sorted(negative_objs)
这可行,但似乎并不是实现此目的的最佳方法,因此任何想法都很棒。附带说明一下,我知道count属性最好存储为整数字段,但是我想在保留char字段的同时完成此操作。
答案 0 :(得分:3)
您可以使用case
添加新字段以进行订购:
>>> from django.db.models import Case, IntegerField, Value, When
>>> Example.objects.annotate(
... o=Case(
... When(count=0, then=Value(0),
... When(count__gt=0, then=Value(1)),
... When(count__lt=0, then=Value(2)),
... output_field=IntegerField(),
... ),
... ).order_by('o', 'count')
说明:
Order子句将由以下两者组成:“新字段” count
。使用“新字段”,您可以将count = 0的行集提高到顶部,然后在最后一组负数处集正数。第二个字段count
对每个集合进行升序排序。
免责声明:
请注意,这不是索引友好的解决方案!如果需要性能,则只需在模型上创建此新字段,然后在保存之前先弄清楚该字段。