How to get POST and create message on Django using DetailView

589 Views Asked by At

I have Post model and Message model.

I want to get POST, create message on one post and preview it.

I have ValueError Cannot assign "<bound method PostDetailView.post of <blog.views.PostDetailView object at 0x7fa9a370b8>>": "Message.post" must be a "Post" instance. at body = request.POST.get('body')

How can I do this?

All my code

models.py

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User,on_delete=models.CASCADE)
    topic = models.ForeignKey(Topic,on_delete=models.SET_NULL,null=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post-detail',kwargs={'pk':self.pk})


class Message(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE) 
    post = models.ForeignKey(Post,on_delete=models.CASCADE)
    body = models.TextField()
    date_posted = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.body[0:50]

views.py

class PostDetailView(DetailView):
    model = Post

    def post(self, request, *args, **kwargs):
        message = Message(
            user = request.user,
            post = self.post,
            body = request.POST.get('body')
        )
        message.save()
        return super(PostDetailView,self).post(request, *args, **kwargs)

urls.py

urlpatterns = [
 path('post/<int:pk>',PostDetailView.as_view(),name='post-detail')
]
1

There are 1 best solutions below

7
Kauê Oliveira On

Assuming your url has the post_id parameter, as in https://example.com/?post_id=1:

def get_post(post_id):
    try:
        post = Post.objects.get(id=post_id)
    except Post.DoesNotExist:
        raise ValidationError(f"Post model with id {post_id} was not found.")

def post(self, request, *args, **kwargs):
        message = Message(
            user = request.user,
            post = self.get_post(kwargs.get('pk')),
            body = request.POST.get('body')
        )
        message.save()
        return super(PostDetailView,self).post(request, *args, **kwargs)

This should get you going. I strongly recommend setting up a serializer to validate your query parameters though.

class ParamValidationSerializer(serializers.Serializer):
    post_id = serializers.IntegerField()

Then change your post function to:

def post(self, request, *args, **kwargs):
    serializer = ParamValidationSerializer(data={'post_id': kwargs.get('pk')})
    serializer.is_valid(raise_exception=True)
    message = Message(
        user = request.user,
        post = self.get_post(serializer.data.get('post_id')),
        body = request.POST.get('body')
    )
    message.save()
    return super(PostDetailView,self).post(request, *args, **kwargs)