Search code examples
pythondjangocommentsblogs

Field 'id' expected a number but got 'hellooo' - Django Blog Comments


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'),
]

Solution

  • 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')