The standard pattern for the view logic for Django forms is thus:
def contact(request):
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
This is fine in simple cases but quite easily descends into a complex mass of nested IF statements if your application logic gets a bit more complex.
Can anyone share their own cleaner approaches that avoid nested IF's and logic that depends on fall-through cases?
I'd be particularly interested in answers that don't rely on additional 3rd party apps.
One of the included class based views is FormView
(documentation). The two main methods you'd be concerned with are form_valid
and form_invalid
.
from django.views.generic import FormView
from myapp.forms import MyForm
class MyView(FormView):
template_name = 'edit_something.html'
form_class = MyForm
success_url = '/success/' # you should use `reverse`, but let's stay focused.
def form_valid(self, form):
"""
This is what's called when the form is valid.
"""
return super(MyView, self).form_valid(form)
def form_invalid(self, form):
"""
This is what's called when the form is invalid.
"""
return self.render_to_response(self.get_context_data(form=form))
Alternatively you can override post
, get
or put
methods and handle the form according to each type of request.
This is shortest approach I found:
def contact(request):
# if it's POST request it'll have data else it'll be unbound
form = ContactForm(request.POST or None)
if request.method == 'POST' and form.is_valid():
# Process the data in form.cleaned_data
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
return render_to_response('contact.html', { 'form': form, })
of course if you don't like nested if you could try reversing logic:
def contact(request):
template = 'contact.html'
if request.method != 'POST': # GET return:
return render_to_response(template, {'form': ContactForm()})
form = ContactForm(request.POST)
if not form.is_valid(): # FAIL return:
return render_to_response(template, {'form': form})
# here logic if user posted form and it's clean:
return HttpResponseRedirect('/thanks/')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With