Расчеты динамического поля в Джанго - PullRequest
0 голосов
/ 12 марта 2012

Я делаю список задач в Django.У меня есть модель с некоторыми свойствами:

class Action(models.Model):
    name = models.CharField("Action Name", max_length=200, unique = True)
    slug = models.SlugField(max_length=100, blank=True)

    complete = models.BooleanField(default=False, verbose_name="Complete?")

    effort = models.IntegerField("Effort Level", choices = LEVELS, default = 3)
    importance = models.IntegerField("Importance", choices = LEVELS, default = 3)
    enjoyment = models.IntegerField("Enjoyment", choices = LEVELS, default = 3)

    days_to_expiration = models.IntegerField("Days to Expiration", choices = DAYS_TO_EXPIRATION, default = 7)

    reset_date = models.DateField("Date of Action Reset", blank=True, null=True)

Я хочу отсортировать по приоритету.Я определяю приоритет как:

priority = (1 + (today's date - reset_date) / days_to_expiration) * importance

Это только увеличивает важность, основываясь на том, насколько «просрочена» задача.

Теперь, когда я получаю список незавершенных действий, я могу вычислить этот приоритетчисло для каждого элемента действия, но это не кажется эффективным, так как в итоге я буду вычислять одни и те же числа несколько раз.Я мог бы определить новое поле в модели:

priority = models.DecimalField("Priority", max_digits=4, decimal_places=2, blank = True, null = True)

и запланировать запуск функции один раз в день для расчета нового приоритета для задачи.

Но я хочу знать, можно ли запрограммировать вычисление приоритетов непосредственно в модели.Таким образом, поле приоритета в модели Action обязательно должно быть разработано как функция важности и days_to_expiration.Он будет обновляться динамически, используя значения важности, days_to_expiration и сегодняшнюю дату.Таким образом, приоритет всегда будет рассчитываться автоматически, когда мне это нужно.Это возможно?

Ответы [ 2 ]

2 голосов
/ 12 марта 2012

То, что вы хотите, называется денормализация ;priority - денормализованное поле.Вероятно, вы можете взломать сигналы, или расширить методы save, или, возможно, использовать методы менеджера каким-то умным способом для достижения этой цели, но хорошей альтернативой является использование django-denorm .В учебнике рассматривается ситуация, очень похожая на вашу.

1 голос
/ 12 марта 2012

Вы можете сделать что-то вроде:

class MyModel(models.Model):
    ...
    @property
    def priority(self):
        return (1 + (date.today() - self.reset_date) / self.days_to_expiration) * self.importance

Затем вы можете получить к нему доступ, как и к любому другому атрибуту вашей модели

priority = my_model.priority
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...