2010-02-06 24 views
13

我的工作有這樣一個模型的一些Django的代碼:Django的模型類方法來預定義值

class Status(models.Model): 
    code = models.IntegerField() 
    text = models.CharField(maxlength=255) 

但是也有一些存儲在大約10個預定義的代碼/文本對數據庫。周圍的代碼庫我看到這樣的代碼分散:

status = Status.objects.get(code=0) # successful 
status = Status.objects.get(code=1) # failed 

我寧願爲每個方法使代碼會是這個樣子,而不是:

status = Status.successful() 
status = Status.failed() 
etc... 

這可能嗎?我已經找到了經理人的東西,但我還沒有找到辦法。是時候真的RTFM了嗎?

在Java中,它將是一個靜態方法,在Ruby中,您只需要在self中定義一個方法,但是在Python中並不那麼容易,是嗎?

回答

33

您應該實現這一點,方法是爲您的類定義一個自定義管理器,並在該管理器上添加兩個管理器方法(我相信這是爲任何模型添加表級功能的首選方法)。然而,這樣做的另一種方式是通過在兩個class methods你的類查詢投擲,並返回得到的對象,如:

class Status(models.Model): 
    code = models.IntegerField() 
    text = models.CharField(maxlength=255) 

    @classmethod 
    def successful(cls): 
     return cls.objects.get(code=0) 

    @classmethod 
    def failed(cls): 
     return cls.objects.get(code=1) 

請注意,請即get()可能拋出不同的異常,如Status.DoesNotExistMultipleObjectsReturned

與示例實現了怎麼辦使用Django經理同樣的事情,你可以做這樣的事情:

class StatusManager(models.Manager): 
    def successful(self): 
     return self.get(code=1) 

    def failed(self): 
     return self.get(code=0) 

class Status(models.Model): 
    code = models.IntegerField() 
    text = models.CharField(maxlength=255) 

    objects = StatusManager() 

在哪裏,你可以做Status.objects.successful()Status.objects.failed()得到你的願望。

+0

經理方法就是這樣。不僅非常靈活,而且非常有表現力! – Agos 2010-02-06 14:26:07

+0

如果這是一個愚蠢的問題,請原諒我,但是直接在模型中定義這些方法而不創建任何額外的管理者有什麼危害?那隻會在默認管理器下注冊這些方法。除非你想根據情況切換管理者,並因此實施不同的方法,否則它應該工作,如果不是的話? – 2013-08-12 10:02:34

+2

@SubhamoySengupta:就我所知,按照您描述的方式進行操作並沒有什麼壞處。但是,爲管理者保留這種方法符合Django的約定,並且有助於保持事物的清潔,因爲管理者中的方法針對特定的表,而模型中的方法針對特定的記錄或行。如果你的要求是在一張桌子上進行操作,那麼一個經理是Django要做的方法。 – ayaz 2013-08-14 19:37:48