4

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 をループしてオプションを取得することで、選択メカニズムをテンプレートに書き込む必要があります。

これを行うより良い方法はありますか?これを防ぐためにバックエンドにカスタム検証を追加できることは知っていますが、なぜユーザーにオプションを提供するのでしょうか?

4

5 に答える 5

1

SQL で任意の深さのカテゴリを処理する必要がありましたが、ネストされたクエリや複数の JOIN が非常に急速に醜くなる傾向があるため、このタイプのデータを通常の形式で格納するのにはあまり適していないようです。

これは、私が一種の不適切な解決策を採用するほとんど唯一のケースです。つまり、カテゴリを文字列形式で格納し、サブカテゴリを区切り記号で区切って保存します。これにより、データベース クエリとその他の操作の両方がより簡単になります。

カテゴリ テーブルは次のようになります。

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

別の解決策は、予想される使用方法に応じて、カテゴリ リストにバイナリ ツリーを実装できることです。これにより、カテゴリ ツリーと親子関係をエレガントに選択できます。ただし、新しいカテゴリを挿入すると、ツリー全体を再計算する必要があり、ツリーのおおよそのサイズを事前に知っておくと便利です。

いずれにせよ、SQL の階層データはそれ自体が簡単ではないため、何をするにしても、かなりのカスタム コーディングを行う必要があります。

于 2008-12-31T08:20:45.420 に答える
1

django-treebeardアプリを見てください。

于 2009-01-02T13:09:01.300 に答える
0

私があなたの苦境を正しく理解しているなら、問題自体は、どのカテゴリーが親になることができ、どのカテゴリーができないかをあなたがどのように扱っているかにあります。これらの問題を回避するための1つのオプションは、親になることができるカテゴリのレベルを実際に制限することです。たとえば、次のカテゴリがあるとします。

  • インターネット
    • グーグル
    • Yahoo
  • オフライン
    • マイクロソフトオフィス
    • OpenOffice

私が通常これを処理する方法は、明らかに、categoriesテーブルにparent_idFKがあることです。ルート要素(インターネット、オフライン)の場合、parent_idは0になります。したがって、ビューでドロップダウンの「親カテゴリ」を取得しようとしている場合、それらがネストし続けることができる距離を決定する必要があります。私は主にこれを最初のレベルに制限しているので、ドロップダウンに表示するカテゴリを選択するには、次のようにします。

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

明らかに、これはアプローチをいくらか制限しますが、ドロップダウンのテンプレートに含めるレベルを増やして、ある種の視覚的識別システムを作成することができます(階層の各レベルの余分なスペースやダッシュなどを含む) )。

とにかく、長い応答について申し訳ありません、そしてうまくいけば、これはあなたの問題にいくらか対処しました。

于 2008-12-30T19:42:19.180 に答える
0

「これを行うためのより良い方法はありますか?」あまり。リレーショナル モデルでは、階層は難しいものです。SQL を完全に放棄する以外に、これを容易にするものはありません。

「pruned_pa​​rent_list をループしてオプションを取得することにより、選択メカニズムをテンプレートに書き込みます」-おそらく最適ではありません。これはあなたの見解で起こるはずです。

于 2008-12-30T19:20:22.453 に答える
0

これがより良いかどうかはわかりませんが(相互作用に関してかそうでないか)、しかし...

保存時に階層の整合性をチェックし、必要に応じてエラーを発生させることができます。

このようなデータ型の場合、インスタンスのツリーを側面に表示したいのが理想的です。または、少なくともオブジェクト詳細ビューの完全な祖先。どちらの場合も、データベースに記載されている追加の旅行を既に行っています。

于 2008-12-30T20:36:29.833 に答える