Home > Software engineering >  IntegrityError at /blog/5 NOT NULL constraint failed: blog_comment.post_id
IntegrityError at /blog/5 NOT NULL constraint failed: blog_comment.post_id

Time:08-30

I'm trying to implement a comment section in my blog that looks as follows: enter image description here

I don't have a user or post name input because it should take as input the request user and the post ID of the post where it's making the comment.

My Comment model:

class Comment(models.Model):
post = models.ForeignKey(
    Post, on_delete=models.CASCADE)
body = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
approved_comment = models.BooleanField(default=False)

class Meta:
    ordering = ['-created_on']

def __str__(self):
    max_len = 75

    if len(self.body) > max_len:
        string = self.body[:max_len]   "..."
    else:
        string = self.body
    return string

Comment form:

class CommentForm(forms.ModelForm):

class Meta:
    model = Comment
    fields = ('body',)
    exclude = ['user', 'post', ]

View function:

def get_post_details(request, post_id):

unique_post = Post.objects.get(id=post_id)
all_comments = Comment.objects.filter(post=unique_post)

new_comment = None

if request.method == 'POST':
    comment_form = CommentForm(data=request.POST)

    if comment_form.is_valid():
        new_comment = comment_form.save(commit=True)
        new_comment.post = unique_post
        new_comment.user = request.user
        new_comment.save()
        return get_post_details(request, post_id)
else:
    comment_form = CommentForm()

context_dict = {
    'post': unique_post,
    'comments': all_comments,
    'new_comment': new_comment,
    'comment_form': comment_form
}

return render(request, 'blog/post_details.html', context=context_dict)

I'm not sure what's missing, but when I try to add a comment I get the below error:

    Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/blog/5

Django Version: 4.1
Python Version: 3.10.6
Installed Applications:
['blog',
 'crispy_forms',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)

The above exception (NOT NULL constraint failed: blog_comment.post_id) was the direct cause of the following exception:
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/workspaces/76966637/Personal/blog_project/diyblog/blog/views.py", line 49, in get_post_details
    new_comment = comment_form.save(commit=True)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/forms/models.py", line 548, in save
    self.instance.save()
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/base.py", line 831, in save
    self.save_base(
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/base.py", line 882, in save_base
    updated = self._save_table(
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/base.py", line 1025, in _save_table
    results = self._do_insert(
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/base.py", line 1066, in _do_insert
    return manager._insert(
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/query.py", line 1790, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1657, in execute_sql
    cursor.execute(sql, params)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 103, in execute
    return super().execute(sql, params)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 67, in execute
    return self._execute_with_wrappers(
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 84, in _execute
    with self.db.wrap_database_errors:
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/utils.py", line 89, in _execute
    return self.cursor.execute(sql, params)
  File "/workspaces/76966637/Personal/blog_project/blogenv/lib/python3.10/site-packages/django/db/backends/sqlite3/base.py", line 357, in execute
    return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /blog/5
Exception Value: NOT NULL constraint failed: blog_comment.post_id

I've searched all over stackoverflow and the issue always seemed to be that the user was forgetting to add the comment.post = post section on the view, but I have that defined.

Any help is appreciated!

CodePudding user response:

The reason this fails is because the commit=True, which thus aims to save the item.

But likely a more robust way to do this, is to inject that data in the instance wrapped in the form directly, so:

from django.shortcuts import get_object_or_404, redirect

def get_post_details(request, post_id):
    unique_post = get_object_or_404(Post, pk=post_id)
    all_comments = Comment.objects.filter(post=unique_post)
    if request.method == 'POST':
        comment_form = CommentForm(data=request.POST, request.FILES)
        if comment_form.is_valid():
            comment_form.instance.post = unique_post
            comment_form.instance.user = request.user
            comment_form.save()
            return redirect(get_post_details, post_id)
    else:
        comment_form = CommentForm()
    
    context = {
        'post': unique_post,
        'comments': all_comments,
        'comment_form': comment_form
    }
    return render(request, 'blog/post_details.html', context)
  • Related