python - values - Django中的ForeignKey形式限制




django菜單 (4)

“有沒有更好的方法來做到這一點? 不是真的。 關係模型中的層次結構很難。 除了完全放棄SQL之外,沒有什麼比這更容易的了。

“通過在pruned_pa​​rent_list中循環來獲取選項,將選擇機制寫入我的模板” - 可能不是最優的。 這應該發生在你看來。

我正在使用Django來編寫一個博客應用程序,我試圖實現一個分層的類別結構。 每個類別有一個“父”ForeignKey指向相同的類別模型。 我想允許管理員添加類別,我希望界面允許他們選擇一個類別的父類別。 但是,我想避免我自己的祖父的情況,所以我想限制可用的類別的選擇,那些沒有問題的類別作為祖先。

現在,我從這個角度來控制它:

parent_candidates = list(Category.objects.all())
pruned_parent_list = [cat for cat in parent_candidates if instance.id not in cat.getHierarchy()]

其中instance是編輯的類別,getHierarchy()是獲取祖先id列表的方法。

這種方法有許多問題。 特別是,它使用額外的數據庫命中來獲取所有類別的列表,這使得我通過在pruned_pa​​rent_list中循環來獲取選項來將選擇機制寫入到我的模板中,當我真的只是指定一個小部件。

有沒有更好的方法來做到這一點? 我知道我可以在後端添加自定義驗證,以防止這種情況,但為什麼給用戶的選擇?


如果我正確地理解你的困境,問題本身就在於你處理哪些類別可以是父母,哪些不能。 避免這些問題的一個選擇是實際限制可以成為父母的類別的級別。 例如,假設您有以下類別:

  • 互聯網
    • 谷歌
    • 雅虎
  • 離線
    • 微軟Office
    • 開發辦公室

我通常處理這個的方式顯然是在類別表上有一個parent_id FK。 對於根元素(Internet,Offline),parent_id將為0.因此,在您的視圖中,當您嘗試檢索下拉菜單的“父類別”時,您需要確定它們能夠保持嵌套的程度。 我主要將其限制在第一級,因此要選擇在下拉列表中顯示哪些類別,請執行以下操作:

parents = Category.objects.filter(parent_id=0)

現在很明顯,這個方法在一定程度上限制了這個方法,但是你可以增加你想要包含的級別,並且在你的模板中為下拉列表制定一些視覺識別系統(包括層次結構中每個級別的額外空格或破折號) )。

無論如何,對於長期的回應感到抱歉,希望這有點解決你的問題。


我不得不在SQL上處理任意深度的類別,因為嵌套查詢和/或多個JOIN往往會變得非常快,所以它似乎不適合以普通形式存儲這種類型的數據。

這幾乎是唯一的情況下,我會去與一種不正確的解決方案,即存儲類別的字符串形式,子分類由分隔符分隔。 它使數據庫查詢和其他操作變得更加微不足道。

分類表看起來像這樣:

id    name
1     Internet
2     Internet/Google
3     Internet/Yahoo
4     Offline
5     Offline/MS Office/MS Excel
6     Offline/Openoffice

另一個解決方案是,根據您的預期使用情況,您可以在類別列表中實現二叉樹。 這允許優雅地選擇分類樹和父/子關係。 然而,它的局限性是,在插入新的類別時,可能需要重新計算整個樹,並且事先知道樹的近似大小是有用的。

無論如何,SQL中的分層數據本身並不是微不足道的,所以,不管你做什麼,你都可能需要做一些自定義編碼。








django-forms