开发者

Django counting related objects in model layer

开发者 https://www.devze.com 2023-03-05 16:23 出处:网络
It is possible to do something like this working:开发者_JAVA技巧 class Book(models.Model): voters = models.ManyToManyField(User, blank=True)

It is possible to do something like this working:

开发者_JAVA技巧
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')))


Maybe something like this?

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())

Let me know if that works. I haven't tested it.


Just override the default manager to make it always return an annotated queryset:

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()

Then, you can get at the value like any other attribute on your the user model:

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

Update: Sorry... got that all wrong. That's what I get for reading the question too quickly. You'd actually need to annotate User not Book, but since User is coming from django.contrib.auth (I'm assuming) that's not going to be possible, or at least it requires more steps. Code above has been updated.

0

精彩评论

暂无评论...
验证码 换一张
取 消