Я бы переписал метод Иготье немного по-другому:
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'),
)
Тогда вам не придется полагаться на логику приложения, чтобы сохранить это ограничение. Возможно, вы захотите запретить пользователям голосовать по своим собственным вопросам.