1

I'm building a forum with comment and Reply capabilities. While populating the form I'm facing a issue of

Cannot assign "<Post: Post object (10)>": "Reply.comment" must be a "Comment" instance. I can understand the problem but don't know how to morph it into a Comment Instance. I'm using Django 3.1.4

The Models are as follows:

class Post(models.Model):
    headline = models.CharField(max_length = 100)
    context = models.TextField()
    author = models.ForeignKey(User, on_delete = models.CASCADE)
    created = models.DateTimeField(auto_now_add = True)
    modified = models.DateTimeField(auto_now = True)


class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete = models.CASCADE)
    text = models.TextField(max_length = 200)
    author = models.ForeignKey(User, on_delete = models.CASCADE)
    created = models.DateTimeField(auto_now_add = True)
    modified = models.DateTimeField(auto_now = True)


class Reply(models.Model):
    comment = models.ForeignKey(Comment, related_name='replies',  on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    timestamp = models.DateTimeField(auto_now_add=True)
    reply = models.TextField()

views.py is as follows:

class PostDetail(DetailView):
    model = Post

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['comment_form'] = CommentForm()
        context['reply_form'] = ReplyForm()
        return context
 
    def post(self, request, *args, **kwargs):
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            comment = Comment(
                author = request.user, 
                post = self.get_object(),
                text = comment_form.cleaned_data['comment']
            )
            comment.save()
        else:
            comment = Comment()

        reply_form = ReplyForm(request.POST)
        if reply_form.is_valid():
            reply = Reply(
                user = request.user, 
                comment = self.get_object(), # This line is the issue!!!
                reply = reply_form.cleaned_data['reply']
            )
            reply.save()
        else:
            reply = Reply()     
        return redirect (reverse('postdetail', args=[self.get_object().id]))

I guess this much info will be sufficient. Really need to understand how to go about this.

Thanks

  • You need to pass the comment object not the post object from get_object – Iain Shelvington Dec 21 '20 at 05:45
  • @IainShelvington could you guide me how to do it. I'm having trouble figuring hoe do it. I'm relatively new to Django. It would really mean alot – Retik Singh Dec 21 '20 at 06:27
  • Seems like there may be multiple comments on the page, how do you know which comment is being replied to? – Iain Shelvington Dec 21 '20 at 06:40
  • @IainShelvington I have filtered that in the template by running a loop and then filtering the replies associated to that comment – Retik Singh Dec 21 '20 at 07:00
  • {% for comment in object.comment_set.all %}
  • {{ comment.author }} : {{ comment.text }}
    {% csrf_token %} {{ reply_form.as_p }}

    {% for reply in comment.reply_set.all %}
  • {{reply.user}} : {{reply.reply}}

  • {% endfor %} {% endfor %} I have tried something like this – Retik Singh Dec 21 '20 at 07:05
  • Am I correct in thinking that a user will only ever submit a comment or a reply never both at the same time? – Iain Shelvington Dec 21 '20 at 07:23
  • Yes indeed that is the case – Retik Singh Dec 21 '20 at 07:26
  • I would suggest splitting your views so that each one handles a single action, having a single view handling 3 different actions including 2 different forms makes for some complex code. I'll post an answer with some code in a bit – Iain Shelvington Dec 21 '20 at 07:35
  • Thanks man. Really appreciate the help. Waiting for the code too. – Retik Singh Dec 21 '20 at 07:36