2017-01-11 35 views
1

我看着這個thread,用排序字典的例子。上下文排序字典Django

我有一個程序對象的字典,其中的關鍵是一個程序對象,該值是查找相關的項目對象的數量。

def DepartmentDetail(request, pk): 
    department = Department.objects.get(pk=pk) 
    programmes = Programme.objects.all().filter(department=department).exclude(active=False).order_by('long_name') 
    combi = {} 
    for p in programmes: 
     prj = Project.objects.all().filter(programme=p) 
     combi[p] = str(len(prj)) 
    return render(request, 'sysadmin/department.html',{'department': department, 'programmes': programmes, 'combi': sorted(combi.items())}) 

在模型中,程序返回一個字符串'long_name',所以我相信我正在嘗試對字符串鍵和字符串值進行排序。

在模板中我得到的鑰匙和價值觀,因此,

{% for programme, n in combi %} 

這給我的錯誤..

unorderable types: Programme() < Programme() 

我真的不理解錯誤,在python 3 documentation它聲明sorted()方法接受任何可迭代 - 那麼爲什麼會發生這種情況呢?

我在尋找collections.OrderedDict來解決問題,但我想知道爲什麼這不起作用。

Thanx。

回答

3

具有列索引的數據庫非常擅長排序。幾乎從不需要在客戶端進行排序。你幾乎可以在服務器上做到這一點。它很有趣的部分,你顯然也知道如何做到這一點。

....exclude(active=False).order_by('long_name') # <--- this 

你猜怎麼着,你的數據已經排序沒有必要裏面蟒蛇再次排序呢!

但是在你的代碼中有一個更大的問題。您正在獲取一組Project項目,然後循環遍歷該組以逐個檢索它們。因此,如果您有200個Project項目,那麼當一個查詢執行該任務時,您正在執行200個查詢。根據您與哪個方向有關係,只需添加select_relatedprefetch_related

您的代碼理想情況下應該是這樣的

department = Department.objects.get(pk=pk) 
    programmes = Programme.objects.all().filter(department=department).exclude(active=False).order_by('long_name') 
    return render(request, 'sysadmin/department.html',{'department': department, 'programmes': programmes,}) 

至於我能看到兩用只包含複製數據。同樣的事情可以從programmes例如。 programme.project_set.all() (這同樣取決於你的關係,你的模型沒有顯示哪個方向)

推薦閱讀:https://docs.djangoproject.com/en/1.10/ref/models/fields/#django.db.models.ForeignKey

+0

我正在查找相關的項目服務器端(因爲它是我能想到的唯一方法),你是否建議我做客戶端?如果是的話,那麼正確的方法是什麼? – Xeberdee

+0

剛纔看到combi值實際上是什麼,看起來好像添加一個'annotate(project_count = Count('project'))'將是必需的 – Sayse

+0

請參閱更新 – e4c5

0

的問題是,sorted希望的方式可以訂購的項目和默認沒有辦法知道如何訂購您的物品。你可以提供一個密鑰

sorted(combi.items(), key=lambda i: i.long_name) 
+0

雖然這可能會修復「無法編譯的類型」錯誤,但您應該使用[e4c5的解決方案](http://stackoverflow.com/a/41586684/1324033) – Sayse