如何对Django模型对象的字母数字列表进行排序
我正在尝试把在如何在Python中对字母数字集合排序这个问题中的答案,移植到Django中。我有一个通过查询返回的Django模型实例的列表,但我不知道怎么用lambda来构建一个优雅(或者其他方式的)排序函数。
如果我的模型里有一个叫做'name'的属性,比如说:
result = Take.objects.all()
for i in result:
print i.name
我该如何根据这个'name'属性对结果列表进行排序,并进行一些测试呢?
也就是说,我的名字值可能是'1A'、'1'、'A1'、'001A'等等。
例如,按照名字来给出这样的排序:
1A
2A
10A
A1
A2
A10
A11
B2
B4
3 个回答
-1
试试这个:
result = Take.objects.order_by('name')
for x in result:
print x
不过,你提到的排序方式并不是我所理解的正常字母数字(字典序)排序。实际上,它应该是:
10A
1A
2A
A1
A10
A11
A2
B2
B4
如果你真的想要你指定的那种排序方式,你就得想点别的办法了。
0
我遇到过类似的问题,我试着用一种相似的方式来排序一个查询集,虽然我使用了一个自定义的函数来完成这个排序。
比如说,排序的结果是这样的:
1AreaDesk.
2-1-1Desk.
10AreaDesk.
AreaDesk.
Desk1
我发现使用Django中的Lower函数可以得到相同的结果。这个函数的作用是把字符串转换成小写。
例如:
Model.objects.filter(**filter_query).order_by(Lower("attribute_name")
5
使用 operator.attrgetter
可以根据对象的某个属性值来排序你的对象:
import operator
class Foo:
def __init__(self, name):
self.name = name
l = [Foo('AA'), Foo('a'), Foo('AB')]
l.sort(key=operator.attrgetter('name'))
print [o.name for o in l]
['AA', 'AB', 'a']
这里还有一个我提供的答案,里面定义了一个函数,可以按照“人类”能理解的顺序进行字母数字排序。把 _human_key
函数合并到上面的例子中,你可以这样做:
l.sort(key=lambda x: _human_key(x.name))
print [o.name for o in l]
['a', 'AA', 'AB']