Trabajando con formas

Sobre este documento

Este documento proporciona una introducción a los fundamentos básicos de las formas web y cómo se manejan en Django. Para obtener una visión más detallada de áreas específicas de la API de formularios, consulte La API de Formularios, Campos del formulario y Validación de formularios y campos.

A menos que estés planeando construir sitios web y aplicaciones que no hagan más que publicar contenido y no acepten entrada de tus visitantes, vas a necesitar entender y utilizar formularios.

Django ofrece una variedad de herramientas y bibliotecas para ayudarte a crear formularios que acepten la entrada de los visitantes del sitio, y luego procesar y responder a la entrada.

Formularios HTML

En HTML, un formulario es una colección de elementos dentro de <form>...</form> que permiten a un visitante realizar cosas como introducir texto, seleccionar opciones, manipular objetos o controles, y así sucesivamente, y luego enviar esa información al servidor.

Algunos de estos elementos de interfaz de formulario - entrada de texto o casillas de verificación - están integrados en el propio HTML. Otros son mucho más complejos; una interfaz que muestra un selector de fecha o permite mover un deslizador o manipular controles suele utilizar JavaScript y CSS, así como elementos de formulario HTML <input> para lograr estos efectos.

Además de sus elementos <input>, un formulario debe especificar dos cosas:

  • donde: la URL a la cual deberán devolverse los datos correspondientes a la entrada del usuario

  • Cómo: el método HTTP por el cual se debería devolver los datos

Como ejemplo, el formulario de inicio de sesión para la administración de Django contiene varios elementos <input>: uno de type="text" para el nombre de usuario, uno de type="password" para la contraseña y uno de type="submit" para el botón «Iniciar sesión». También contiene algunos campos de texto ocultos que el usuario no ve, que Django utiliza para determinar qué hacer a continuación.

También le dice al navegador que los datos del formulario deben ser enviados a la URL especificada en el atributo action de <form> - /admin/ - y que debe ser enviado utilizando el mecanismo HTTP especificado por el atributo method - post.

When the <input type="submit" value="Log in"> element is triggered, the data is returned to /admin/.

GET y POST

GET y POST son los únicos métodos HTTP a utilizar cuando se trate de formularios.

La forma de inicio de sesión de Django se devuelve utilizando el método POST, en el que el navegador empaqueta los datos del formulario, los codifica para su transmisión, los envía al servidor y luego recibe la respuesta del servidor.

GET, por contraste, empaqueta los datos enviados en una cadena y utiliza esta cadena para componer una URL. La URL contiene la dirección a la que deben ser enviados los datos, así como las claves y valores de los datos. Puedes ver esto en acción si haces una búsqueda en la documentación de Django, lo que producirá una URL del tipo https://docs.djangoproject.com/search/?q=forms&release=1.

GET y POST se utilizan típicamente para fines diferentes.

Cualquier solicitud que pueda ser utilizada para cambiar el estado del sistema - por ejemplo, una solicitud que realiza cambios en la base de datos - debe utilizar POST. GET solo debería usarse para solicitudes que no afecten el estado del sistema.

GET tampoco sería adecuado para un formulario de contraseña, ya que la contraseña aparecería en la URL y también en los registros del servidor y la historia del navegador, todo en texto plano. Tampoco sería adecuado para grandes cantidades de datos o para datos binarios, como una imagen. Una aplicación web que utiliza solicitudes GET para formularios administrativos es un riesgo para la seguridad: puede ser fácil para un atacante imitar la solicitud del formulario para acceder a partes sensibles del sistema. POST, combinado con otras protecciones como la protección CSRF de Django (<doc>`_CSRF protection </ref/csrf/>), ofrece más control sobre el acceso.

Por otro lado, GET es adecuado para cosas como un formulario de búsqueda web, ya que las URLs que representan una solicitud GET pueden fácilmente ser marcadas como favoritas, compartidas o resubmitidas.

El papel de Django en los formularios

Los formularios son un negocio complejo. Considera el administrador de Django, donde numerosos elementos de datos de varios tipos diferentes pueden necesitar ser preparados para su visualización en un formulario, renderizados como HTML, editados mediante una interfaz conveniente, devueltos al servidor, validados y limpiados, y luego guardados o pasados a otra parte para su procesamiento posterior.

La funcionalidad de formularios de Django puede simplificar y automatizar vastas porciones de este trabajo, y también lo puede hacer con más seguridad que la mayoría de los programadores podrían hacerlo en el código que escribieran ellos mismos.

Django maneja tres partes distintas del trabajo involucrado en formularios:

  • Preparar y reestructurar datos para que estén listos para su renderizado

  • Crear formularios HTML para los datos

  • Recibir y procesar formularios y datos enviados por el cliente

Es posible escribir código que haga todo esto manualmente, pero Django se encarga de ello todo.

Formularios en Django

Hemos descrito brevemente los formularios HTML, pero un formulario HTML <form> es solo una parte de la maquinaria requerida.

En el contexto de una aplicación web, “formulario” podría referirse a ese formulario HTML <form>, o al formulario Django Form que lo produce, o a los datos estructurados devueltos cuando se envía, o a la colección trabajadora de fin a fin de estas partes.

La Form de Django clase

En el corazón de este sistema de componentes está la Form clase de Django. De manera similar a como un modelo Django describe la estructura lógica de un objeto, su comportamiento y la forma en que sus partes se representan para nosotros, una Form clase describe un formulario y determina cómo funciona y aparece.

De manera similar a como los campos de una clase de modelo se mapean con campos de base de datos, los campos de una clase de formulario se mapean con elementos <input> HTML de formulario. (Un ModelForm mapea los campos de una clase de modelo con elementos <input> HTML de formulario a través de un Form; esto es lo que la administración de Django está basada en.)

Los campos de un formulario son ellos mismos clases; gestionan los datos del formulario y realizan la validación cuando se envía el formulario. Una DateField y una FileField manejan tipos muy diferentes de datos y tienen que hacer cosas diferentes con él.

Un campo de formulario se representa a un usuario en el navegador como un «widget» HTML - una pieza de maquinaria de interfaz de usuario. Cada tipo de campo tiene un clase de widget por defecto adecuada, pero estos pueden ser sobrescritos según sea necesario.

Instanciar, procesar y renderizar formularios

Cuando se está renderizando un objeto en Django, generalmente:

  1. obtenemos una referencia a él en la vista (lo recuperamos de la base de datos, por ejemplo)

  2. se lo pasamos al contexto del template

  3. lo expandimos a marcado HTML utilizando variables de plantilla

La renderización de un formulario en una plantilla implica casi el mismo trabajo que la renderización de cualquier otro tipo de objeto, pero hay algunas diferencias clave.

En el caso de una instancia de modelo que no contenía datos, raramente si es útil hacer algo con ella en una plantilla. Por otro lado, hace perfecto sentido renderizar un formulario vacío - eso es lo que hacemos cuando queremos que el usuario lo complete.

Así que cuando manejar una instancia de modelo en una vista, típicamente la recuperamos desde la base de datos. Cuando estamos tratando con un formulario, típicamente lo instanciamos en la vista.

Cuando instanciamos un formulario, podemos optar por dejarlo vacío o prepoblarlo, por ejemplo con:

  • datos de una instancia de modelo guardada (como es el caso de los formularios administrativos para editar)

  • datos que hemos recopilado desde otras fuentes

  • datos recibidos de una solicitud previa de formulario HTML

El último de estos casos es lo más interesante, porque es lo que hace posible que los usuarios no solo lean un sitio web, sino que también envíen información hacia él.

Crear un formulario

El trabajo que necesita hacerse

Supongamos que deseas crear un formulario sencillo en tu sitio web para obtener el nombre del usuario. Necesitarías algo como esto en tu plantilla:

<form action="/your-name/" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

Esto le dice al navegador que devuelva los datos del formulario en la URL /tu-nombre/, utilizando el método POST. Mostrará un campo de texto, etiquetado «Tu nombre:», y un botón marcado «OK». Si el contexto del template contiene una variable current_name, se utilizará para prellenar el campo your_name.

Necesitarás una vista que renderice el plantilla que contiene la forma HTML y que pueda suministrar el campo current_name según corresponda.

Cuando se envía el formulario, la solicitud POST que se envía al servidor contendrá los datos del formulario.

Ahora también necesitarás una vista correspondiente a esa URL /your-name/ que encontrará las pares clave/valor adecuados en la solicitud y luego los procesará.

Esta es una forma muy sencilla. En la práctica, una forma podría contener docenas o cientos de campos, muchos de los cuales podrían necesitar ser prepoblados, y podríamos esperar que el usuario pase por el ciclo edita-envía varias veces antes de concluir la operación.

Podríamos necesitar que se produzca alguna validación en el navegador, incluso antes de enviar el formulario; podríamos querer utilizar campos mucho más complejos, que permitan al usuario realizar cosas como seleccionar fechas desde un calendario y así sucesivamente.

En este punto es mucho más fácil dejar que Django se encargue de la mayor parte del trabajo.

Creando un formulario en Django

La clase Form

Ya sabemos qué queremos que se vea nuestro formulario HTML. El punto de partida para ello en Django es esto:

forms.py
from django import forms


class NameForm(forms.Form):
    your_name = forms.CharField(label="Your name", max_length=100)

Esta define una clase de tipo Form con un solo campo (your_name). Hemos aplicado un etiqueta amigable para el usuario al campo, que aparecerá en el <label> cuando se renderice (aunque en este caso, la etiqueta que especificamos mediante label es la misma que se generaría automáticamente si lo hubiéramos omitido).

El campo de longitud máxima permitida se define mediante max_length. Esto hace dos cosas. Coloca un maxlength="100" en el HTML <input> (por lo tanto, el navegador debería impedir al usuario que ingrese más de ese número de caracteres desde el principio). También significa que cuando Django recibe la forma de regreso del navegador, validará la longitud de los datos.

Una instancia de Form tiene un método is_valid(), que ejecuta las rutinas de validación para todos sus campos. Cuando se llama a este método, si todos los campos contienen datos válidos, realizará:

  • return Verdadero

  • Coloca los datos del formulario en su atributo cleaned_data.

La forma completa, cuando se renderiza por primera vez, tendrá el siguiente aspecto:

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100" required>

Ten en cuenta que no incluye las etiquetas <form> ni un botón de envío. Tendremos que proporcionarlos nosotros mismos en el template.

La vista

Los datos de formulario enviados a un sitio web de Django se procesan mediante una vista, generalmente la misma vista que publicó el formulario. Esto nos permite reutilizar algunas de la misma lógica.

Para manejar el formulario necesitamos instanciarlo en la vista para la URL donde queremos que se publique:

views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render

from .forms import NameForm


def get_name(request):
    # if this is a POST request we need to process the form data
    if request.method == "POST":
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect("/thanks/")

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, "name.html", {"form": form})

Si llegamos a esta vista con una solicitud GET, creará una instancia vacía del formulario y la colocará en el contexto de la plantilla para su renderizado. Esto es lo que podemos esperar que suceda la primera vez que visitemos la URL.

Si se envía el formulario mediante una solicitud POST, la vista volverá a crear una instancia del formulario y la poblará con datos de la solicitud: form = NameForm(request.POST). Esto se llama «vincular datos al formulario» (ahora es un formulario vinculado).

Llamamos al método is_valid() del formulario; si no es True, volvemos a la plantilla con el formulario. Esta vez, el formulario ya no está vacío (no vinculado) y el formulario HTML se poblará con los datos previamente enviados, donde pueden ser editados y corregidos según sea necesario.

Si is_valid() es True, ahora podremos encontrar todos los datos del formulario validados en su atributo cleaned_data. Podemos utilizar estos datos para actualizar la base de datos o realizar otros procesamientos antes de enviar una redirección HTTP al navegador indicándole dónde ir a continuación.

La plantilla

No necesitamos hacer mucho en nuestra plantilla name.html:

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

Todos los campos y atributos del formulario se desempaquetarán en marcado HTML desde esa {{ form }} por el lenguaje de plantillas de Django.

Formularios y protección contra ataques de Cross Site Request Forgery

Django viene con una fácil de usar protección contra ataques de Cross Site Request Forgeries. Al enviar un formulario mediante POST con la protección CSRF habilitada, debemos utilizar el etiqueta de plantilla csrf_token como en el ejemplo precedente. Sin embargo, ya que la protección CSRF no está directamente ligada a los formularios en las plantillas, esta etiqueta se omite en los ejemplos siguientes en este documento.

HTML5 input types and browser validation

Si tu formulario incluye un campo URLField, un campo EmailField o cualquier tipo de campo entero, Django utilizará los tipos de entrada HTML5 url, email y number. Por defecto, los navegadores pueden aplicar su propia validación en estos campos, que puede ser más estricta que la validación de Django. Si deseas deshabilitar este comportamiento, establece el atributo novalidate en la etiqueta form, o especifica un widget diferente para el campo, como TextInput.

Ahora tenemos un formulario web funcional, descrito por una clase de Django Form, procesado por una vista y renderizado como un <form> HTML.

Eso es todo lo que necesitas para empezar, pero el framework de formularios pone mucho más a tu alcance. Una vez que comprendas los fundamentos del proceso descrito anteriormente, deberías estar preparado para entender otras características del sistema de formularios y listo para aprender un poco más sobre la maquinaria subyacente.

Más sobre las clases Form de Django

Todas las clases de formulario se crean como subclases de django.forms.Form o django.forms.ModelForm. Puedes pensar en ModelForm como una subclase de Form. Form y ModelForm heredan funcionalidad común de una clase privada (BaseForm), pero este detalle de implementación es raramente importante.

Modelos y Formularios

De hecho, si tu formulario va a ser utilizado para agregar o editar directamente un modelo Django, una ModelForm puede ahorrarte mucho tiempo, esfuerzo y código, ya que construirá un formulario, junto con los campos y sus atributos adecuados, desde una clase Model.

Instancias de formularios vinculadas y no vinculadas

La distinción entre Formularios vinculados y no vinculados es importante:

  • Un formulario no vinculado no tiene datos asociados a él. Cuando se renderiza para el usuario, estará vacío o contendrá valores por defecto.

  • Un formulario vinculado tiene datos enviados y, por lo tanto, puede utilizarse para determinar si esos datos son válidos. Si un formulario vinculado inválido se renderiza, puede incluir mensajes de error en línea que informen al usuario qué datos corregir.

La propiedad is_bound del formulario te dirá si el formulario tiene datos vinculados o no.

Más sobre campos

Consideremos un formulario más útil que nuestro ejemplo mínimo anterior, que podríamos utilizar para implementar la función «contactame» en una página web personal:

forms.py
from django import forms


class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

Nuestro formulario anterior utilizó un solo campo, your_name, un CharField. En este caso, nuestro formulario tiene cuatro campos: subject, message, sender y cc_myself. CharField, EmailField y BooleanField son solo tres de los tipos de campo disponibles; una lista completa se puede encontrar en la documentación de Campos del formulario.

Widgets

Cada campo del formulario tiene un widget correspondiente, que a su vez corresponde a un widget HTML como <input type="text">.

En la mayoría de los casos, el campo tendrá un widget predeterminado sensato. Por ejemplo, por defecto, un CharField tendrá un widget TextInput, que produce un <input type="text"> en HTML. Si necesitabas <textarea> en su lugar, especificarías el widget adecuado cuando definieras tu campo de formulario, como hemos hecho para el campo message.

Datos de campos

Whatever los datos enviados con un formulario, una vez que han sido validados correctamente llamando a is_valid() (y is_valid() ha devuelto True), los datos validados estarán en el diccionario form.cleaned_data. Esta data habrá sido convenientemente convertida en tipos de Python para ti.

Nota

Todavía puedes acceder a los datos no validados directamente desde request.POST en este punto, pero la data validada es mejor.

En el ejemplo del formulario de contacto anterior, cc_myself será un valor booleano. De manera similar, campos como IntegerField y FloatField convierten valores a Python int y float respectivamente.

Aquí tienes cómo se podría procesar la data del formulario en el view que maneja este formulario:

views.py
from django.core.mail import send_mail

if form.is_valid():
    subject = form.cleaned_data["subject"]
    message = form.cleaned_data["message"]
    sender = form.cleaned_data["sender"]
    cc_myself = form.cleaned_data["cc_myself"]

    recipients = ["info@example.com"]
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect("/thanks/")

Truco

Para más información sobre enviar correos electrónicos desde Django, consulta Enviando correo electrónico.

Algunos tipos de campos necesitan algún tratamiento adicional. Por ejemplo, los archivos subidos utilizando un formulario deben ser tratados de manera diferente (pueden recuperarse desde request.FILES, en lugar de request.POST). Para detalles sobre cómo manejar las subidas de archivos con tu formulario, consulta Asociar archivos subidos a un formulario.

Trabajando con plantillas de formularios

Todo lo que necesitas hacer para poner tu formulario en una plantilla es colocar la instancia del formulario en el contexto de la plantilla. Así que si tu formulario se llama form en el contexto, {{ form }} renderizará sus elementos <label> y <input> apropiadamente.

Muebles adicionales para las plantillas de formularios

No te olvides de que la salida de un formulario no incluye los tags <form> circundantes, ni el control de envío del formulario. Tendrás que proporcionar estos por tu cuenta.

Plantillas de formulario reutilizables

El HTML generado al renderizar un formulario se genera a través de una plantilla. Puedes controlar esto creando un archivo de plantilla adecuado y estableciendo un FORM_RENDERER personalizado para utilizar esa form_template_name en todo el sitio. También puedes personalizar por formulario sobrescribiendo la propiedad template_name del formulario para renderizar el formulario utilizando la plantilla personalizada, o pasando directamente el nombre de la plantilla a Form.render().

El ejemplo a continuación resultará en {{ form }} siendo renderizado como salida del template form_snippet.html.

En tus templates:

# In your template:
{{ form }}

# In form_snippet.html:
{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

Luego puedes configurar el FORM_RENDERER de la configuración:

settings.py
from django.forms.renderers import TemplatesSetting


class CustomFormRenderer(TemplatesSetting):
    form_template_name = "form_snippet.html"


FORM_RENDERER = "project.settings.CustomFormRenderer"

… o para un formulario único:

class MyForm(forms.Form):
    template_name = "form_snippet.html"
    ...

… o para una sola renderización de una instancia de formulario, pasando el nombre de la plantilla al método Form.render(). Aquí tienes un ejemplo de cómo se utiliza esto en una vista:

def index(request):
    form = MyForm()
    rendered_form = form.render("form_snippet.html")
    context = {"form": rendered_form}
    return render(request, "index.html", context)

Consulta Imprimir formas como HTML para obtener más detalles.

Plantillas reutilizables de grupo de campos

Cada campo está disponible como atributo de la forma, utilizando {{ form.name_of_field }} en un template. Un campo tiene un método as_field_group() que renderiza los elementos relacionados con el campo como un grupo, su etiqueta, widget, errores y texto de ayuda.

Esto permite escribir plantillas genéricas que arreglen los elementos de los campos en la disposición requerida. Por ejemplo:

{{ form.non_field_errors }}
<div class="fieldWrapper">
  {{ form.subject.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.message.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.sender.as_field_group }}
</div>
<div class="fieldWrapper">
  {{ form.cc_myself.as_field_group }}
</div>

Por defecto, Django utiliza la plantilla "django/forms/field.html" diseñada para uso con el estilo de formulario por defecto "django/forms/div.html".

La plantilla por defecto se puede personalizar estableciendo field_template_name en tu proyecto a nivel de la configuración FORM_RENDERER:

from django.forms.renderers import TemplatesSetting


class CustomFormRenderer(TemplatesSetting):
    field_template_name = "field_snippet.html"

… o en un campo individual:

class MyForm(forms.Form):
    subject = forms.CharField(template_name="my_custom_template.html")
    ...

… o en una base por solicitud llamando a BoundField.render() y suministrando el nombre de la plantilla:

def index(request):
    form = ContactForm()
    subject = form["subject"]
    context = {"subject": subject.render("my_custom_template.html")}
    return render(request, "index.html", context)

Rendimiento de campos manual

También es posible tener control más fino sobre el rendimiento de los campos. Es probable que esto se realice en una plantilla de campo personalizada, para permitir que la plantilla se escriba una vez y se reutilice para cada campo. Sin embargo, también se puede acceder directamente desde el atributo del campo en la forma. Por ejemplo:

{{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.subject.errors }}
    <label for="{{ form.subject.id_for_label }}">Email subject:</label>
    {{ form.subject }}
</div>
<div class="fieldWrapper">
    {{ form.message.errors }}
    <label for="{{ form.message.id_for_label }}">Your message:</label>
    {{ form.message }}
</div>
<div class="fieldWrapper">
    {{ form.sender.errors }}
    <label for="{{ form.sender.id_for_label }}">Your email address:</label>
    {{ form.sender }}
</div>
<div class="fieldWrapper">
    {{ form.cc_myself.errors }}
    <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label>
    {{ form.cc_myself }}
</div>

También se pueden generar elementos <label> completos utilizando el método label_tag(). Por ejemplo:

<div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
</div>

Rendimiento de mensajes de error de la forma

El precio de esta flexibilidad es un poco más de trabajo. Hasta ahora no hemos tenido que preocuparnos por cómo mostrar errores de formulario, porque eso se ha tomado cuidado por nosotros. En este ejemplo tenemos que asegurarnos de que nos ocupamos de cualquier error para cada campo y cualquier error del formulario en su conjunto. Toma nota de {{ form.non_field_errors }} en la parte superior del formulario y el recuento de plantillas para errores en cada campo.

Usando {{ form.name_of_field.errors }} muestra una lista de errores de formulario, renderizados como una lista no ordenada. Esto podría parecerse a:

<ul class="errorlist">
    <li>Sender is required.</li>
</ul>

La lista tiene un clase CSS de errorlist para permitir que estés personalizando su apariencia. Si deseas personalizar aún más la presentación de los errores puedes hacerlo recorriendo cada uno:

{% if form.subject.errors %}
    <ol>
    {% for error in form.subject.errors %}
        <li><strong>{{ error|escape }}</strong></li>
    {% endfor %}
    </ol>
{% endif %}

Los errores no relacionados con campos (y/o errores ocultos que se renderizan en la parte superior del formulario cuando se utilizan ayudantes como form.as_p()) se renderizarán con una clase adicional de nonfield para ayudarte a distinguirlos de los errores específicos de campo. Por ejemplo, {{ form.non_field_errors }} se vería así:

<ul class="errorlist nonfield">
    <li>Generic validation error</li>
</ul>

Ver La API de Formularios para más información sobre errores, estilos y trabajo con atributos del formulario en plantillas.

Recorrer los campos del formulario

Si estás utilizando el mismo HTML para cada uno de tus campos de formulario, puedes reducir código duplicado recorriendo cada campo a la vez mediante un bucle {% for %}:

{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
        {% if field.help_text %}
          <p class="help" id="{{ field.auto_id }}_helptext">
            {{ field.help_text|safe }}
          </p>
        {% endif %}
    </div>
{% endfor %}

Atributos útiles en {{ field }} incluyen:

{{ field.errors }}

Saca una <ul class="errorlist"> conteniendo cualquier error de validación correspondiente a este campo. Puedes personalizar la presentación de los errores con un bucle {% for error in field.errors %}. En este caso, cada objeto en el bucle es una cadena que contiene el mensaje de error.

{{ campo.campo }}

La instancia de la clase Field del formulario que envuelve esta instancia de BoundField. Puedes utilizarla para acceder a atributos de la clase Field, por ejemplo {{ campo_de_caracter.campo.max_length }}.

{{ campo.help_text }}

Cualquier texto de ayuda asociado al campo.

{{ campo.html_name }}

El nombre del campo que se utilizará en el campo name del elemento input. Esto tiene en cuenta la prefijo del formulario, si ha sido establecido.

{{ campo.id_for_label }}

El ID que se utilizará para este campo (id_email en el ejemplo anterior). Si estás construyendo manualmente el etiqueta, podrías querer utilizar esto en lugar de label_tag. También es útil, por ejemplo, si tienes algún JavaScript inline y quieres evitar codificar el ID del campo.

{{ campo.is_hidden }}

Esta atributo es True si el campo del formulario es un campo oculto y False en caso contrario. No es particularmente útil como variable de plantilla, pero podría ser útil en pruebas condicionales como:

{% if field.is_hidden %}
   {# Do something special #}
{% endif %}
{{ campo.label }}

El etiqueta del campo, por ejemplo Dirección de correo electrónico.

{{ campo.label_tag }}

La etiqueta del campo envuelta en la etiqueta HTML adecuada <label>. Esto incluye el sufijo de etiqueta del formulario: label_suffix. Por ejemplo, el sufijo de etiqueta por defecto es un dos puntos:

<label for="id_email">Email address:</label>
{{ campo.legend_tag }}

Similar a field.label_tag pero utiliza la etiqueta <legend> en lugar de <label>, para widgets con múltiples entradas envueltas en una <fieldset>.

{{ campo.use_fieldset }}

Esta atributo es True si el widget del campo del formulario contiene múltiples entradas que deben ser agrupadas semánticamente en un <fieldset> con una <legend> para mejorar la accesibilidad. Un ejemplo de uso en un template:

{% if field.use_fieldset %}
  <fieldset>
  {% if field.label %}{{ field.legend_tag }}{% endif %}
{% else %}
  {% if field.label %}{{ field.label_tag }}{% endif %}
{% endif %}
{{ field }}
{% if field.use_fieldset %}</fieldset>{% endif %}
{{ campo.value }}

El valor del campo. e.g someone@example.com.

Ver también

Para un lista completa de atributos y métodos, consulte BoundField.

Iterando sobre campos ocultos y visibles

Si estás colocando manualmente una forma en un template, a diferencia de confiar en la disposición por defecto de Django para las formas, podrías querer tratar los campos <input type="hidden"> de manera diferente a los campos no ocultos. Por ejemplo, porque los campos ocultos no muestran nada, poner mensajes de error «a lado» del campo podría causar confusión para tus usuarios – por lo tanto, los errores para esos campos deberían ser tratados de manera diferente.

Django proporciona dos métodos en una forma que te permiten iterar sobre los campos ocultos y visibles independientemente: hidden_fields() y visible_fields(). Aquí tienes una modificación de un ejemplo anterior que utiliza estos dos métodos:

{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

Este ejemplo no maneja ningún error en los campos ocultos. Normalmente, un error en un campo oculto es un signo de manipulación de la forma, ya que la interacción normal con las formas no altera a esos campos. Sin embargo, podrías insertar fácilmente algunas vistas de errores para esos formularios.

Temas adicionales

Esto cubre los conceptos básicos, pero las formas pueden hacer mucho más:

Ver también

La Referencia de Formularios

Cubre la referencia completa del API, incluyendo campos de formulario, widgets de formulario y validación de formularios y campos.