Search code examples
djangodjango-rest-frameworkdjango-redis

how to combine values from Redis and Django-rest-framework


I'm building a social app which has a "like" feature, I'm using django-redis to store "like" numbers from every post like this:

from django_redis import get_redis_connection
con = get_redis_connection("default")
con.incr("post" + ":" + id)

From the doc Raw client access

It works great, and I also use django-rest-framework to provide api, ListCreateAPIView to list all posts.Usually it will display any fields you want in the database. The problem here is now I wanna display "like" count from django-redis in this API which means the json return are from my database and django-redis.

I had look around the source code about django-rest-framework

class ListCreateAPIView(mixins.ListModelMixin,mixins.CreateModelMixin,
                    GenericAPIView):
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

and the list method:

class ListModelMixin(object):
    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

It seems like I can only get data from the database queryset(which I use Mysql). Any possible way to return data from django-redis with django-rest-framework?

Solved: Thanks answer from @Rahul Gupta, I do a little hack to work better:

def get_likes(self, obj):
    post_id = obj.id
    post_like = get_redis_connection("default")
    likes = post_like.get("post"+":"+str(post_id))
    if likes == None:
        return 0
    else:
        likes = likes.decode('utf-8')
        return likes

Solution

  • You can add a 'likes' SerializerMethodField in your PostSerializer to add likes in the serialized representation of the object.

    class SocialPostSerializer(serializers.ModelSerializer):
    
        likes = serializers.SerializerMethodField() # define field
    
        class Meta:
            model = SocialPost
    
        def get_likes(self, obj):
            social_post_id = obj.id    
            # here write the logic to get the no. of likes 
            # for a social post using the 'social_post_id' from redis    
            return likes 
    

    Now, the serialized data returned by DRF in list requests will contain a parameter likes along with other parameters.