2010-09-02 39 views
13

给定一个id/pks列表,我想生成列表中由索引排序的对象的QuerySetDjango查询集按ID自定义排序

一般情况下我首先:

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

这当然返回的对象,但在模型元排序属性的顺序,我希望得到的pk S的顺序记录在pk_list

最终的结果必须是一个QuerySet对象(不是列表),因为我希望通过有序QuerySet到Django的ModelMultipleChoiceField表单域。

+1

在数据库级别为MySQL,PostgreSQL及:http://blog.mathieu-leplatre.info/django-create-a-queryset-from-a-list-preserving-order.html – Medorator 2014-08-25 06:58:07

回答

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'并自己生成选择列表。 – 2010-09-03 01:49:57

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'并自己生成选择列表。 – 2010-09-03 01:49:37

+0

等待,'order_by ='pk''不起作用? – amirouche 2012-09-26 15:27:24

+1

@amirouche,不,他希望它的顺序完全不同于简单的数字排序。 – LarrikJ 2012-12-26 19:37:54