I'm trying to make it possible to add comments on my blog, but I'm getting the following error when I try to submit the comment:
"Field 'id' expected a number but got 'hellooo'."
Views.py:
class AddComment(generic.CreateView):
model = Comment
form_class = AddComment
template_name = 'add_comment.html'
def form_valid(self, form):
form.instance.post_id = self.kwargs['slug']
return super().form_valid(form)
success_url = reverse_lazy('blog')
forms.py:
class AddComment(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'body')
widgets = {
'Name': forms.TextInput(attrs={'class': 'form-control'}),
'body': forms.Textarea(attrs={'class': 'form-control'}),
}
models.py:
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete= models.CASCADE, related_name='comments')
name = models.CharField(max_length=255)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.post.title, self.name)
urls.py:
from . import views
from django.urls import path
urlpatterns = [
path('', views.PostList.as_view(), name='blog'),
path('add_post/', views.AddPost.as_view(), name='add_post'),
path('edit_post/<slug:slug>/', views.EditPost.as_view(), name='edit_post'),
path('delete_post/<slug:slug>/', views.DeletePost.as_view(), name='delete_post'),
path('<slug:slug>/comment/', views.AddComment.as_view(), name='add_comment'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
As you've correctly figured out, the problem is on how you assign the value to form.instance.post_id
.
The post
field of the Comment
model should be an object. You can also work with post_id, and then it needs to be an integer. You assign it a string (slug) which will not work in either case.
As you only have the slug, you should fetch either the Post object or its id before assigning it to the field.
class AddComment(generic.CreateView):
model = Comment
form_class = AddComment
template_name = 'add_comment.html'
def form_valid(self, form):
# Get the slug
slug = self.kwargs['slug']
# Assign as an object
form.instance.post = Post.objects.get(slug=slug)
# Or assign as an integer id
# form.instance.post_id = Post.objects.get(slug=slug).pk
return super().form_valid(form)
success_url = reverse_lazy('blog')