Notes 11/19 on form processing

Avoid hard-coding settings

We previously specified absolute paths for templates and static files based on /home/liucs/cs690/ but it’s much nicer if those paths can adapt based on the location of the project. At the top of settings.py, add these lines:

import os.path
ROOT = os.path.dirname(os.path.dirname(__file__))

Then, you can use os.path.join(ROOT, "static") in place of "/home/liucs/cs690/bookswap/static" and similarly for "templates".

Create a form

You can do this in views.py where you use it, or create a separate forms.py and import it:

from django import forms
class AuthorForm(forms.Form):
    first = forms.CharField(max_length=100)
    last = forms.CharField(max_length=100)
    #sender = forms.EmailField()
    #cc_myself = forms.BooleanField(required=False)

Initially, to display the form, make your view like this:

from django.template import RequestContext
def home(request):
    f = AuthorForm()
    return render_to_response("home.html",
        {'form': f},
        context_instance=RequestContext(request))

and then dump this into the template:

    <form method="POST">
        {% csrf_token %}
        <h2>Add an author</h2>
        {{form.as_p}}
        <input type='submit' value='Add'>
    </form>

That should be enough to display a blank form on the page. When you submit it though, it will just show you another blank form.

Form processing

Time to add the form processing logic to your view. It looks like this:

def home(request):
    if request.method == 'POST':
        f = AuthorForm(request.POST)
        if f.is_valid():
            # Process form
            a = Author(first_name = f.cleaned_data['first'],
                       last_name = f.cleaned_data['last'])
            a.save()
            return HttpResponseRedirect(reverse('author', args=[a.id]))
    else:
        f = AuthorForm()
    return render_to_response("home.html",
        {'form': f},
        context_instance=RequestContext(request))

In this case, to process the form, we are saving a new Author object, and redirecting to a detail page for that author.

The reverse function must be imported:

from django.core.urlresolvers import reverse

and it behaves pretty much like the {% url %} syntax in a template – it uses the short name defined in urls.py to generate a URL for the redirect.