Управление данными другой модели из метода сохранения модели - PullRequest
0 голосов
/ 18 декабря 2010

Я создаю простое приложение, в котором есть вопросы. Каждый вопрос будет иметь бинарный голос (да / нет). Я хочу записать голосование за пользователя, поэтому каждый пользователь получает только один голос за вопрос (аналогично переполнению стека или reddit).

По этому вопросу у меня есть поле Vote_no и Vote_yes int. Они должны обновляться в транзакции каждый раз, когда добавляется голосование. Можно ли это сделать с помощью метода сохранения модели голосования?

class Question(models.Model):
    part_isit = models.CharField(max_length=45)
    part_if = models.CharField(max_length=90)
    votes_no = models.IntegerField()
    votes_yes = models.IntegerField()
    author = models.ForeignKey(User)
    create_date = models.DateField(auto_now_add=True)

VOTE_CHOICES = (
    ('Y', 'Yes'),
    ('N', 'No'),
)

class Vote(models.Model):
    choice = models.CharField(max_length=1, choices=VOTE_CHOICES)
    question = models.ForeignKey(Question)
    author = models.ForeignKey(User)
    create_date = models.DateField(auto_now_add=True)
    def save(self):
       # increment the questions vote totals

       #save the vote
       super(Vote, self).save();

Ответы [ 2 ]

1 голос
/ 18 декабря 2010

Я бы переписал метод Иготье немного по-другому:

class Question(models.Model):
    # your defn

    def count_yes(self):
        return self.votes_set.filter(choice='Y')
    def count_no(self):
        return self.votes_set.filter(choice='N')

Причина этого (и ответ Иготье) заключается в том, что все данные уже хранятся в базе данных: имея общую сумму, которая сохраняется, хотя она предотвращает дополнительный запрос при каждом вызове этих методов, это означает дополнительную работу при сохранении и вероятность того, что данные, хранящиеся в базе данных, станут противоречивыми.

Если вы обнаружите, что производительность становится проблемой (и я настоятельно рекомендую вам не беспокоиться об этом до тех пор, пока это не произойдет), то вы можете взглянуть на кэширование наборов запросов (попробуйте johnny-cache, для автоматической или другой системы кэширования), или даже триггеры базы данных. Я думаю, что это может переместить его из вашего цикла запросов: база данных будет следить за обновлением значений всякий раз, когда происходит запись. Очевидно, это будет немного зависеть от вашей СУБД.

И, наконец, это не ответ на ваш вопрос напрямую, но вы упоминаете один голос за пользователя на вопрос.

class Vote(models.Model):
    # Your defn

    class Meta:
        unique_together = (
            ('author', 'question'),
        )

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

1 голос
/ 18 декабря 2010

Будет ли следующее ответить на вопрос?

class Question(models.Model):
    blablabla #your definition

    def count_yes(self):
        return Vote.objects.filter(question__exact = self,
                                   choice__exact = 'Y').count()
...