I am trying to create a comment system for the blog portion of my app with Django. I have attempted to mix my detail view with the form mixin and I'm struggling a bit. When the form is submitted, it doesn't save and no error is present. If any of you can help I would greatly appreciate it.
Here is my View
class DetailPostView(FormMixin, DetailView):
model = Post
template_name = "blog/post_detail.html"
context_object_name = "posts"
form_class = CommentForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form"] = CommentForm
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
return reverse("post-detail", kwargs={"pk": self.object.pk})
The model
class Comment(models.Model):
comment = models.ForeignKey(Post, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
content = models.TextField()
author = models.CharField(max_length=50)
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["-created_on"]
def __str__(self):
return self.title
The reason that this happens is because you construct a new form that you pass to the context data, as a result, it will not render any errors, since you construct a form without validating the request data and render that form, you thus do not display the form that rejected the data in the first place.
But you do not need to do that. Django's FormMixin
[Django-doc] already takes care of that. You thus should not override the .get_context_data(…)
method [Django-doc].
Another problem is that you did not save your form, you can override a the form_valid
method, or you can inherit from ModelFormMixin
[Django-doc].
Finally you better first create the form, and then assign self.object
, otherwise it will pass this as an instance to the form:
from django.views.generic.edit import ModelFormMixin
class DetailPostView(ModelFormMixin, DetailView):
model = Post
template_name = 'blog/post_detail.html'
context_object_name = 'posts'
form_class = CommentForm
# no get_context_data override
def post(self, request, *args, **kwargs):
# first construct the form to avoid using it as instance
form = self.get_form()
self.object = self.get_object()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_success_url(self):
return reverse('post-detail', kwargs={'pk': self.object.pk})