Порядок сортировки в Django: можно ли игнорировать префикс «The» при сортировке? - PullRequest
2 голосов
/ 19 мая 2011

Это похоже на то, что Джанго делает простым, задаваясь вопросом, есть ли у кого-нибудь опыт работы с ним.

У меня есть таблица групп, некоторые из которых называются «Гики» (например).Я хочу, чтобы они отображались в алфавитном порядке под буквой «G».

Я знаю, что могу сделать какой-нибудь причудливый SQL, чтобы переписать их на лету и отсортировать таким образом, но предлагает ли Django что-нибудь встроенное, чтобы я мог сохранить своеBand.objects.all() синтаксис и все еще фильтр для пользовательской сортировки?

Я знаю, что мог бы изменить свои данные, чтобы включить поле has_prefix или что-то подобное, и сохранить название группы как «Geeks, The» или что-то еще, но я »Не буду прикасаться к самим данным, если это возможно.

Любые советы?

Ответы [ 3 ]

3 голосов
/ 22 августа 2012

Вот как я это сделал в недавнем проекте 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)

Я уверен, что вы уже давно нашли решение, но я подумал, что это может помочь опубликовать его в любом случае, так как кто-то еще в будущем может столкнуться с этой же проблемой.

2 голосов
/ 19 мая 2011

Вы не можете сделать это с order_by()

Вы можете

  1. Сделать какой-нибудь причудливый SQL .Если вы хотите, чтобы он был красивым и коротким, вам следует написать собственный менеджер моделей.
  2. Выполнять сортировку на уровне Python, а не на уровне SQL
  3. Хранить «сортировать заголовок» и «отображать заголовок»"отдельно.
1 голос
/ 16 декабря 2017

Используя модель и пару подсказок из вышеперечисленного (по отклику) и адаптацию этого ответа , я придумал следующий однострочный подход:

mysortedlist = sorted([x for x in SomeClass.all()],
               key=lambda y: re.sub("^(the|a|an) ","",y.title.lower()) )

Это генерирует список из QuerySet и сортирует его в соответствии с лямбда-функцией, которая заменяет, a и a в начале строчной версии заголовка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...