Django Docs for Forms - Alternative Pattern from Advanced Django Forms Usage talk?

79 views
Skip to first unread message

Victor Hooi

unread,
Oct 22, 2011, 8:57:52 PM10/22/11
to django-d...@googlegroups.com
heya,

Disclaimer: This is about the the Django Docs, and a possible suggestion for it - apologies if this isn't the correct group (but I didn't think it quite fell into django-users).

The official Django Docs for forms offers up the following pattern for Form view code:

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,
    })


I was just viewing a talk by pydanny and Miguel Araujo at DjangoCon US 2011 on "Advanced Django Form Usage", and they offered up what they seem to feel was a better pattern for form viewcode:

def some_view(request, template_name="someapp/someform.html")
    form = MyForm(request.POST or None)
    if form.is_valid():
        do_x()
        return redirect('Home')
    return render(request, template_name {'form': form}).


Now, apart from being shorter, I don't think I know enough about Django or forms to know which one is actually "better" overall. However, what's the community's consensus on this?

If it is better, is there any scope for having it in the official Django docs? Or even adding it as an alternative approach, and discussing the pros/cons?

Cheers,
Victor

Carl Meyer

unread,
Oct 22, 2011, 10:48:34 PM10/22/11
to django-d...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi Victor,

On 10/22/2011 06:57 PM, Victor Hooi wrote:
> /Disclaimer: This is about the the Django Docs, and a possible


> suggestion for it - apologies if this isn't the correct group (but I
> didn't think it quite fell into django-users).

No worries, you've got the right list. Developing the Django docs is
part of developing Django, and this list is about developing Django.

I think this might have been mentioned in an audience question at that
talk: the shorter code does have an edge-case problem. It is possible
for request.method to be "POST" and for request.POST to be empty.
(Browsers generally won't do that, they'll submit empty strings; but
forms are useful for validating data from other sources as well, such as
API clients). For some (less common) forms, this could even be a valid
form submission (if no fields are required). In the other cases, it
should really return a bound, not-valid form, with one or more "This
field is required" validation errors. With the shorter code, it will
instead return the unbound form again.

This problem can be fixed by changing the form instantiation to:

form = MyForm(request.POST if request.method == "POST" else None)

At this point, though, I'm no longer convinced that it's much simpler or
more readable.

The other advantage of the longer version is that if you need to add
request.FILES handling to the form, for instance, it's clearer and
simpler how to do that.

> If it is better, is there any scope for having it in the official Django
> docs? Or even adding it as an alternative approach, and discussing the
> pros/cons?

I think the issues with the short version are subtle and advanced enough
that they'd be a serious distraction at that point in the docs, and the
gain just isn't worth the need to introduce that discussion. The
currently-documented version is good enough (TM), and it's more explicit
about what's going on.

Carl
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk6jgIIACgkQ8W4rlRKtE2dIzACgt4lh06OKTeCyb1cGPnKKYq8h
twUAoM21MaExW6uLk/DxgUzaKcbwEQFb
=EWnD
-----END PGP SIGNATURE-----

Russell Keith-Magee

unread,
Oct 23, 2011, 3:10:30 AM10/23/11
to django-d...@googlegroups.com
On Sun, Oct 23, 2011 at 10:48 AM, Carl Meyer <ca...@oddbird.net> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1

Yes, it was raised -- by me :-)

In my opinion, "MyForm(request.POST or None)" is an antipattern -- it
saves you a line of code, and one level of indentation; but it
obscures the distinction between POST and GET requests, is fragile in
the case of empty POST dictionaries, and doesn't work as a shortcut as
soon as you have other POST specific form pre-processing.

Part of good programming practice is ensuring that your code is easy
to read, and being explicit about the fact that you're handling a POST
is just good practice IMHO.

I'd be -1 on adding any reference to this shortcut as a suggested or
alternate rendition of form handling as part of Django's official
documentation. Anyone with enough Python experience will be able to
work out that this shortcut is possible. The only reason I can think
of to include mention of this shortcut in Django's documentation would
be as a cautionary note for what *not* to do.

Yours,
Russ Magee %-)

Daniel Greenfeld

unread,
Oct 24, 2011, 1:36:25 AM10/24/11
to django-d...@googlegroups.com
One of the things that I think would be wonderful is to see this and other issues such as server specific settings actually described in a Django best practices document. And not as part of the wiki.

Alex Gaynor

unread,
Oct 24, 2011, 1:52:08 AM10/24/11
to django-d...@googlegroups.com
Danny, I think you meant that for a different thread.

Alex

On Mon, Oct 24, 2011 at 1:36 AM, Daniel Greenfeld <pyd...@gmail.com> wrote:
One of the things that I think would be wonderful is to see this and other issues such as server specific settings actually described in a Django best practices document. And not as part of the wiki.

--
You received this message because you are subscribed to the Google Groups "Django developers" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-developers/-/x2P5VD53QTsJ.

To post to this group, send email to django-d...@googlegroups.com.
To unsubscribe from this group, send email to django-develop...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.



--
"I disapprove of what you say, but I will defend to the death your right to say it." -- Evelyn Beatrice Hall (summarizing Voltaire)
"The people's good is the highest law." -- Cicero

Reply all
Reply to author
Forward
0 new messages