Django:如何设计以下模型?

时间:2012-05-23 16:13:11

标签: django django-models django-forms

我想知道如何设计我的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)

1 个答案:

答案 0 :(得分:2)

首先,将第一个models.TextField更改为CharField,与其他人一样。

类别不必是单独的模型,除非您打算在应用程序完成后添加新类别,在这种情况下它必须是一个单独的模型,您应该使用从Road到Category和Ditch的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字段更改为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)

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