给定一个id / pks列表,我想生成列表中索引排序的QuerySet
个对象。
通常我会先:
pk_list = [5, 9, 2, 14]
queryset = MyModel.objects.filter(pk__in=pk_list)
这当然会返回对象,但是按照模型元排序属性的顺序,我希望按pk
中pk_list
的顺序获取记录。
最终结果必须是一个 QuerySet
对象(不是列表),因为我希望将有序的QuerySet
传递给Django的ModelMultipleChoiceField
表单字段
答案 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
并在渲染时添加自定义排序逻辑。