Files
deb-python-django-formtools/docs/preview.rst
2016-05-28 11:56:26 -04:00

4.3 KiB

Form preview

formtools.preview

Django comes with an optional "form preview" application that helps automate the following workflow:

"Display an HTML form, force a preview, then do something with the submission."

To force a preview of a form submission, all you have to do is write a short Python class.

Overview

Given a ~django.forms.Form subclass that you define, this application takes care of the following workflow:

  1. Displays the form as HTML on a Web page.
  2. Validates the form data when it's submitted via POST.
    1. If it's valid, displays a preview page.
    2. If it's not valid, redisplays the form with error messages.
  3. When the "confirmation" form is submitted from the preview page, calls a hook that you define -- a ~FormPreview.done() method that gets passed the valid data.

The framework enforces the required preview by passing a shared-secret hash to the preview page via hidden form fields. If somebody tweaks the form parameters on the preview page, the form submission will fail the hash-comparison test.

How to use FormPreview

  1. Point Django at the default FormPreview templates. There are two ways to do this:

    • Add 'formtools' to your INSTALLED_APPS setting.

      This will work if your TEMPLATES setting includes the app_directories template loader (which is the case by default).

      See the template loader docs <template-loaders> for more.

    • Otherwise, determine the full filesystem path to the formtools/templates directory and add that directory to your DIRS <TEMPLATES-DIRS> option in the TEMPLATES setting.

  2. Create a ~FormPreview subclass that overrides the done() method:

    from django.http import HttpResponseRedirect
    
    from formtools.preview import FormPreview
    from myapp.models import SomeModel
    
    class SomeModelFormPreview(FormPreview):
    
        def done(self, request, cleaned_data):
            # Do something with the cleaned_data, then redirect
            # to a "success" page.
            return HttpResponseRedirect('/form/success')

    This method takes an ~django.http.HttpRequest object and a dictionary of the form data after it has been validated and cleaned. It should return an ~django.http.HttpResponseRedirect that is the end result of the form being submitted.

  3. Change your URLconf to point to an instance of your ~FormPreview subclass:

    from django import forms
    
    from myapp.forms import SomeModelForm
    from myapp.preview import SomeModelFormPreview

    ...and add the following line to the appropriate model in your URLconf:

    url(r'^post/$', SomeModelFormPreview(SomeModelForm)),

    where SomeModelForm is a Form or ModelForm class for the model.

  4. Run the Django server and visit /post/ in your browser.

FormPreview classes

A ~FormPreview class is a simple Python class that represents the preview workflow. ~FormPreview classes must subclass FormPreview and override the done() method. They can live anywhere in your codebase.

FormPreview templates

FormPreview.form_template

FormPreview.preview_template

By default, the form is rendered via the template formtools/form.html, and the preview page is rendered via the template formtools/preview.html.

These values can be overridden for a particular form preview by setting ~FormPreview.preview_template and ~FormPreview.form_template attributes on the FormPreview subclass. See formtools/templates for the default templates.

Required methods

FormPreview.done

Optional methods

FormPreview.get_auto_id

FormPreview.get_initial

FormPreview.get_context

FormPreview.parse_params

FormPreview.process_preview

FormPreview.security_hash

FormPreview.failed_hash