Saltar a contenido

Formularios a partir de Modelos

1. Introducción

En Django, los formularios a partir de modelos son una forma de crear formularios basados en los modelos definidos para acceder a la información de la base de datos. Esto facilita la creación de formularios (templeates) para la manipulación de registros en la base de datos (operaciones CRUD: Crear, Leer, Actualizar y Eliminar) sin necesidad de definir manualmente los campos del formulario, como vimos en los puntos anteriores. Utilizando esta técnica, podemos generar formularios que se corresponden con los datos de nuestros modelos y realizar operaciones de CRUD sobre ellos.

En este tema, utilizaremos el modelo Employee del proyecto employees que creamos en el tema anterior (5.8). En este tema nos centramos solo en generar el formulario para el modelo Employee. Las operaciones CRUD las veremos en el siguiente tema, aunque en este vamos a adelantar algo de teoría sobre las mismas, y comprender a qué nos referimos con operaciones CRUD

Operaciones CRUD sobre el Modelo Employee

El formulario que vamos a crear, veremos que nos permitirá realizar las siguientes operaciones sobre el modelo Employee:

  • Create (Crear): Usaremos un formulario para crear nuevos empleados en la base de datos. El formulario contendría campos como name, last_name y email.
  • Read (Leer): Los formularios de lectura nos permitirán visualizar los datos de un empleado en la base de datos. No necesitamos un formulario complejo, solo una vista que recupere los datos.
  • Update (Actualizar): Crear un formulario que permita actualizar los detalles de un empleado ya existente en la base de datos.
  • Delete (Eliminar): Un formulario para eliminar un registro de la base de datos.

Para realizar estas operaciones, utilizaremos el ModelForm de Django, lo que nos permitirá generar automáticamente formularios a partir de los modelos.


2. Introducción a ModelForm

En Django, el ModelForm es una clase especial que nos permite crear formularios a partir de un modelo de base de datos. La principal ventaja de utilizar ModelForm es que permite generar formularios automáticamente para los modelos, sin tener que escribir el código para cada campo manualmente.

Ventajas de ModelForm:

  • Generación automática de formularios: Django crea automáticamente el formulario basado en los campos definidos en el modelo, lo que ahorra tiempo y reduce la posibilidad de errores.
  • Validaciones automáticas: ModelForm se encarga de realizar las validaciones necesarias basadas en los campos del modelo, como la longitud máxima de un campo o la validación de correo electrónico.
  • Facilidad de trabajo con la base de datos: Al ser un Form vinculado directamente a un modelo, podemos guardar o actualizar los datos de forma sencilla sin tener que realizar consultas SQL manualmente.

¿Cómo funciona?

El ModelForm es una clase que hereda de forms.ModelForm. En su interior, hay una clase Meta que especifica el modelo a utilizar y los campos del formulario. Aquí tenemos el ejemplo básico de un ModelForm para el modelo Employee:

from django import forms
from .models import Employee

class EmployeeForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['name', 'last_name', 'email']  # Especificamos los campos a usar en el formulario

En los puntos siguientes entraremos en más detalle sobre cómo crear y utilizar un ModelForm en un proyecto Django.


3. Creación del Proyecto formularios_modelos y la Aplicación employees

3.1 Crear el Proyecto y la Aplicación

Vamos a crear un nuevo proyecto llamado formularios_modelos y una aplicación llamada employees para manejar los formularios basados en el modelo Employee.

django-admin startproject formularios_modelos
cd formularios_modelos
python manage.py startapp employees

3.2 Crear el Modelo Employee

En el archivo models.py de la aplicación employees, creamos el modelo Employee con los siguientes campos: name, last_name y email.

employees/models.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# employees/models.py
from django.db import models

class Employee(models.Model):
    name = models.CharField(max_length=50, blank=False, null=False)
    last_name = models.CharField(max_length=50, blank=False, null=False)
    email = models.EmailField(max_length=100, blank=False, null=False)

    def __str__(self):
        return f'{self.name} {self.last_name}'

3.3 Migraciones

Para crear las tablas en la base de datos, primero creamos las migraciones:

python manage.py makemigrations employees

Y luego las aplicamos a la base de datos:

python manage.py migrate

4. Creación de la Ruta y Vista para index

Creamos una vista que será la ruta por defecto de la aplicación, donde se mostrará un mensaje de éxito, de momento, como una comprobación inicial.

4.1 Crear la Ruta index

En urls.py de la aplicación employees, creamos la ruta index:

# employees/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='employee_index'),
]

4.2 Crear la Vista index

En views.py, definimos la vista index que solo devolverá un mensaje de éxito para comprobar que la ruta está funcionando correctamente:

# employees/views.py
from django.http import HttpResponse

def index(request):
    return HttpResponse('¡El formulario de Employee funciona correctamente!')

4.3 Crear la Plantilla index.html

Aunque en este paso solo necesitamos una confirmación simple, podemos crear el archivo index.html con la estructura básica HTML5 y el título "Formulario".

templates/employees/index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<!-- templates/employees/index.html -->
<!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 de Employee!</h1>
</body>
</html>

Ahora la vista index devolverá esta plantilla en lugar de un simple mensaje de texto.


5. Creación del ModelForm para el Modelo Employee

5.1 Crear el ModelForm en forms.py

Creamos el archivo forms.py en la aplicación employees y definimos el formulario a partir del modelo Employee utilizando ModelForm.

# employees/forms.py
from django import forms
from .models import Employee

class EmployeeForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['name', 'last_name', 'email']

5.2 Explicación del ModelForm

  • Herencia de ModelForm: La clase EmployeeForm hereda de forms.ModelForm, lo que le permite generar un formulario basado en el modelo Employee.
  • Clase Meta: Dentro de la clase Meta, especificamos el modelo que utilizaremos (Employee) y los campos que queremos incluir en el formulario (name, last_name, email).

La clase Meta también podemos utilizar:

  • fields = '__all__': para incluir todos los campos del modelo en el formulario.
  • exclude = ['campo1', 'campo2']: para excluir ciertos campos del formulario.
  • Campos adicionales: Si necesitamos agregar campos adicionales que no están en el modelo, podemos definirlos directamente en la clase EmployeeForm.
    class EmployeeForm(forms.ModelForm):
        confirm_email = forms.EmailField()  # Campo adicional no en el modelo   
        class Meta:
            model = Employee
            fields = '__all__'
    

6. Añadir el Formulario en la Plantilla HTML

Vamos a agregar el formulario generado por ModelForm en una plantilla HTML, de modo que los usuarios puedan rellenarlo.

6.1 Crear la Vista para Mostrar y Procesar el Formulario

En views.py, creamos la vista para mostrar el formulario en el navegador y manejar el envío de los datos.

employees/views.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# employees/views.py
from django.shortcuts import render
from .forms import EmployeeForm
from django.http import HttpResponse


def index(request):         
    if request.method == 'POST':
        form = EmployeeForm(request.POST)
        if form.is_valid():
            form.save()  # Guardar el nuevo empleado en la base de datos
            return HttpResponse('Empleado guardado correctamente.')
        else:
            return render(request, 'employees/index.html', {'form': form})
    else:
        form = EmployeeForm()
        return render(request, 'employees/index.html', {'form': form})

6.2 Mostrar el Formulario en la Plantilla

En el archivo index.html, incluimos el formulario utilizando {% csrf_token %} para el token CSRF y un botón de submit:

templates/employees/index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<!-- templates/employees/index.html -->
<!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 de Employee</h1>

    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}  <!-- Renderiza el formulario -->
        <button type="submit">Enviar</button>
    </form>
</body>
</html>

7. Validación del Formulario

Django realiza validaciones automáticas según el modelo, pero también podemos definir validaciones personalizadas.

7.1 Validaciones Automáticas de Django

Django realiza validaciones automáticas basadas en los campos del modelo. Por ejemplo, si el campo email no es una dirección de correo válida, Django generará un error.

7.2 Validaciones Personalizadas

Podemos agregar validaciones personalizadas dentro del formulario. Por ejemplo, asegurarnos de que el nombre no sea "admin":

employees/forms.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# employees/forms.py
from django.core.exceptions import ValidationError

class EmployeeForm(forms.ModelForm):
    class Meta:
        model = Employee
        fields = ['name', 'last_name', 'email']

    def clean_name(self):
        name = self.cleaned_data['name']
        if name == 'admin':
            raise ValidationError('El nombre no puede ser "admin".')
        return name

7.3 Mostrar los Errores en la Plantilla HTML

Django maneja los errores de validación automáticamente. Si algún campo no es válido, Django redirige al formulario con los errores y los muestra en la plantilla.

templates/comentarios/form_contact.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!-- templates/comentarios/form_contact.html -->
<form action="/post/comment" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    {% for field in form %}
        {% for error in field.errors %}
            <p class="error">{{ error }}</p>
        {% endfor %}
    {% endfor %}
    <button type="submit">Enviar</button>
</form>

8. Resumen

En este tema, hemos aprendido a crear formularios en Django utilizando ModelForm, lo que nos permite generar formularios automáticamente basados en los modelos de la base de datos. Hemos visto cómo crear un proyecto y una aplicación, definir un modelo, crear un ModelForm, y mostrar el formulario en una plantilla HTML. También hemos explorado las validaciones automáticas y personalizadas que Django ofrece para asegurar la integridad de los datos.