Django, IntegrityError, NOT NULL constraint failed: ask_response.postinfo_id

Viewed 130

I am new to Django and I have been following some YouTube tutorials to understand it's concepts. The website that I am creating is a blog/forum. Now I came to the part where I have to implement the comments for the user's posts, I created the model for the responses, and bonded it with the actual post. Everything works just fine when I add a response/comment for a specific post from the admin page, but when I try to add a new response/comment from the template form it gives me an error like this: IntegrityError at /question-1 NOT NULL constraint failed: ask_response.postinfo_id

I assume it must be something about the form that doesn't want to work, but I cannot understand what.

Here is the models.py:

class PostInfo(models.Model):
      title = models.CharField(max_length=70)
      content = models.TextField(max_length=5000)
      date_posted = models.DateTimeField(default=timezone.now)
      author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
      likes = models.ManyToManyField(User, related_name="blog_posts")
      views = models.IntegerField(default=0)

class Response(models.Model):
      user = models.ForeignKey(User, on_delete=models.CASCADE)
      postinfo = models.ForeignKey(PostInfo, on_delete=models.CASCADE, related_name="responses")
      body = models.TextField()
      date_published = models.DateTimeField(default=timezone.now)

Views.py:

def detailed_view(request, pk):
     post = get_object_or_404(PostInfo.objects.filter(id=pk))
     comments = post.responses.all()
     new_comment = None

     if request.method == 'POST':
         comment_form = ResponseForm(data=request.POST)
         if comment_form.is_valid():
             new_comment = comment_form.save(commit=False)
             new_comment.post = post
             new_comment.save()
     else:
         comment_form = ResponseForm()

     return render(request, 'homepage/post_detailed_view.html', {'post': post,
                                                            'comments': comments,
                                                            'new_comment': new_comment,
                                                            'comment_form': comment_form})

And here is the form from the template:

<div class="col-md-8 card mb-4  mt-3 ">
    <div class="card-body">
        {% if new_comment %}
        <div class="alert alert-success" role="alert">
            Your comment is awaiting moderation
        </div>
        {% else %}
        <h3>Leave a comment</h3>
        <form method="post" style="margin-top: 1.3em;">
            {{ comment_form.as_p }}
            {% csrf_token %}
            <button type="submit" class="btn btn-primary  btn-lg"">Submit</button>
        </form>
        {% endif %}
    </div>
</div>

Thank you very much for your help in advance.

1 Answers

You need to set the .post_info field, not .post, since there is no such field defined in the Response model:

def detailed_view(request, pk):
    post = get_object_or_404(PostInfo, id=pk)
    comments = post.responses.all()
    new_comment = None
    if request.method == 'POST':
        comment_form = ResponseForm(data=request.POST)
            if comment_form.is_valid():
                form.instance.post_info = post
                form.instance.user = request.user
                form.save()
                return redirect('name-of-some-view')
    else:
         comment_form = ResponseForm()
    context = {'post': post,
               'comments': comments,
               'new_comment': new_comment
               'comment_form': comment_form
    }
    return render(request, 'homepage/post_detailed_view.html', context)

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.

Related