2012-05-23 117 views
0

我想知道我該怎麼設計我的Django模型,以實現以下目標:Django:如何設計以下模型?

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

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

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

是否有意義,包括TRAFFIC_CHOICES,CONDITION_CHOICES的道班VS下爲每個組選擇VS創建單獨的類創建一個通用的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) 

回答

2

首先,變化第一個models.TextFieldCharField像其他人一樣。

類別不必是單獨的模型,除非您打算在應用程序完成後添加新的類別,在這種情況下,它必須是單獨的模型,並且您應該使用從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場到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中 - 你必須安裝一個擴展。

+0

謝謝你的答案和提示。不幸的是,道路屬性必須是複選框。一條道路可以有多個屬性(例如一半平滑和一半粗糙) – howtodothis

+0

那麼,這種方式會打敗「變化」選項的目的,但我會更新我的答案以包含複選框的說明。 –

+0

我應該沒有使用「變化」。它只是一個佔位符。我會糾正它,以減少混淆。 – howtodothis