2010-02-06 2 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 вы бы просто определили метод для себя, но это не так просто в 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.DoesNotExist и MultipleObjectsReturned ,

И для примера реализации, как сделать то же самое с помощью менеджеров 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

+0

Простите меня, если это глупый вопрос, но каков же вред в определении этих методов в модели непосредственно без создания каких-либо дополнительных менеджеров? Это просто зарегистрировало бы методы под менеджером по умолчанию. Если вы не хотите переключать менеджеров в зависимости от обстоятельств и, таким образом, внедрять различные наборы методов, он должен работать, не так ли? –

+2

@SubhamoySengupta: Нет никакого вреда в том, чтобы делать это так, как вы описали, насколько я знаю. Тем не менее, сохранение таких методов, зарезервированных для менеджеров, соответствует соглашениям Django и помогает сохранять чистоту, потому что методы в менеджерах работают против конкретной таблицы, тогда как методы в моделях работают против определенной записи или строки. Если ваше требование состоит в том, чтобы работать над таблицей, тогда менеджер - это способ Django, чтобы это сделать. – ayaz

Смежные вопросы