You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django报错:无法赋值"<Product: Test Product>","Reply.comment"必须为"Comment"实例的解决方法咨询

Fixing "Cannot assign : Reply.comment must be a Comment instance" Error

Error Cause

The error pops up because when creating a Reply in your post method, you’re passing a Product object (from self.get_object()) to the comment field of Reply. Since your view is a DetailView for Product, self.get_object() returns the current product—but the Reply model’s comment field expects a Comment instance, not a Product.

Plus, your get_context_data method has a similar issue: Reply.objects.filter(comment=self.get_object()) tries to filter replies by a product, which won’t work because comment requires a Comment object.


Step-by-Step Fixes

1. Correctly Fetch Replies in get_context_data

Use Django’s double-underscore syntax to traverse the foreign key between Comment and Product to get all replies linked to the current product’s comments:

def get_context_data(self , **kwargs):
    data = super().get_context_data(**kwargs)
    connected_comments = Comment.objects.filter(product=self.get_object())
    number_of_comments = connected_comments.count()
    data['comments'] = connected_comments
    data['no_of_comments'] = number_of_comments
    data['comment_form'] = CommentForm()
    
    # Fix: Get replies tied to comments of the current product
    connected_replies = Reply.objects.filter(comment__product=self.get_object())
    number_of_replies = connected_replies.count()
    data['replies'] = connected_replies
    data['no_of_replies'] = number_of_replies
    data['reply_form'] = ReplyForm()
    return data

2. Update the post Method to Handle Replies Properly

You need to distinguish between comment and reply submissions, and fetch the specific Comment the reply is targeting:

def post(self , request , *args , **kwargs):
    # Use a hidden field to identify which form was submitted
    form_type = request.POST.get('form_type')
    
    if form_type == 'reply':
        reply_form = ReplyForm(request.POST)
        if reply_form.is_valid():
            content = reply_form.cleaned_data['content']
            comment_id = request.POST.get('comment_id')
            
            try:
                # Fetch the Comment instance the reply belongs to
                comment = Comment.objects.get(id=comment_id)
                new_reply = Reply(content=content, author=self.request.user, comment=comment)
                new_reply.save()
            except Comment.DoesNotExist:
                # Optional: Add an error message if the comment doesn't exist
                pass
            
            return redirect(self.request.path_info)
    
    elif form_type == 'comment':
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            content = comment_form.cleaned_data['content']
            new_comment = Comment(content=content, author=self.request.user, product=self.get_object())
            new_comment.save()
            return redirect(self.request.path_info)
    
    # Fall back to the page if no valid form submission
    return self.get(request, *args, **kwargs)

3. Add Hidden Fields to Your Template

Update product_feedback.html to include hidden inputs that tell the view which form is being submitted, and pass the comment ID for replies:

Comment Form:
<form method="POST">
    {% csrf_token %}
    <input type="hidden" name="form_type" value="comment">
    {{ comment_form.as_p }}
    <button type="submit">Add Comment</button>
</form>
Reply Forms (Inside the Comment Loop):
{% for comment in comments %}
    <div class="comment">
        <p><strong>{{ comment.author.username }}:</strong> {{ comment.content }}</p>
        
        <!-- Reply Form -->
        <form method="POST" class="reply-form">
            {% csrf_token %}
            <input type="hidden" name="form_type" value="reply">
            <input type="hidden" name="comment_id" value="{{ comment.id }}">
            {{ reply_form.as_p }}
            <button type="submit">Post Reply</button>
        </form>
        
        <!-- Display Replies for This Comment -->
        {% for reply in comment.reply_set.all %}
            <p class="reply"><strong>{{ reply.author.username }}:</strong> {{ reply.content }}</p>
        {% endfor %}
    </div>
{% endfor %}

Why This Works

  • The form_type hidden field lets the view know whether to process a comment or reply submission.
  • The comment_id hidden field passes the ID of the comment being replied to, so we can fetch the correct Comment instance to assign to the new Reply.
  • The updated get_context_data correctly fetches all replies linked to the current product’s comments using comment__product.

内容的提问来源于stack exchange,提问作者static-man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 16:42:43