2010-09-02 42 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