2013-01-14 113 views
0

對於一個項目庫,用戶可以手動排序某些項目以始終使它們首先顯示。Django模型queryset使用.extra()或union來在PositiveIntegerField上應用自定義排序

對於該模型有一個「排序」不爲null PositiveIntegerField(默認爲0)。與排序字段項大於零,手動排序,並在0

之前排序值沒有排序項就必須出現可以使用可能是這樣的SQL查詢:

(select photo, sort, 0 as priority from photos where sort > 0) 
union all 
(select photo, sort, 1 as priority from photos where sort = 0) 
order by priority, sort 

結果將外觀像:

+---------+------+----------+ 
| photo | sort | priority | 
+---------+------+----------+ 
| photo-a | 1 | 0  | 
| photo-b | 2 | 0  | 
| photo-c | 0 | 1  | 
| photo-d | 0 | 1  | 
| photo-e | 0 | 1  | 
| ...      | 

但我不明白它應該如何正確使用Django Queryset完成?

我能夠合併兩個不同的查詢集與list(chain(q1, q2))但執行查詢,這對大集合是低效的,特別是如果我的查詢集應該被傳遞給django.core.paginator,通常會應用LIMIT OFFSET子句分頁。當然,我可以在每個查詢q1q2上應用切片,但由於它與分頁器的作用重疊,所以這有點難看。

也許我試圖做錯的方式。或者也許它應該用extra()方法完成?

+0

你能詳細解釋爲什麼'Photo.objects.all()。order('sort')'不夠嗎? – scytale

+0

我詳細說明了我的問題,這可能會回答爲什麼降序order_by on是不夠的。 – nrako

回答

1

做的聯合/合併查詢集不是解決方案。更簡單的解決方案是在訂單聲明中使用比較。在stackeoverflow上的answer指出我這個巧妙的解決方案。

select * from photos order by sort=0, sort 

0 = 0被評估爲True,等於1,1 = 0是False等於0等等。

翻譯成Django的查詢集:

Photos.objects.extra(select={'sortiszero': 'sort = 0'}, order_by=['sortiszero', 'sort']) 

結果:

+---------+------+ 
| photo | sort | 
+---------+------+ 
| photo-a | 1 | 
| photo-b | 2 | 
| photo-c | 0 | 
| photo-d | 0 | 
| photo-e | 0 | 
| ...   | 

瞧!

0

你應該提供更多細節。

如果你想工會這兩個集合,你可以簡單地添加名單:

list1 = SomeModel.objects.filter(sort != 0).order_by('column_name_1','column_name_2') 
list2 = SomeModel.objects.filter(sort = 0).order_by('priority','foo') 
return list = list1 + list2 

或者,如果你想使用額外的()方法,這裏是一個的exaple:

list = SomeModel.objects.fooMethod().extra(order_by=[foo,]) 
+0

我提供了更多的細節。關於您的解決方案,我嘗試將兩個Queryset與+操作數連接時出錯。 '不支持的操作數類型爲+:'QuerySet'和'QuerySet'。所以我使用'list(chain(q1,q2))',但是這會在django.core.paginator可以應用切片來應用LIMIT OFFSET子句之前執行查詢。 – nrako

+0

你應該添加列表而不是查詢集: 'p爲p_list: list = Object.objects.filter(point = p) return_list = return_list + list' – arturex

相關問題