I'm trying to implement a comment section in my blog that looks as follows:
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)