2010-09-02 7 views
13

Учитывая список идентификаторов/pks, я хотел бы создать QuerySet объектов, упорядоченных по индексу в списке.Django QuerySet Пользовательский заказ по ID

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

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

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

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

+1

На уровне БД для MySQL и PostgreSQL: http://blog.mathieu-leplatre.info/django-create-a-queryset-from-a-list-preserving-order.html – Medorator

ответ

1

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

В .: например

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 и добавления пользовательской логики сортировки при рендеринге.

+0

Спасибо за это, но мне нужно что-то, что будет совместимо с sqlite и mysql. Я думаю, что поеду с помощью «MultipleChoiceField» и самостоятельно создав список вариантов. –

7

Существует не встроенный способ сделать это.

Если вы используете 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',)) 
+0

Спасибо за это, но мне нужно что-то, что будет совместимо как с sqlite, так и с mysql. Я думаю, что поеду с помощью «MultipleChoiceField» и самостоятельно создав список вариантов. –

+0

wait, 'order_by = 'pk'' не работает? – amirouche

+1

@amirouche, он не хочет этого в порядке, отличном от простого численного сортировки. – LarrikJ

Смежные вопросы