Сортировать по отображаемому имени вместо фактического значения - PullRequest
2 голосов
/ 06 января 2010

Рассмотрим этот пример модели:

MODEL_CHOICES = ( («СПАМ», «СПАМ»), (у "XOUP", у "Eggsoup"), )

(надрез)

type = models.CharField (max_length = 4, выбор = MODEL_CHOICES)

(Фактическая реализация зависит от предметной области и не на английском языке, так что этот пример должен.)

При построении запроса я хотел бы отсортировать результаты по полю этого типа и представить результаты пользователю. Естественно, я бы хотел отсортировать по отображаемому имени этого поля.

Что-то вроде:

documents = MyModel.objects.filter (...). Order_by ("тип")

Однако [query-set].order_by([field]) разрешает сортировку только по имени поля, что приведет к СПАМ

Рассмотрим этот набор экземпляров, отсортированных по типу:

Имя | Тип

obj1 | SPAM

obj2 | SPAM

obj3 | SPAM

obj4 | XOUP

obj5 | XOUP

Но это будет порядок, который увидит пользователь, то есть пользователь увидит отображаемое имя, а не значение внутреннего поля столбца типа:

Имя | Тип

obj1 | Спам

obj2 | Спам

obj3 | Спам

obj4 | Eggsoup

obj5 | Eggsoup

Что в глазах человека-пользователя неправильно отсортировано.

Есть ли в Django функция, позволяющая сортировать по отображаемому имени? Или способ сделать это "вручную"? (Переименование вариантов выбора, чтобы отображаемое имя имело тот же порядок, что и фактические значения, не допускается.)

Ответы [ 2 ]

4 голосов
/ 06 января 2010

Если наборы результатов достаточно малы, вы можете выполнить сортировку результатов в памяти в коде. Я не могу придумать какой-либо достойный способ сортировки результатов на уровне базы данных. Конечно, это было бы возможно, если бы вы использовали хранимую процедуру, которая знает отображаемые имена, однако вам пришлось бы писать raw sql. Что касается ручной сортировки, вы можете использовать что-то вроде этого:

obj_list = list(Model.objects.all())
import operator
obj_list.sort(key=operator.methodcaller('get_foo_display'))

Вот несколько хороших примеров того, как сортировать списки в Python: http://wiki.python.org/moin/HowTo/Sorting

0 голосов
/ 06 января 2010

Предполагая, что отображаемое имя также исходит от модели, вы можете отсортировать по этому полю, чтобы упорядочить нужные вам варианты.

MODEL_CHOICES = MyModel.objects.all().values_list('value_field', 'display_field').order_by('display_field')
...
type = models.CharField(max_length=4, choices=MODEL_CHOICES)

Если выбор является константой, как в вашем вопросе, то вы можете просто изменить порядок в константе.

MODEL_CHOICES = ((u"XOUP", u"Eggsoup"), (u"SPAM", u"Spam"), )

В конце концов, выбор - это просто список кортежей, так что вы можете сортировать с помощью обычной сортировки Python. В Python wiki есть хороший пример сортировки списка кортежей по второму элементу.

...