Django中的排序顺序:排序时可能忽略“The”前缀?

时间:2011-05-19 11:12:27

标签: django sorting

这似乎是Django简单的事情,想知道是否有人有任何经验。

我有一张乐队表,其中一些被称为'The Geeks'(例如)。我希望它们按字母顺序显示在'G'下。

我知道我可以做一些花哨的SQL来动态地重写它们并按照那种方式进行排序,但是Django是否提供了内置的任何内容,因此我可以保留我的Band.objects.all()语法并仍然可以过滤自定义排序?

我知道我可以将我的数据更改为包含has_prefix字段或其他内容,并将带名称存储为“Geeks,The”或其他任何内容,但如果可能,我宁愿不触及数据本身。

任何提示?

3 个答案:

答案 0 :(得分:3)

以下是我在最近的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)

我确信你早就找到了一个解决方案,但我认为它可能会有所帮助,因为将来其他人可能遇到同样的问题。

答案 1 :(得分:2)

您无法使用order_by()

执行此操作

你可以

  1. Do some fancy SQL。如果你想保持简洁,你应该写一个自定义模型管理器。
  2. 在Python级别进行排序,而不是在SQL级别进行排序
  3. 分别存储“排序标题”和“显示标题”。

答案 2 :(得分:1)

使用上面的模型和一些提示(通过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。