Adding an object to a ManyToMany field doesn't work

I have 2 models:

class User(AbstractUser):
    pass

class Post(models.Model):
    poster = models.ForeignKey('User', on_delete=models.CASCADE, related_name='posts')
    body = models.TextField()
    likes = models.IntegerField(default=0)
    likers = models.ManyToManyField('User', blank=True, null=True, related_name='liked_posts')

Post model has a manytomany field to User model. I try to add a user object to the field with the view function below but it doesn’t work. Basically, when I check the post in the admin page, the user is not added to the likers.
The view I user to add the object:

@csrf_exempt
def likepost(request, like, post_id):
    if (request.method == 'PUT'):
        post = Post.objects.get(pk=post_id)
        if like:
            post.likers.add(request.user)
        else:
            post.likers.remove(request.user)

        post.save()
        print(post.likers)
        return HttpResponse(status=204)
    else:
        return JsonResponse({
            'error': 'PUT request required.'
        }, status=400)

Url path:

path('likepost/<int:like>/<int:post_id>', views.likepost, name='likepost')

JavaScript:

fetch(`likepost/${likeValue}/${postId}`, {
        method: 'PUT'
    });

What does your url definition look like? What is a sample url being submitted?

Also, since you’re obviously not doing this through an HTML form submission, are you sure you’re getting the request.user reference in the view?

If I had to debug this, I’d throw a set of print calls before the if to verify that the parameters received are what are expected.

Side note: This is not necessary. You’re not actually changing the Post object. A ManyToMany relationship exists as a “join table” between the two related models. An add does not affect either related table - it’s an insert into that join table.

1 Like

I actually did add a few prints to the view. Turns out the view executes properly and how it should. But add doesn’t seem to work.
By the way, thanks for your the side note. Didn’t know that.
I added the url path and javascript code in edit.

What’s a sample of an actual URL being submitted? Have you verified that the add is actually being executed?

1 Like

URL sample: likepost/1/1
And no. How can I do that?

I just figured out It was actually working correctly! It just wouldn’t appear on admin page when I refreshed the tab. It seems it needed a hard refresh to load properly. :man_facepalming: