Методы класса модели Django для предопределенных значений - PullRequest
14 голосов
/ 06 февраля 2010

Я работаю над некоторым 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 это не так просто, не так ли?

1 Ответ

35 голосов
/ 06 февраля 2010

Возможно, вам следует реализовать это путем определения настраиваемого менеджера для вашего класса и добавления двух методов менеджера для этого менеджера (который, я считаю, является предпочтительным способом добавления функциональности на уровне таблицы для любой модели). Однако, другой способ сделать это - добавить два метода класса в ваш класс, которые запрашивают и возвращают результирующие объекты, такие как:

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(), чтобы получить то, что вы хотите.

...