2016-02-22 123 views
1

我正在將代碼從Django 1.6移動到1.9。 在1.6我有這個代碼Django 1.9中的query.group_by

models.py

class MyReport(models.Model): 
    group_id = models.PositiveIntegerField(blank=False, null=False) 

views.py

query = MyReport.objects.filter(owner=request.user).query 
query.group_by = ['group_id'] 
entries = QuerySet(query=query, model=MyReport) 

該查詢將返回一個對象爲每個 'GROUP_ID';由於我使用它的方式,任何帶有group_id的表格行都可以作爲代表。

隨着1.9此代碼已損壞。上述第二行後的查詢是:

SELECT "reports_myreport"."group_id", ... etc FROM "reports_myreport" WHERE "reports_myreport"."owner_id" = 1 GROUP BY "reports_myreport"."group_id", "reports_report"."otherfield", ... 

基本上它列出所有表中的字段組中由子句,使得查詢返回整個表。

雖然曾經在調試器中我看到

query.group_by = ['group_by'] 

它看起來並不像query.group_by是在1.9的方法也不限於1.7-1.9的變化記錄表明,事情發生了轉變。

有沒有更好的方法 - 不取決於內部的Django的東西 - 我可以用於我的查詢?

任何方式來解決我當前的查詢?

+0

什麼是與您的MyReport相關的'group_id'?你能向你的模型展示相關的部分嗎? – Sayse

+0

@Sayse'group_id'是模式中的一個簡單字段。我用相關的行編輯了這個問題 – mibm

+0

好吧,我期待它是一個外鍵......你在尋找MyReport.objects.filter(owner = request.user).distinct('group_id')'? – Sayse

回答

0

您可以使用order_by()獲得排序結果,在同一個查詢中,您可以通過第二個條件進行排序。

如果你想獲得組,你需要迭代集合來檢索這些值。

如果你消耗所有查詢返回的結果的話,可以考慮:

一)itertools.groupby其通過代之的內存組,但你不應該將其用於大型數據集。

b)另一種選擇是使用Manager.raw(),但你需要編寫SQL裏面Django的,就像這樣:

for report in MyReport.objects.raw('SELECT * FROM reporting_report GROUP by group_id'): 
    print(report) 

這將爲大型數據集工作,但你可能會失去一些數據庫引擎的兼容性。

紅利:我建議您在重寫之前瞭解舊代碼的確切含​​義。

+0

舊代碼將爲每個group_id返回一個條目(完整的表格行)。無論它是錯誤的工作,現在按照設計工作,我不知道。 你的解決方案應該可以工作,但他們會遇到像你自己提到的問題。我的解決方案(無法獲得'代碼'工作)在上面的評論也適用,但我把查詢作爲遠離理想的組數量... – mibm

+1

顯然,舊的代碼工作是錯誤的。做一個沒有聚合的group_by沒有真正定義。上面的建議(以及我以前的評論中的我自己的建議)工作。在Postgres中,這可以做得更簡單。 – mibm