2010-01-06 2 views
2

Рассмотрим этот пример модели:Сортировка по отображения названия вместо фактического значения

MODEL_CHOICES = ( (U "спам", и "Спам"), (и "XOUP", и "Eggsoup") , )

(надрез)

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

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

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

Что-то вдоль линий:.

документов = MyModel.objects.filter (...) order_by ("тип")

Однако [query-set].order_by([field]) только позволяет сортировать по имени поля , что приведет к SPAM < XOUP (к машине), хотя Eggsoup < Спам (для читателя).

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

Имя | Тип

obj1 | СПАМ

obj2 | СПАМ

obj3 | СПАМ

obj4 | XOUP

obj5 | XOUP

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

Имя | Тип

obj1 | Спам

obj2 | Спам

obj3 | Спам

obj4 | Eggsoup

obj5 | Eggsoup

Который в глазах человека не отсортирован правильно.

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

ответ

4

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

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

Спасибо. Использование оператора выглядит превосходно, я не знал об этом. – nikola

0

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

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 has a nice example сортировки списка кортежей на втором элементе.

+0

Марк, спасибо за ваш ответ. Однако речь идет не о порядке сортировки вариантов, а о порядке результатов. Я уточнил исходный вопрос, чтобы прояснить суть. – nikola

+0

Мне все еще не ясно, откуда вы получаете отображаемое имя. Это часть модели? –

+0

Это функция Django - когда вы определяете выбор в виде двух кортежей, первый элемент становится фактическим значением, хранящимся в таблице, а второй элемент является отображаемым именем, которое, например, используется в администраторе или при создании форм из модели. См. Здесь: http://www.djangoproject.com/documentation/models/choices/ – nikola