4

モデル フィールドでブール値の選択を使用して、他のフィールドを有効/無効にするにはどうすればよいですか。ブール値が true/false の場合、他のモデル フィールドを有効/無効にしたい。django モデル/フォーム/ウィジェットを使用してこれらの関係をネイティブに表現する方法はありますか? 私はこれらの関係をモデル化するためにカスタム テンプレートを書き続けていますが、特別なテンプレートを使わずに Django でそれらを表現する良い方法を見つけることができません。

例えば:

クラス PointInTime(models.Model):
    is_absolute_time = models.BooleanField()
    absolute_time = models.DateTimeField()
    is_relative_time = models.BooleanField()
    days_before = models.IntegerField()

したがって、is_absolute_time が True の場合、absolute_time エントリを GUI で編集可能にし、days_before エントリをグレー表示して編集できないようにします。「is_relative_time」フラグが True の場合、absolute_time エントリをグレー表示にし、days_before 値を編集可能にします。したがって、is_absolute_time と is_relative_time は、GUI の同じグループ内のラジオ ボタンになり、それらの 2 つの対応するフィールドは、ラジオ ボタンが選択されている場合にのみ編集可能になります。これはカスタマイズされたテンプレートで簡単に実行できますが、django でモデル/フォームを使用してこの関係をネイティブに表示する方法はありますか?

4

2 に答える 2

6

「この関係を自然に示す」とはどういう意味かを明確にし、関心の分離について明確に考えると役立ちます。

別のフィールドの値に基づいて特定のフィールドを「グレーアウト」または無効にするだけの場合、これは純粋にプレゼンテーション/ UIの問題であるため、テンプレート(および/またはJavascript)がそれを処理するのに適した場所です。

送信されたデータが内部的に一貫していることを検証する場合(つまり、is_absolute_timeがTrueの場合はabsolute_timeが入力されるなど)、これはフォーム検証の問題です。そのロジックの場所は、FormまたはModelFormオブジェクトのclean()メソッドにあります。

内部的に一貫性がない限り、PointInTimeモデルをデータベースに保存できないようにする場合は、データ層の問題です。その場所は、モデルオブジェクトのカスタムsave()メソッドにあります(Django 1.2には、より広範なモデル検証システムが含まれます)。

これらのオプションはすべて、これらの特定のフィールドで必要なことを実行するための命令型コードの記述を伴います。上記の3つのケースすべてのコードを具体的にではなく一般的に記述できるように、モデルで状況を宣言的に表す方法を探している可能性があります。これを行うための組み込みのDjangoの方法はありませんが、確かに次のようなことを行うことができます。

class PointInTime(models.Model):
    field_dependencies = {'is_absolute_time': 'absolute_time',
                          'is_relative_time': 'days_before'}
    ... fields here ...

次に、モデルのsave()コード(またはForm clean()コード、またはテンプレート)は、このディクショナリを使用して、他のフィールドの値に応じて、どのフィールドを有効/無効にするかを決定できます。ただし、この一般化は、多くの異なるモデルで同じことを行う必要があると予想しない限り、努力する価値はほとんどありません。

最後に、データレイヤーをより適切に正規化するために検討する必要のあるいくつかのスキーマ設計の選択肢:

  • 有効な状態(絶対状態と相対状態)が2つしかない場合は、2つではなく1つのブールフィールドを使用します。次に、起こりうる不整合を回避します(両方のブール値がFalseまたはTrueの場合はどういう意味ですか?)

  • または、ブール値を完全に削除し、absolute_time/days_beforeのいずれかでNull値を使用することでさらに単純化します。

  • 有効な状態が3つ以上ある可能性がある場合は、2つのブールフィールドを使用する代わりに、選択肢として1つのIntegerFieldまたはCharFieldを使用してください。上記と同じ理由ですが、3つ以上のオプションに対応できます。

  • RelativeTimeとAbsoluteTimeは互いにデータフィールドを共有していないように見えるため、それらを完全に別々のモデルに分割することを検討してください。どちらか一方にForeignKeyを必要とする他のモデルがある場合は、継承を使用してモデル化できます(RelativeTimeとAbsoluteTimeの両方がPointInTimeから継承し、他のモデルにはPointInTimeへのForeignKeyがあります)。

于 2009-02-03T18:29:14.320 に答える
1

これらのオブジェクトで何をしているのかは完全にはわかりませんが、ユーザーがどちらを選択しても、ある瞬間を指しています. 「5 日前」は「木曜日」であり、その逆です。

したがって、日付がサイトと一緒に転がらない限り (たとえば、「5 日前」というレコードは、木曜日、明日などを意味します)、これはインターフェイスの問題に過ぎないのでしょうか? その場合は、モデルの日付に単一の値を使用し、フォームとビューにすべての作業を任せます。

これにより、競合するフィールドが 1 つだけになるため、自動生成された管理者側の問題は解決しますが、独自のフォーム ウィジェットを作成してモデルの ModelAdmin クラスをオーバーライドしない限り、2 つの選択肢をネイティブに選択することはできません。

そうでない場合は、この回答を無視してください。

于 2009-02-03T16:29:48.287 に答える