这似乎是Django简单的事情,想知道是否有人有任何经验。
我有一张乐队表,其中一些被称为'The Geeks'(例如)。我希望它们在'G'下按字母顺序显示。
我知道我可以做一些花哨的SQL来动态地重写它们并按照那种方式进行排序,但是Django是否提供了内置的任何东西,所以我可以保留我的漂亮的Band.objects.all()
语法并仍然可以过滤自定义排序?
我知道我可以将我的数据更改为包含has_prefix
字段或其他内容,并将带名称存储为“Geeks,The”或其他任何内容,但如果可能的话,我宁愿不触及数据本身。
有小费吗?
你不能用order_by()
做到这一点
您可以
以下是我在最近的Django项目中的表现:
from django.db import models
SomeClass(models.Model):
title = models.CharField()
@property
def alphabetical_title(self):
"""
Returns an alphabetical-friendly string of a title attribute.
"""
title = self.title
# A list of flags to check each `title` against.
starts_with_flags = [
'the ',
'an ',
'a '
]
# Check each flag to see if the title starts with one of it's contents.
for flag in starts_with_flags:
if title.lower().startswith(flag):
# If the title does indeed start with a flag, return the title with
# the flag appended to the end preceded by a comma.
return "%s, %s" % (title[len(flag):], title[:len(flag)-1])
else:
pass
# If the property did not return as a result of the previous for loop then just
# return the title.
return self.title
由于这是一个属性而不是数据库中的实际列,我需要先检索一个QuerySet,然后在视图中对事实进行排序。这是我如何做到的:
from operator import attrgetter
from someapp.models import SomeClass
some_objects = SomeClass.objects.all()
sorted_objects = sorted(some_objects, key=attrgetter('alphabetical_title'), reverse=False)
我相信你早就找到了一个解决方案,但我认为它可能有助于发布它,因为将来其他人可能遇到同样的问题。
使用上面的模型和一些提示(通过respondcreate),以及this answer的改编,我想出了以下一行方法:
mysortedlist = sorted([x for x in SomeClass.all()],
key=lambda y: re.sub("^(the|a|an) ","",y.title.lower()) )
这将从QuerySet生成一个列表,并根据lambda函数对其进行排序,该函数替换标题的小写版本的开头处的a,a和a。