Saltar a contenido

Formularios HTML

1. Introducción

En este tema aprenderemos cómo trabajar con formularios HTML para enviar datos al servidor. A diferencia de otros temas donde se utilizan formularios gestionados por Django, en este caso trabajaremos directamente con formularios HTML5 para interactuar con el servidor. Utilizaremos los métodos GET y POST para recibir datos en el backend, y explicaremos cómo manejarlos en nuestras vistas.

El objetivo es crear un formulario de contacto simple, donde los usuarios puedan enviar su nombre y mensaje. Utilizando los formularios debemos ser capaces de gestionar la información recibida.

<form> HTML

Si no estas familiarizado con los formularios HTML, te recomiendo revisar la documentación oficial de HTML5 sobre formularios: W3Schools HTML Forms.


2. Creación de un Proyecto: Contactos

Vamos a crear un nuevo proyecto llamado contactos, que gestionará los formularios de contacto. Para ello, seguimos estos pasos:

2.1 Crear el Proyecto Django

Entorno Virtual

Asegúrate de tener un entorno virtual activo para evitar conflictos con otras instalaciones de Python o Django. Lo tienes explicado en temas anteriores.

django-admin startproject contactos .

2.2 Crear la Aplicación formularios

Ahora, dentro del proyecto contactos, creamos la aplicación contactos que se encargará de gestionar el formulario.

python manage.py startapp formularios

2.3 Registrar la Aplicación en settings.py

Abre el archivo settings.py de tu proyecto y añade la aplicación formularios a la lista de INSTALLED_APPS:

INSTALLED_APPS = [
    # ...
    'formularios',  # Aquí añadimos la aplicación formularios
]

Configuración

Recuerda añadir en settings la información necesaria para los ficheros estáticos y para las plantillas como en los temas anteriores y crear las carpetas necesarias. También puedes hacer las migraciones necesarias.

Realizar una comprobación

Ejecuta python manage.py check para asegurarte de que no hay errores en la configuración del proyecto.


3. Creación de un Formulario HTML para Contactos

Ahora, vamos a crear el formulario HTML para la página de contacto. Tendremos dos archivos de plantilla:

  • contact.html: El archivo principal de la página de contacto que incluirá el formulario.
  • form_contact.html: El archivo que contendrá solo el formulario HTML.

3.1 Crear el archivo principal contact.html

Ahora, creamos el archivo contact.html que incluirá el formulario. Este archivo incluirá el formulario definido en form_contact.html.

templates/contactos/contact.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Formulario</title>
</head>
<body>
    <h1>Formulario</h1>
    {% include 'forms/contact_form.html' %}
</body>
</html>

3.2 Crear el Formulario en form_contact.html

Crea el archivo form_contact.html dentro de la carpeta templates/contactos/ con el siguiente contenido. Este formulario pedirá el nombre y el mensaje del usuario.

templates/contactos/form_contact.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- templates/contactos/form_contact.html -->
<form action="{% url 'get_success' %}" method="GET">
    {% csrf_token %}
    <label for="name">Nombre:</label>
    <input type="text" id="name" name="name" required>

    <label for="message">Mensaje:</label>
    <textarea id="message" name="message" rows="4" required></textarea>

    <input type="submit" value="Enviar">
</form>

csrf_token

Aunque el token CSRF no es estrictamente necesario para formularios enviados con GET, es una buena práctica incluirlo para mantener la consistencia y seguridad en los formularios. Sin embargo, es obligatorio para formularios enviados con POST.

3.3 Vistas y Rutas

Definimos las rutas y vistas necesarias para manejar el formulario y la página de éxito.

Las rutas se definen en urls.py de la aplicación formularios.

urls.py
1
2
3
4
5
6
7
# formularios/urls.py
from django.urls import path
from . import views
urlpatterns = [
    path('get/contact', views.get_contact, name='get_contact'),
    path('get/success', views.get_success, name='get_success'),
]

Ahora, definimos la vista que renderizará el formulario cuando se acceda a la ruta /contact.

views.py
1
2
3
4
5
6
7
8
9
# contactos/views.py
from django.shortcuts import render
from django.http import HttpResponse

def get_contact(request):
    return render(request, 'contactos/contact.html', {})

def get_success(request):
   return HttpResponse("Datos recibidos correctamente.", {})

Podemos probar el circuito accediendo a la ruta:

http://localhost:8000/forms/get/contact
Nos debe presentar el formulario, y al enviarlo, nos debe llevar a la página de éxito con el mensaje "Datos recibidos correctamente."

3.3 Crear la Página de Éxito success.html

Las aplicaciones, normalmente, necesitan manejar los datos recibidos antes de mostrarlos en una página de éxito. Por tanto la solución anterior no es suficiente. Necesitamos añadir una nueva plantilla, en este caso mostraremos los datos recibidos en la página de éxito. Pero se podrían:

  • Guardar en una base de datos.
  • Enviar un correo electrónico.
  • Otras acciones.

Primera versión de la página de éxito para ver que funciona:

success.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<!-- templates/success.html -->
 <!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Success</title>
</head>
<body>
    <h1>Éxito</h1>
    <p>Datos recibidos correctamente.</p>
</body>
</html>

Método GET

método GET

El método GET envía los datos del formulario a través de la URL, lo que no es seguro para datos sensibles. Se utiliza principalmente para solicitudes que no modifican datos en el servidor.

Si nos fijamos en el formulario, el atributo action apunta a la ruta get_success, que es donde se enviarán los datos del formulario. El método utilizado es GET, lo que significa que los datos se enviarán a través de la URL. Vamos a ver este caso primero y luego el método POST.

Veamos cómo podemos acceder a los datos recibidos y mostrarlos en la página de éxito. Segunda versión de la página de éxito para mostrar los datos recibidos.

Primero necesitamos que en la vista (controlador de Django) se pasen los datos al contexto. Luego, en la plantilla, podemos acceder a ellos usando las variables de contexto. Por tanto modificamos la vista que debe quedar así:

views.py
1
2
3
4
5
6
7
8
# contactos/views.py
from django.shortcuts import render

def get_success(request):
    name = request.GET.get('name')
    message = request.GET.get('message')
    context = {'name': name, 'message': message}
    return render(request, 'contactos/success.html', context)

Ahora ya podemos acceder en el template a las variables name y message que hemos pasado en el contexto. Modificamos la plantilla success.html para mostrar estos datos:

success.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<!-- templates/contactos/success.html -->
 <!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Success</title>
</head>
<body>
    <h1>Éxito</h1>
    <p>Datos recibidos correctamente.</p>
    <p>Nombre: {{ name }}</p>
    <p>Mensaje: {{ message }}</p>
</body>
</html>

4. Método GET

En este paso, aprenderemos a recibir los datos enviados por el formulario utilizando el método GET.

Antes de crear las rutas en nuestra aplicación, recuerda de delegar las URLs proyecto contactos/urls.py a la aplicación formularios/urls.py.

urls.py
1
2
3
4
5
6
7
8
# formularios/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('forms/', include('formularios.urls')),
]

5. Método POST

Ahora vamos a ver cómo recibir los datos enviados utilizando el método POST. El formulario se enviará mediante POST para asegurar la privacidad y seguridad de los datos.

5.1 Crear la Ruta /post/success

Primero, creamos una ruta para gestionar la solicitud POST cuando el formulario sea enviado.

urls.py
1
2
3
4
# formularios/urls.py
urlpatterns += [
    path('post/success', views.post_success, name='post_success'),
]

5.2 Definir la Vista post_success

En este caso, avanzando un poco más, vamos a definir la vista que manejará la solicitud POST y procesará los datos recibidos. Pero vamos a asegurarnos de que la vista solo maneje solicitudes POST, en otro caso devolverá un error 405 (método no permitido).

views.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# formularios/views.py
from django.shortcuts import render

def post_success(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        message = request.POST.get('message')
        context = {'name': name, 'message': message}
        return render(request, 'contactos/success.html', context)
    else:
        return HttpResponse("Método no permitido.", status=405)

Modiicar el formulario para usar POST

Simplemente cambiamos el método en el formulario de GET a POST y la acción a la ruta post_success.

form_contact.html
1
2
3
4
5
6
7
8
<!-- templates/contactos/form_contact.html -->
<form action="{% url 'post_success' %}" method="POST">
    {% csrf_token %}
    <label for="name">Nombre:</label>
    <input type="text" id="name" name="name" required>

    <label for="message">Mensaje:</label>
    <textarea id="message" name="message" rows="4" required></textarea>

5.5 Solución al Error de CSRF

Al utilizar POST, Django requiere un token CSRF para prevenir ataques. Este token debe estar incluido en el formulario. Para solucionarlo, aseguramos que el formulario tiene el siguiente campo:

Ya lo hemos incluido en el formulario anteriores, porque sino el servidor nos devolverá un error 403 (Forbidden) indicando que el token CSRF no fue proporcionado. Es una manera de proteger las aplicaciones web contra ataques de tipo CSRF (Cross-Site Request Forgery).

form_contact.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- templates/contactos/form_contact.html -->
<form action="/post/contact" method="POST">
    {% csrf_token %}
    <label for="name">Nombre:</label>
    <input type="text" id="name" name="name" required><br><br>

    <label for="message">Mensaje:</label>
    <textarea id="message" name="message" rows="4" required></textarea><br><br>

    <input type="submit" value="Enviar">
</form>

El campo {% csrf_token %} se incluye dentro del formulario para que Django lo reconozca y valide la solicitud POST.


6. Resumen

En este tema hemos aprendido a trabajar con formularios HTML5 en Django, utilizando los métodos GET y POST para enviar y recibir datos. Hemos creado formularios, manejado datos con ambos métodos, y solucionado el error de CSRF al trabajar con el método POST.