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与其他人一样。

Category 不必是单独的模型,除非您打算在应用程序完成后添加新的类别,在这种情况下,它必须是单独的模型,并且您应该使用从 Road 到 Category 的 ForeignKey 关系并放弃 CATEGORY_CHOICES。

假设您不打算添加新类别,您可以完全摆脱 Category 模型并将 CATEGORY_CHOICES 放入 Road。然后将 name = 更改为 category = 并将其也放入 Road。

所有这些字段的 max_length 都为 1,这很好,但在这种情况下,您需要将 CHOICES 映射到单个字符,以便它们适合该字段。例如:

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

为什么要使用复选框来选择流量和条件?复选框意味着您可以选择多个答案,而不是被迫只选择一个。这在概念上对于道路状况或交通没有意义,并且与 CharField 不兼容(因为 CharField 只能存储一个值,没有一些非常人为的设置)。如果您更喜欢单选按钮而不是下拉菜单,则可以保留您拥有的系统并使用单选按钮,但是您不能在不摆脱选择的情况下使用复选框,而是将每个可能的复选框设置为自己的 BooleanField 或 NullBooleanField。

我通常把我的选择放在类定义之外。我不知道当它在里面时它是否能如你所愿地工作。对于我的示例,我将它们移到类定义之外;这可能不是必需的,因此请随意尝试。

总结一下(我将name字段更改为 aCharField因为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)

编辑:如果你真的确定复选框是最合适的,那么你有两个主要选择。如上所述,如果您打算在应用程序完成后添加选项,那么您的策略是不同的(您需要使用 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 回答