简体   繁体   中英

CharField of Form not showing up in Django Project

I have created Comment Model for my Project but the CharField is not showing in the LocalHost for some reason.

The submit button is working but there is no field to place text. I am trying to know why the CharField is not showing and how to show it in the website?

Here is the models.py

class Comment(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    body = models.TextField(max_length=300)

    def __str__(self):
        return f"{self.post}-{self.user}-Comment No.{self.pk}"

Here is the views:

class Comment_create(CreateView):
    model = Comment
    fields = ['body']
    template_name = 'blog/post_detail.html'
    form = CommentModelForm

    def form_valid(self, form):
        post = get_object_or_404(Post, slug=self.kwargs['slug'])
        form.instance.user = self.request.user
        form.instance.post = post
        return super().form_valid(form)

    def form_invalid(self, form):
        return HttpResponseRedirect(self.get_success_url())

    def get_success_url(self):
        return reverse('blog:post-detail', kwargs=dict(slug=self.kwargs['slug']))

Here is the forms.py

class CommentModelForm(forms.ModelForm):
    body = forms.CharField(label='',
                            widget=forms.TextInput(attrs={'placeholder': 'Add a comment...'}))
    class Meta:
        model = Comment
        fields = ('body',)

Here is the urls.py

    path('blogs/<slug:slug>/comment/',
         Comment_create.as_view(), name='comment-post'),

Here is the template:

            <div class="container-fluid mt-2">
                <div class="form-group row">

                    <form action="{% url 'blog:comment-post' post.slug %}" method="post" class="comment-form" action=".">
                    {% csrf_token %}
                    {{ form }}
                    <input type="submit" value="Submit" class="btn btn-outline-success">
                    </form>

                </div>
            </div>

In your code, you made a mistake declaring form = CommentModelForm . This is incorect, the correct attribute is form_class , so:

class Comment_create(CreateView):
    model = Comment
    # fields = ['body']  # <--- this is redundant, since you already specified it in yout modelform 
    template_name = 'blog/post_detail.html'
    # form = CommentModelForm       <--- this is wrong
    form_class = CommentModelForm # <--- this is the correct signature

    # the rest of the view


Next, in your ModelForm, it is redundant to specify body field, since you already declared it in the Meta section:

class CommentModelForm(forms.ModelForm):
    # body = forms.CharField(label='',
    #                        widget=forms.TextInput(attrs={'placeholder': 'Add a comment...'}))
    # This is redundand. You can specify input widget in Meta section

    class Meta:
        model = Comment
        fields = ('body',)

If you want to modify the widgets look and feel, you can do it in the Meta section like this:

    # previous code

    class Meta:
        model = Comment
        fields = ['body',]
        labels  = {
                     'body':'your label'
                   }
        widgets = {
             'body' : Textarea(attrs={
                 'rows': '9',
                 'cols': '80',
             }),
          }

[EDIT: Missing {{form}} in template]

If you are missing form in your template context, that would be very strange, if you have shown us all you do in your views/forms. The context is usually populated by default, so you should have the lines:

            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],

set in your settings.py of the project.

You can always manually check if everything is ok, by overriding the context data function and populating it yourself:

# in your create view:
class Comment_create(CreateView):
    #def all the other definitions and then override:
    def get_context_data(self,**kwargs):
        context = super().get_context_data(**kwargs) # <-- this should populate your form, but let us do it manually nonetheless
        form = self.form_class(self.request.POST or None)
        context['form'] = form
        return context

If this fails to work as well, then the issue is somewhere else, I believe.

Also, I see you set action attribute in your <form> tag of the template twice. That is also wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM