4


0

私はブログアプリを書くためにDjangoを使っています、そして私は階層的なカテゴリー構造を実装しようとしています。 各カテゴリには、同じカテゴリモデルを指す「親」ForeignKeyがあります。 私は管理者がカテゴリを追加できるようにしたいと思います、そして私は彼らがカテゴリの親カテゴリを選択できるようにするインターフェースが欲しいです。 しかし、私は自分のおじいちゃんのような状況を避けたいので、カテゴリーの選択肢を、祖先として問題のカテゴリーを持たないものに限定したいと思います。

今、私はこれをビューから制御しています。

parent_candidates = list(Category.objects.all())pruned_pa​​rent_list = [instance.idがcat.getHierarchy()にない場合、parent_candidatesにあるcatのcat]

ここで、instanceは編集中のカテゴリ、getHierarchy()は先祖IDのリストを取得するメソッドです。

この方法には多くの問題があります。 特に、すべてのカテゴリのリストを取得するために余分なデータベースヒットを使用し、オプションを取得するためにpruned_pa​​rent_listをループすることによって選択メカニズムをテンプレートに書き込むようにしています。

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

5 回答


1


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

これは、カテゴリを文字列形式で、サブカテゴリを区切り文字で区切って格納するという、不適切な解決方法を使用する場合がほとんど唯一の場合です。 データベースクエリと他の操作の両方がはるかに簡単になります。

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

ID名1インターネット2インターネット/ Google 3インターネット/ Yahoo 4オフライン5オフライン/ MS Office / MS Excel 6オフライン/ Openoffice

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

いずれにしても、SQLの階層データはそれだけでは簡単ではないので、あなたが何をしても、あなたはおそらくかなりのカスタムコーディングをしなければならないでしょう。


1


http://code.google.com/p/django-treebeard/[django-treebeard]アプリを見てください。


0


「これを行うためのもっと良い方法はありますか?」あんまり。 リレーショナルモデルでは階層は難しいです。 SQLを完全にあきらめる以外に簡単なことはありません。

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


0


私があなたの苦境を正しく理解しているならば、問題それ自体はあなたがどのカテゴリーが親になることができて、どれがそうでないことができるかに対処する方法にあります。 これらの問題を回避するための1つの選択肢は、実際に親になることができるカテゴリのレベルを制限することです。 たとえば、次のようなカテゴリがあるとします。

  • インターネットグーグルヤフー

  • オフライン MS Office OpenOffice

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

保護者= Category.objects.filter(parent_id = 0)

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

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


0


これがより優れているかどうかはわかりません(インタラクション的にもそうでなくても)。

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

理想的にはそのようなデータ型のために私は側面のインスタンスのツリーを見たいと思います。 あるいは、オブジェクト詳細ビューの少なくとも完全な先祖です。 どちらの場合も、データベースへの追加の出張はすでに済んでいるはずです。