Mutiple Forms With Class Based View. How to show errors on one page?
views.py
from forms.py import PersonCreateForm
class PersonCreateView(CreateView):
model = Person
form_class = PersonCreateForm
template_name = "my_app/create_person.html"
def form_valid(self, form):
self.object = form.save()
return redirect('/homepage/')
class PeopleListView(ListView):
[...]
context.update({
'task_form': TaskCreateForm(),
return context
In my template, I just add an action url that the PersonCreateView handles.
<form action="{% url 'people_create' %}" method="post">{% csrf_token %}
When the form is valid, all data is saved without issue and redirects me to the page / main page. But when my form is invalid it redirects me to {% url 'people_create' %}
and shows errors to / homepage / people _create /
How can I avoid this? I want all errors to be displayed on one page without redirecting.
source to share
Process the form in the same view that you create it, otherwise the page will change. You can mix django.views.generic.edit.ModelFormMixin
into PeopleListView
yours so that it has most of the features you need.
class PeopleListView(ModelFormMixin, ListView):
success_url = '/homepage/' # should use reverse() here
def get_context_data(self, **kwargs):
# only add the form if it is not already given to us
if not 'task_form' in kwargs:
kwargs['task_form'] = self.get_form()
return super(PeopleListView, self).get_context_data(**kwargs)
def post(self, request, *args, **kwargs):
# ListView won't have a post method, we define one
form = self.get_form()
if form.is_valid():
return self.form_valid(form) # default behavior will save and redirect
else:
return self.form_invalid(form) # default behavior has to be overridden (see below)
def form_invalid(self, form):
# Whatever you wanna do. This example simply reloads the list
self.object_list = self.get_queryset()
context = self.get_context_data(task_form=form)
return self.render_to_response(context)
There are three code paths there:
- The initial display will load the list as usual, only an empty form will be added to the context.
- On submitting valid input, a method is called
form_valid
that will be redirected to/homepage/
. - When an invalid input is submitted, our overridden method is called
form_invalid
, which will render the page normally, except that the form will contain validation errors.
You can make the whole thing a little more persistent by using the caching property for the form, but then you start working with Django-provided views instead, and you can also just use the base class View
and implement all the logic yourself. I would stick with the Django views, but ymmv.
source to share