2014-07-10 26 views
4

我有一個Django字段,我基本上用作通知首選項的枚舉。使用Django ModelField選項作爲字符串 - 反模式?

現在我有它設置就像這樣:

class MyModel(models.Model): 
    # ... 
    EVERY_TIME = 'every'; WEEKLY = 'weekly'; NEVER = 'never' 
    NOTIFICATION_CHOICES = ((EVERY_TIME, "Every time"), (WEEKLY, "Weekly"), (NEVER, "Never")) 
    notification_preferences = models.CharField(choices=NOTIFICATION_CHOICES, default=EVERY_TIME, max_length=10) 

我知道,通常這種枚舉應設置爲models.IntegerField,而不是一個CharField,但是由於前端採用角和數據全部通過API提供,我覺得它可能會爲前端提供更有用的信息,例如,接收'weekly'而不是2

是它認爲是不好的做法是使用CharField作爲一個枚舉?如果是這樣,我的用例足夠小,這不是什麼大不了的事,或者有什麼我錯過了,我應該改變它?

+0

更Python做你的頻率變量的元組分配:'EVERY_TIME,每週,NEVER =「每一個」,「周」,「never'' – hobs

回答

3

你可能要考慮的Django-model-utils Choices庫,這將讓您欣賞到枚舉的文本版本的一些更多的控制。

要回答你的問題,不是一切適合於整數標識符。考慮美國,澳大利亞有7個,他們有一個固定的已知當集:

ACT - Australian Capital Territory 
NSW - New South Wales 
NT - Northern Territory 
QLD - Queensland 
SA - South Australia 
TAS - Tasmania 
VIC - Victoria 
WA - Western Australia 

因爲這些都是相對固定的(國家的彌補是不可能改變的,沒有理由爲一個整數分配給每個,當文本編碼,與全名工作一樣好

我不會說使用CharField作爲選擇是一種反模式,只是應該只適用於如果您確信當文本存儲縮寫版本數據庫的意義。

+0

哇謝謝你,這是一個夢幻般的模塊。 – jdotjdot

+0

可悲的是我不能讚揚它,但它非常棒 - 而且非常重要。 –

+0

不幸的是,這並不能回答我的問題,這更多的是關於效率,儘管'Choice'仍然是一個很好的工具。看起來他們有一些例子,雖然有選擇作爲'Charfield',所以我想這是我的答案。 – jdotjdot

2

使用CharField作爲枚舉是否被認爲是不好的做法?如果是這樣,是 我的用例足夠小,它不是什麼大不了的,或者是有 我想念我應該改變它嗎?

您正在尋找在這個完全錯誤的方式。字段的選擇完全取決於您想要存儲的數據。所以,問題不在於是否CharField是不好的做法,枚舉,你需要問的問題是:

「什麼我需要在我的數據庫來存儲這一塊 信息?」

有思想的學校,說,你應該,如果你希望數據庫,以幫助您在這個領域做計算僅在數據庫中存儲整數,否則,你應該存儲數字作爲一個字符串類型,因爲這給你更多的靈活性。

我不會去多深入,由於它的自以爲是的話題,我今天要說的是,如果你決定了數據存儲爲字符有意義的應用程序,那麼就去做。不要在你的腦海裏煮這個。

我知道一般這種枚舉應該設置爲 模型。IntegerField而不是CharField,但由於前端 使用Angular,並且數據全部通過API提供,我覺得它可能會爲前端提供更有用的信息,而不是接收「每週」而不是2,例如。

我不確定你在哪裏得出你的結論,但是關於什麼樣的數據類型應該枚舉引用並沒有硬性規定。這取決於您的應用程序以及您需要存儲哪些信息 - 並決定您需要知道如何在數據庫中查詢此信息。

就你而言,你正在從API可用性的角度來看待這個問題,那就是完全沒問題。這種模式的主要目的是存儲信息,並且應該以對應用程序最有用的方式存儲信息。

最後,不要在Python中使用;。雖然技術上沒有錯誤,但通常會皺眉並且不符合python style guide

+1

關於';',雖然我非常瞭解Python風格指南所說的內容,但對於像這樣的選擇分配的小列表,我喜歡使用';',這是我唯一的一次。當你將每個選項分配放在自己的行上時,它最終會佔用模型中的大量空間,並且它必須在有問題的區域之前被聲明,所以我不能將它們全部粘在底部,並且它使我的模型比我喜歡的更大 - 所以我(和其他我見過的人)這樣做。 – jdotjdot

0

使用CharField一個枚舉絕對不是一個反模式了,考慮到最新的Django文檔建議its choices example這種方法,在這裏轉載:

FRESHMAN = 'FR' 
SOPHOMORE = 'SO' 
JUNIOR = 'JR' 
SENIOR = 'SR' 
YEAR_IN_SCHOOL_CHOICES = (
    (FRESHMAN, 'Freshman'), 
    (SOPHOMORE, 'Sophomore'), 
    (JUNIOR, 'Junior'), 
    (SENIOR, 'Senior'), 
) 
year_in_school = models.CharField(max_length=2, 
            choices=YEAR_IN_SCHOOL_CHOICES, 
            default=FRESHMAN) 
相關問題