Django QuerySet按ID自定义排序

时间:2010-09-02 09:10:23

标签: python django django-queryset

给定一个id / pks列表,我想生成列表中索引排序的QuerySet个对象。

通常我会先:

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

这当然会返回对象,但是按照模型元排序属性的顺序,我希望按pkpk_list的顺序获取记录。

最终结果必须是一个 QuerySet对象(不是列表),因为我希望将有序的QuerySet传递给Django的ModelMultipleChoiceField表单字段

2 个答案:

答案 0 :(得分:10)

没有内置方法可以做到这一点。

如果您正在使用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 :(得分: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并在渲染时添加自定义排序逻辑。