Last Updated: January 23, 2019
·
9.074K
· scott_woodall

Better Way To Initialize Django Forms

A common way for initializing forms is:

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            # Process the data in form.cleaned_data
            return HttpResponseRedirect('/thanks/')
    else:
        form = ContactForm()

    return render(request, 'contact.html', {
        'form': form,
    })

A better way that DRYs things up and removes a conditional:

def contact(request):
    form = ContactForm(request.POST or None)
    if request.method == "POST" and form.is_valid():
        # Process the data in form.cleaned_data
        return HttpResponseRedirect('/thanks/')

    return render(request, 'contact.html', {
        'form': form,
    })

5 Responses
Add your response

That's not exactly DRY, since there is a boolean test twice on request.POST.
Python is about being explicit and easy to read, not about being short and obscure - that sort of stuff is what Perl handles :) Therefore, I would prefer the first code block.
For more, please refer to the Zen of Python - type "import this" in your python shell.

over 1 year ago ·

Wrote about how to handle forms, that will allow easier customize your view for users of your app - https://coderwall.com/p/ypgd1q. Another thing - you don't need request.method == "POST", except cases when your form is initially already valid.

over 1 year ago ·

No need for the “request.method == "POST"”

over 1 year ago ·

The second code has a bug. If the form contains only checkbox fields, when submitted and none of them are checked, the request.POST variable will be an empty dictionary, evaluated as False.

So, the form will be initialized with None (and consequently unbound). So the is_valid will be always False, even if the form is valid.

over 1 year ago ·

That second snippet is really bad. Hard to read, contains a bug as rennerocha notes, not dry cause there are essentially two checks if the request is a POST request. Don't ever use it, please. The Django way is the correct one or use class based views.

over 1 year ago ·