Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRF serializer get liked data with post by request user

I'm making a social app like facebook. when getting post(at news feed) data I would like to get Boolean if I pressed like about that post.

models.py

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Post(models.Model):
    uploader = models.ForeignKey(User)
    likes = models.IntegerField(default=0)
    point = models.IntegerField(default=0)
    isPointReceived = models.BooleanField(default=False)

    content = models.TextField()
    uploadedTime = models.DateTimeField(auto_now=True)
    # editedTime = models.DateTimeField()
    def __str__(self):
        return ("[uploader = " + self.uploader.username + "]") + (", [id = " + (str)(self.id) + "]") + ("[content = " + self.content[:50] + "]")


class PostLike(models.Model):
    post = models.ForeignKey(Post, related_name='postLikes')
    liker = models.ForeignKey(User)
    def __str__(self):
        return "Like" + "| [Post = " + (str)(self.post) + "]" + ", [Liker = " + self.liker.username + "]"

serializers.py

class PostLikeSerializer(serializers.ModelSerializer):
    class Meta:
        model = PostLike
        fields = '__all__'


class PostListSerializer(serializers.ModelSerializer):
    uploader = UserDetailSerializer()
    isMine = serializers.SerializerMethodField()
    isLiked = serializers.SerializerMethodField()
    postComments = PostCommentSerializer(many=True, allow_null=True)
    class Meta:
        model = Post
        fields = ('uploader', 'id',  'likes', 'point', 'isPointReceived', 'content', 'uploadedTime', 'postComments', 'isMine', 'isLiked',)


    def get_isMine(self, obj):
        requestUser = CurrentUserDefault()
        return obj.objects.fileter(uploader=requestUser).exists()
        # return obj.filter(uploader=requestUser)


    def get_isLiked(self, obj):
        requestUser = CurrentUserDefault()
        return PostLike.objects.filter(post=obj, liker=requestUser).exists()
        #
        # try:
        #     PostLike.objects.get(post=obj, liker=requestUser)
        #     return True
        # except:
        #     return False

I tried lot of dirty stuffs. but there was no solution..

conclusion: HTF to get data about, if user has a record of PostLike(post=post, user=user)

  • how to get user in serializer Class.

or should I approach this in different ways? like managing liked data in APIView or whatever etc...

help!

========EDITED========== final code should look like this. in serialziers.py

class PostListSerializer(serializers.ModelSerializer):
    uploader = UserDetailSerializer()
    postComments = PostCommentSerializer(many=True, allow_null=True)
    postLikes = PostLikeSerializer(many=True, allow_null=True)
    postImages = PostImageSerializer(many=True, allow_null=True)
    isMine = serializers.SerializerMethodField()
    isLiked = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = ('uploader', 'id',  'likes', 'content', 'uploadedTime', 'postComments', 'postLikes', 'postImages', 'isMine', 'isLiked',)


    def get_isMine(self, obj):
        requestUser = self.context['request'].user
        return obj.uploader == requestUser


    def get_isLiked(self, obj):
        requestUser = self.context['request'].user
        return PostLike.objects.filter(post=obj, liker=requestUser).exists()
like image 232
softmarshmallow Avatar asked Oct 18 '22 17:10

softmarshmallow


1 Answers

You can get a user from serializer context inside serializer method:

self.context['request'].user

It passed from a method get_serializer_context which originally created in a GenericAPIView:

class GenericAPIView(APIView):
    ....
    def get_serializer_context(self):
        """
        Extra context provided to the serializer class.
        """
        return {
            'request': self.request,
            'format': self.format_kwarg,
            'view': self
        }

As you can see you could also get format and view from context. You could also override this method for set additional context.

like image 59
Ivan Semochkin Avatar answered Oct 21 '22 04:10

Ivan Semochkin