0

I have a model which looks like this:

class Posts(models.Model):
    title = models.CharField(max_length=100)
    creation_timestamp = models.DateTimeField(auto_now_add=True)
    body = models.CharField(max_length=255)
    user_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) 
    likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="likes",blank=True)
    dislikes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name="dislikes",blank=True)

I have added an endpoint in urls.py, so that when the url .../v1/posts/max-interaction-count is visited, the following function in views.py is run:

@api_view(['GET'])
def interaction_count_view(request):
    max_post = None
    max_interactions = 0
    for post in Posts.objects.all():
        interactions = post.likes.count() + post.dislikes.count()
        if interactions > max_interactions:
            max_post = post
            max_interactions = interactions
    return Response({"Post number " :  max_post.pk, "interaction_count ": max_post.likes.count() + max_post.dislikes.count()})

This works, returning the id of the post with the maximum sum of likes and dislikes. However, I believe interaction_count_view might not be very scalable because it was written in python, rather than using built-in django methods which use SQL. Is this the case? If so, what is a better approach to counting the number of likes and dislikes associated with a post instance?

nyptop
  • 59
  • 1
  • 2
  • 9

1 Answers1

0

Annotate the expression calculating the number of interactions of a post on the queryset and use latest to get the post which has maximum number of interactions:

from django.db.models import Count

@api_view(['GET'])
def interaction_count_view(request):
    max_post = Posts.objects.annotate(interactions=Count('likes') + Count('dislikes')).latest('interactions')
    if max_post:
        return Response({"Post number" :  max_post.pk, "interaction_count": max_post.interactions})
    return Response({"Post number": None, "interaction_count": 0, "message": "No posts exist!"})

Note: I changed your keys in the dictionary that you pass to response they had extra spaces ("Post number " changed to => "Post number", etc.)

Note: Model names should ideally be singular so Post instead of Posts

Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33