Django QuerySet Индивидуальный заказ по ID - PullRequest
15 голосов
/ 02 сентября 2010

Учитывая список идентификаторов / пакетов, я хотел бы сгенерировать QuerySet объектов, упорядоченных по индексу в списке.

Обычно я бы начал с:

pk_list = [5, 9, 2, 14]
queryset = MyModel.objects.filter(pk__in=pk_list)

Это, конечно, возвращает объекты, но в порядке свойства упорядочения метаданных моделей, и я хочу получить записи в порядке pk s в pk_list.

Конечный результат должен быть один QuerySet объект (не список), так как я хочу передать упорядоченный QuerySet в поле формы ModelMultipleChoiceField Джанго.

Ответы [ 2 ]

10 голосов
/ 02 сентября 2010

Нет встроенного способа сделать это.

Если вы используете MySQL, вы можете использовать функцию FIELD() этой базы данных, чтобы настроить последовательность заказа в вашей модели, исортировать по этому.Это будет работать:

pk_list = [5, 9, 2, 14]
ordering = 'FIELD(`id`, %s)' % ','.join(str(id) for id in pk_list)
queryset = MyModel.objects.filter(pk__in=[pk_list]).extra(
               select={'ordering': ordering}, order_by=('ordering',))
1 голос
/ 02 сентября 2010

Я не знаю, как сделать это с помощью условия фильтра. Если ваша база данных будет возвращать строки в порядке предложения IN, тогда вы сможете комбинировать метод Django extra с ROWNUM, предоставленным вашей базой данных, для достижения этого.

Например ::100100

queryset = MyModel.objects.filter(pk__in=[pk_list]).extra(
       select: {'rownum': 'row_num()'}).order_by('rownum')

Где row_num() предполагается как функция базы данных, которая возвращает номер строки текущей строки. Postgresql 8.4+ поддерживает row_num(), но я не знаю, как упорядочить строки, возвращенные в том же порядке, что и значения в предложении IN.

Я думаю, что лучше было бы использовать подкласс ModelMultipleChoiceField и добавить собственную логику сортировки при рендеринге.

...