0

次のことを達成するために Django モデルを設計する方法を知りたいです。

 Road -> Category (required): Highway (select list)

 Road -> Attribute (optional): Traffic -> Heavy + Moderate (checkboxes)

 Road -> Attribute (optional): Condition -> Smooth + Rough + Average(checkboxes)

Road クラスの下に TRAFFIC_CHOICES、CONDITION_CHOICES を含めるのと、選択肢のセットごとに個別のクラスを作成するのとでは、一般的な Attribute クラスを作成するのとでは意味がありますか?

選択肢をチェックボックスとして表示するにはどうすればよいですか?

このモデルの最終目標は、「交通量のない滑らかな高速道路」などのクエリを作成できるようにすることです

これが私の試みです:

class Category(models.Model):

    CATEGORY_CHOICES = (
        ('highway', 'Highway'),
        ('parkway', 'Parkway'),
    )
    name = models.CharField(max_length=1, choices=CATEGORY_CHOICES, blank=False)

class Road(models.Model):

        name = models.TextField(blank=False)

        TRAFFIC_CHOICES = (
            ('moderate', 'Moderate'),
            ('busy', 'Busy'),
        )
        traffic = models.CharField(max_length=1, choices=TRAFFIC_CHOICES)

        CONDITION_CHOICES = (
            ('smooth', 'Smooth'),
            ('rough', 'Rough'),
            ('average', 'Average'),
        )
        condition = models.CharField(max_length=1, choices=CONDITION_CHOICES)
4

1 に答える 1

2

まず、最初models.TextFieldのものを他のものとCharField同じように変更します。

アプリケーションの終了後に新しいカテゴリを追加する場合を除き、カテゴリは個別のモデルである必要はありません。その場合、カテゴリは個別のモデルである必要があり、Road からカテゴリへの ForeignKey 関係を使用し、CATEGORY_CHOICES を破棄する必要があります。

新しいカテゴリを追加するつもりがないと仮定すると、Category モデルを完全に取り除き、CATEGORY_CHOICES を Road に入れることができます。次に name = を category = に変更し、それも Road に入れます。

これらすべてのフィールドの max_length は 1 ですが、これは問題ありませんが、その場合、フィールドに収まるように CHOICES を単一の文字にマップする必要があります。例えば:

CATEGORY_CHOICES = (
    ('H', 'Highway'),
    ('P', 'Parkway'),
)

トラフィックと条件の選択にチェックボックスを使用するのはなぜですか? チェックボックスは、1 つだけを選択するのではなく、複数の回答を選択できることを意味します。これは、道路状況や交通量に関して概念的に意味がなく、CharField と互換性がありません (CharField は非常に不自然なセットアップなしで 1 つの値しか格納できないため)。あなたが持っているシステムを維持し、ドロップダウンよりもラジオボタンを好む場合はラジオボタンを使用することができますが、選択肢を取り除き、代わりに可能なチェックボックスをそれぞれ独自の BooleanField または NullBooleanField にすることなくチェックボックスを使用することはできません。

私は通常、選択をクラス定義の外に置きます。内部にあるときに期待どおりに機能するかどうかはわかりません。私の例では、それらをクラス定義の外に移動します。これは必須ではないかもしれないので、気軽に試してみてください。

要約すると (そして、nameフィールドを a に変更しています。CharFieldこれTextFieldは、名前ではなく、非常に大きなブロックのみを対象としているためです):

CATEGORY_CHOICES = (
    ('H', 'Highway'),
    ('P', 'Parkway'),
)
TRAFFIC_CHOICES = (
    ('M', 'Moderate'),
    ('B', 'Busy'),
)
CONDITION_CHOICES = (
    ('S', 'Smooth'),
    ('R', 'Rough'),
    ('V', 'Varying'),
)

class Road(models.Model):
    name = models.CharField(max_length=512, blank=False)
    category = models.CharField(max_length=1, choices=CATEGORY_CHOICES, blank=False)
    traffic = models.CharField(max_length=1, choices=TRAFFIC_CHOICES)
    condition = models.CharField(max_length=1, choices=CONDITION_CHOICES)

編集: チェックボックスが最適であると本当に確信している場合は、主に 2 つの選択肢があります。上記のように、アプリケーションの完成後に選択肢を追加する場合は、戦略が異なります (ManyToManyField を使用する必要があります)。それ以外の場合は、次のように実装できます。

class Road(models.Model):
    name = models.CharField(max_length=512, blank=False)
    category = models.CharField(max_length=1, choices=CATEGORY_CHOICES, blank=False)
    moderate_traffic = models.NullBooleanField()
    heavy_traffic = models.NullBooleanField()
    smooth_condition = models.NullBooleanField()
    rough_condition = models.NullBooleanField()
    varying_condition = models.NullBooleanField()

グループ化されたチェックボックスとして表示する部分は、モデルではなくフォームを表示しているときに特に発生します。

ある種のビット フィールドを使用することもできますが、これはデフォルトでは Django に含まれていません。拡張機能をインストールする必要があります。

于 2012-05-23T16:22:24.563 に答える