I'm adding a very simple roadmap voting feature to my website, where people can add feature requests, and people can then vote on each other's suggestions. The basics are pretty simple:
# models.py
class FeatureRequest(models.Model):
title = models.CharField(max_length=50)
description = models.TextField()
author = models.ForeignKey(User, editable=False, on_delete=models.CASCADE)
is_implemented = models.BooleanField(default=False, editable=False, db_index=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Vote(models.Model):
feature = models.ForeignKey(FeatureRequest, editable=False, on_delete=models.CASCADE)
user = models.ForeignKey(User, editable=False, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ["feature", "user"]
#views.py
class RoadmapController(viewsets.ModelViewSet):
permission_classes = (AuthorOrReadOnlyPermission,)
serializer_class = FeatureRequestSerializer
def get_queryset(self):
return FeatureRequest.objects.filter(is_implemented=False)
def perform_create(self, serializer):
return serializer.save(author=self.request.user)
# serializers.py
class FeatureRequestSerializer(serializers.ModelSerializer):
class Meta:
model = FeatureRequest
fields = "__all__"
There is also a separate view for actually creating and deleting votes, but that's not needed here for my question.
What I want is that the response of the feature request list includes the number of votes for each one, and a boolean if the logged-in user has voted for it:
[
{
"title": "This is a feature request",
"description": "Foo bar",
"author": 1,
"number_of_votes": 1,
"has_my_vote": true
}
]
I already figured out that I can change my queryset to FeatureRequest.objects.filter(is_implemented=False).annotate(number_of_votes=Count("vote"))
, add number_of_votes = serializers.ReadOnlyField()
to the serializer, and the number of votes is visible. Is that the best way? It adds a query for each feature request I would assume.
But most of all, I don't know how to add that "has_my_vote" boolean to the result (and how to keep that performant, of course).