El libro de Django 1.0

7.7. Creando formularios a partir de Modelos

Construyamos algo un poquito más interesante: un formulario que suministre los datos de un nuevo publicista a nuestra aplicación de libros del Capítulo 5.

Una regla de oro que es importante en el desarrollo de software, a la que Django intenta adherirse, es: no te repitas (del inglés Don't Repeat Yourself, abreviado DRY). Andy Hunt y Dave Thomas la definen como sigue, en The Pragmatic Programmer:

Cada pieza de conocimiento debe tener una representación única, no ambigua, y de autoridad, dentro de un sistema.

Nuestro modelo de la clase Publisher dice que un editor tiene un nombre, un domicilio, una ciudad, un estado o provincia, un país, y un sitio web. Si duplicamos esta información en la definición del formulario, estaríamos quebrando la regla anterior. En cambio, podemos usar este útil atajo: form_for_model():

from models import Publisher
from django.newforms import form_for_model

PublisherForm = form_for_model(Publisher)

PublisherForm es una subclase de Form, tal como la clase ContactForm que creamos manualmente con anterioridad. Podemos usarla de la misma forma:

from forms import PublisherForm

def add_publisher(request):
    if request.method == 'POST':
        form = PublisherForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/add_publisher/thanks/')
    else:
        form = PublisherForm()
    return render_to_response('books/add_publisher.html', {'form': form})

El archivo add_publisher.html es casi idéntico a nuestra plantilla contact.html original, así que la omitimos. Recuerda además agregar un nuevo patrón al URLconf: (r'^add_publisher/$', 'mysite.books.views.add_publisher').

Ahí se muestra un atajo más. Dado que los formularios derivados de modelos se emplean a menudo para guardar nuevas instancias del modelo en la base de datos, la clase del formulario creada por form_for_model incluye un conveniente método save(). Este método trata con el uso común; pero puedes ignorarlo si deseas hacer algo más que tenga que ver con los datos suministrados.

form_for_instance() es un método que está relacionado con el anterior, y puede crear formularios preinicializados a partir de la instancia de un modelo. Esto es útil al crear formularios "editar".