Reputation: 902
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>
Upvotes: 0
Views: 832
Reputation: 401
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.
Upvotes: 1