1👍
✅
If I understood you already have a Post instance, and you would like to get its score? I so, I think you could implement a computed property as follow:
class Post(models.Model):
voters = models.ManyToManyField(User, through="PostVote")
@property
def score(self):
return sum([-1 if vote.state == 'downvote' else 1 for vote in self.postvotes.all()])
Note that this method will trigger extra DB queries if you didn’t fetch your Post instance with .prefetch_related('postvotes')
Then you can use post.score
to get the result
Another way to implement the property would be by doing a query instead:
class Post(models.Model):
voters = models.ManyToManyField(User, through="PostVote")
@property
def score(self):
return PostVote.objects.filter(post=self.pk).aggregate(vote=models.Sum(
models.Case(
models.When(state="upvote", then=1),
models.When(state="downvote", then=-1),
default=0,
output_field=models.IntegerField()
)
))['vote']
Note that I didn’t try any of those code, so there might be any typo/wrong variable names
0👍
Another solution might be to add it to your query sets by default.
This should make the annotation available throughout.
-
Create a file
managers.py
inside of your app. And create the custom queryset/managerfrom django.db import models class PostQuerySet(models.QuerySet): def annotate_vote(self): return self.annotate(vote=models.Sum( models.Case( models.When(postvote__state="upvote", then=1), models.When(postvote__state="downvote", then=-1), default=0, output_field=models.IntegerField() ))) class PostManager(models.Manager): def get_queryset(self): return PostQuerySet(self.model, using=self._db).\ annotate_vote()
- Add the new manager as inside of your model.
from .managers import PostManager
class Post(models.Model):
...
objects = PostManager()
...
- This should give you accesss to the data like so:
Post.objects.last().vote
👤S.D.
- [Answered ]-Does both csrftoken cookie AND csrf_token INPUT type required in django
- [Answered ]-Django get base model from parent model
- [Answered ]-From . import views ImportError: attempted relative import with no known parent package
- [Answered ]-Testing with Django: how to display all characters when using assertEqual with json object?
Source:stackexchange.com