Django подсчитывает связанные объекты на уровне модели

#django #average #vote

#django #среднее #Голосовать

Вопрос:

Можно сделать что-то вроде этого, работая:

 class Book(models.Model):
    voters = models.ManyToManyField(User, blank=True)
    vote = models.IntegerField() # summary of all votes
    def average_vote(self):
        return int(vote/self.annotate(Count('voters')))
  

Ответ №1:

Может быть, что-то вроде этого?

 class Book(models.Model):
    voters = models.ManyToManyField(User, blank=True)
    vote = models.IntegerField() # summary of all votes

    def average_vote(self):
        return int(self.vote/self.voters.all().count())
  

Дайте мне знать, если это сработает. Я это не тестировал.

Комментарии:

1. Я попробую это, но мне нужно выполнить другие действия в коде, прежде чем я смогу проверить все. Но я отвечаю вам.

Ответ №2:

Просто переопределите диспетчер по умолчанию, чтобы он всегда возвращал аннотированный набор запросов:

 class BookUserManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        return super(BookUserManager, self).get_query_set(*args, **kwargs).annotate(average_vote=models.Avg('books__vote'))

class BookUser(User):
    objects = BookUserManager()

    class Meta:
        proxy = True

class Book(models.Model):
    # Next line has been changed to use proxy model. This *will* affect the m2m table name.
    voters = models.ManyToManyField(BookUser, blank=True, related_name='books')
    vote = models.IntegerField() # summary of all votes

    objects = BookManager()
  

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

 user = BookUser.objects.get(username='joe')
print user.average_vote
  

Обновление: Извините… все неправильно понял. Это то, что я получаю за слишком быстрое прочтение вопроса. На самом деле вам нужно было бы комментировать User not Book , но поскольку User это происходит из django.contrib.auth (я предполагаю), это будет невозможно, или, по крайней мере, для этого требуется больше шагов. Приведенный выше код был обновлен.