我想知道如何设计我的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)
答案 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中 - 您必须安装扩展程序。