0

I'm creating a newsfeed in an APP.

A user is logged in and sees the posting of other users. Therefore I need two user models (user + auth_users)

Now I want to add a boolean field that shows if a post is already liked or not.

I already looked at the documentation and other posts here but I can´t find a solution. The auth_user is shown in the response but I can´t included it in the get_already_liked function

class NewsPostSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(read_only=True)
    auth_user = serializers.PrimaryKeyRelatedField(
        read_only=True,
        default=serializers.CurrentUserDefault()
    )
    attachments = AttachmentSerializer(read_only=True, many=True)
    already_liked = serializers.SerializerMethodField()

    def get_already_liked(self, request):
        liking_kwargs = {
            'post_id': request.id,
            'user_id': self.auth_user
        }
        if LikePost.objects.filter(**liking_kwargs).exists():
            return True
        else:
            return False

    class Meta:
        model = Post
        read_only_fields = (
            'id', "user", 'creation_time_stamp', 'auth_user', 'ready_liked',
        )
        fields = (
            'id', 'user', 'creation_time_stamp', 'last_update_time_stamp',
            'description', 'attachments', 'already_liked', 'auth_user',
        )

UPDATE: In another post I found a solution. My code looks now like this and works:

class NewsPostSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer(read_only=True)
    attachments = PostAttachmentSerializer(read_only=True, many=True)
    already_liked = serializers.SerializerMethodField()

    def get_already_liked(self, obj):
        user = self.context['request'].user.id
        liking_kwargs = {
                    'post_id': obj.id,
                    'user_id': user
        }
        if LikePost.objects.filter(**liking_kwargs).exists():
            return True
        else:
            return False

    class Meta:
        model = Post
        read_only_fields = (
            'id', "user", 'creation_time_stamp', 'attachments', 'already_liked',
        )
        fields = (
            'id', 'user', 'creation_time_stamp', 'last_update_time_stamp',
            'description', 'attachments', 'already_liked',
        )

Thanks to Marco and Shakil

2 Answers2

0

I would change the approach here a little bit. For the like counter I'd use something like a model in the database that has a foreign key to the picture and another foreign key to the user, with that in place you can use the reverse relations between the models. For instance:

class Post(models.Model):
    ...
    ...

    def number_of_likes(self):
        return len(self.likes.all())  # dont know if sintax is right, but the idea is to get all the instance of likes that is related to this post. (reverse relation)


class Like(models.Model):

    post = models.ForeignKey(Post, on_delete=models.CASCADE ,related_name='likes')
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='all_likes')

So, what I recommend is to insert the counter of likes inside the model of the user, and then you can start playing around with this in the serializers.

  • Hi Marco, first of all thanks for your answer! I already have a model for the liking. `class LikePost(models.Model): user = models.ForeignKey(User, related_name='like_post_user', on_delete=CASCADE, null=True) post = models.ForeignKey(Post, related_name='like_post', on_delete=CASCADE, null=True) time_stamp = models.DateTimeField(auto_now=True)` My probelm is currently to get the ID of the user that is looged in and wants to receive the feed – Andreas Reichienger Sep 11 '19 at 05:43
0

Your serializerMethodField's arguments are wrong. This should be like this

def get_already_liked(self, obj):
        request = self.context.get('request')
        liking_kwargs = {
            'post_id': request.id, // I have a doubt, is this request.data['id'] 
            'user_id': obj.auth_user
        }
        if LikePost.objects.filter(**liking_kwargs).exists():
            return True
        else:
            return False
Shakil
  • 4,520
  • 3
  • 26
  • 36
  • Hi, thanks for your support on this! I tried your solution, but following problems appeared: 'Post' object has no attribute 'auth_user' and request doesn´t include any values My biggest problem is to get the auth_user. When I hard code all IDs everything works well – Andreas Reichienger Sep 11 '19 at 05:51
  • `Post` object has no attribute `auth_user` because you mention it is a `read_only_fields` in meta class. request.data should contains those, i have commented this. If you post data then . request.data.get('auth_user') should contain auth_user. – Shakil Sep 11 '19 at 06:01
  • Hi Shaki, thanks for your quick response. I tried what you suggested. ' request.data.get('auth_user') ' gives me None and not the user id – Andreas Reichienger Sep 11 '19 at 06:14
  • first remove `auth_user` from `read_only_fields`. Can you please update your question with post data ( possible screen shoot of postman ) and your updated code. This will help us to point out the fault. – Shakil Sep 11 '19 at 06:53
  • Hi Shakil. I found a solution. Please look at the updated Posting. Thanks for your support! – Andreas Reichienger Sep 11 '19 at 08:18