2010-04-20 79 views
3

說我有未知數量的問題。例如:如何在單個Django模型中存儲任意類型的值?

  • 天空是藍色的[Y/N]
  • 是你出生於[日期]什麼日期
  • 什麼是圓周率[3.14]
  • 什麼是大INTEG [100]

現在,每個這些問題都提出了一個不同但非常具體的答案(布爾型,日期型,浮點型,整數型)。本地django可以愉快地在模型中處理這些。

class SkyModel(models.Model): 
    question = models.CharField("Is the sky blue") 
    answer = models.BooleanField(default=False) 

class BirthModel(models.Model): 
    question = models.CharField("What date were your born on") 
    answer = models.DateTimeField(default=today) 

class PiModel(models.Model) 
    question = models.CharField("What is pi") 
    answer = models.FloatField() 

但這有明顯的問題,每個問題都有一個特定的模型 - 所以,如果我們需要添加問題後,我不得不改變數據庫。呸。所以,現在我想變得很花哨 - 如何設置一個由答案類型轉換自動發生的模型?

ANSWER_TYPES = (
    ('boolean', 'boolean'), 
    ('date', 'date'), 
    ('float', 'float'), 
    ('int', 'int'), 
    ('char', 'char'), 
) 

class Questions(models.model): 
    question = models.CharField(() 
    answer = models.CharField() 
    answer_type = models.CharField(choices = ANSWER_TYPES) 
    default = models.CharField() 

所以從理論上講,這將做到以下幾點:

  • 當我建立我的意見我看答案的類型,並確保我 只是擺在那價值。
  • 但是當我想把這個回答拉出來時,它會以answer_type指定的格式返回數據。例3.14作爲浮點數而不是str返回。

如何執行這種自動轉換?或者可以有人建議一個更好的方法來做到這一點?

非常感謝!

回答

5

我其實只是遇到了有關可擴展用戶設置的這類問題。我的解決方案是在CharField的模型上存儲該類型,並使用__builtin__getattr的智能使用吸氣劑進行類型轉換。這是我的代碼(適應您的需求):

VALUE_TYPE_CHOICES = (
    ("unicode", "Unicode String"), 
    ("int", "Integer"), 
    ("bool", "Boolean"), 
) 

class Setting(models.Model): 
    name = models.CharField(max_length=100) 
    description = models.TextField(blank=True) 
    type = models.CharField(max_length=50, choices=VALUE_TYPE_CHOICES) 
    default_value = models.CharField(max_length=127) 

def get_setting(user, setting_id): 
    profile_setting = #get the user's specific setting value here, not relevant 
    type = getattr(__builtin__, profile_setting.setting.type) 
    if type is bool: 
     return type(int(profile_setting.value)) 
    else: 
     return type(profile_setting.value) 

那裏面有一個疑難雜症:bool('0')實際上返回True,所以我選擇了值映射爲bool之前強制轉換爲int。還有其他方法可以實現此目的,例如使用ast模塊的literal_eval方法。儘管如此,整體模式仍然有效。

2

你應該沒問題,只是將答案存儲爲字符串。如果我們談論的是通過網絡接受數據,那麼無論如何你都會接收到一個字符串的輸入,所以你不會因爲把它作爲字符串存儲在數據庫中而失去精確性。

一種可能的選擇是爲每種可能的數據類型包含一列,使它們爲空。

class Questions(models.model): 
    question = models.CharField(() 
    answer = models.CharField() 
    answer_type = models.CharField(choices = ANSWER_TYPES) 
    int_answer = models.IntegerField(null=True) 
    bool_answer = models.NullBooleanField(null=True) 
    ... etc. 

如果是我,我會堅持一個CharField雖然。

+0

把它作爲一個字符串是去了,恕我直言的方式,但具有類型轉換回原來的值一個好的策略是非常重要的。每種類型的答案都有不同的字段,聽起來很麻煩。 – 2010-04-20 22:00:43

2

我想補充一個自定義的方法,對您的問題類:

def get_converted_answer(self): 
    if self.answer_type == 'int': 
    return int(self.answer) 
    if self.answer_type == 'bool': 
    # ... 
+0

我認爲這樣做,並認識到我可以變得棘手,並避免使用上面我的帖子中的邏輯寫所有額外的ifs。但絕對是正確的想法。 – 2010-04-20 21:53:30

+0

你的訣竅確實很不錯。 +1 – Bolo 2010-04-20 22:18:51

相關問題