El libro de Django 1.0

7.4. Procesamiento de los datos suministrados

Una vez que el usuario ha llenado el formulario al punto de que pasa nuestras reglas de validación, necesitamos hacer algo útil con los datos. En este caso, deseamos construir un correo electrónico que contenga los comentarios del usuario, y enviarlo. Para esto, usaremos el paquete de correo electrónico de Django.

Pero antes, necesitamos saber si los datos son en verdad válidos, y si lo son, necesitamos una forma de accederlos. El framework de formularios hace más que validar los datos, también los convierte a tipos de datos de Python. Nuestro formulario para comentarios sólo trata con texto, pero si estamos usando campos como IntegerField o DateTimeField, el framework de formularios se encarga de que se devuelvan como un valor entero de Python, o como un objeto datetime, respectivamente.

Para saber si un formulario está vinculado (bound) a datos válidos, llamamos al método is_valid():

form = ContactForm(request.POST)
if form.is_valid():
    # Process form data

Ahora necesitamos acceder a los datos. Podríamos sacarlos directamente del request.POST, pero si lo hiciéramos, no nos estaríamos beneficiando de la conversión de tipos que realiza el framework de formularios. En cambio, usamos form.clean_data:

if form.is_valid():
    topic = form.clean_data['topic']
    message = form.clean_data['message']
    sender = form.clean_data.get('sender', '[email protected]')
    # ...

Observa que dado que sender no es obligatorio, proveemos un valor por defecto por si no fue proporcionado. Finalmente, necesitamos registrar los comentarios del usuario. La manera más fácil de hacerlo es enviando un correo electrónico al administrador del sitio. Podemos hacerlo empleando la función:

from django.core.mail import send_mail

# ...

send_mail(
    'Feedback from your site, topic: %s' % topic,
    message, sender,
    ['[email protected]']
)

La función send_mail tiene cuatro argumentos obligatorios: el asunto y el cuerpo del mensaje, la dirección del emisor, y una lista de direcciones destino. send_mail es un código conveniente que envuelve a la clase EmailMessage de Django. Esta clase provee características avanzadas como adjuntos, mensajes multiparte, y un control completo sobre los encabezados del mensaje.

Una vez enviado el mensaje con los comentarios, redirigiremos a nuestro usuario a una página estática de confirmación. La función de la vista finalizada se ve así:

from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.mail import send_mail
from forms import ContactForm

def contact(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            topic = form.clean_data['topic']
            message = form.clean_data['message']
            sender = form.clean_data.get('sender', '[email protected]')
            send_mail(
                'Feedback from your site, topic: %s' % topic,
                message, sender,
                ['[email protected]']
            )
            return HttpResponseRedirect('/contact/thanks/')
    else:
        form = ContactForm()
    return render_to_response('contact.html', {'form': form})

Nota Si un usuario selecciona actualizar sobre una página que muestra una consulta POST, la consulta se repetirá. Esto probablemente lleve a un comportamiento no deseado, por ejemplo, que el registro se agregue dos veces a la base de datos. Redirigir luego del POST es un patrón útil que puede ayudar a prevenir este escenario. Así que luego de que se haya procesado el POST con éxito, redirige al usuario a otra página en lugar de retornar HTML directamente.