Vistas en Django: Guía Completa y Práctica

Las vistas en Django son las responsables de procesar las solicitudes de los usuarios, interactuar con los modelos y devolver las respuestas correspondientes.

Creación de Vistas

En Django, las vistas se definen como funciones o clases que reciben una solicitud y devuelven una respuesta. Las vistas se asocian a las URLs a través del archivo urls.py.

Vistas basadas en Funciones

Las vistas basadas en funciones son funciones simples que reciben un objeto HttpRequest y devuelven un objeto HttpResponse.

Ejemplo Básico de Vista

python
# views.py
from django.http import HttpResponse

def home(request):
  return HttpResponse("¡Hola, Mundo!")

En este ejemplo, la vista home devuelve un simple texto cuando un usuario accede a la URL asociada.

Vistas basadas en Clases

Django también permite definir vistas como clases, que proporcionan más funcionalidades y reutilización de código a través de la herencia.

Ejemplo Básico de Vista Basada en Clase

python
# views.py
from django.http import HttpResponse
from django.views import View

class HomeView(View):
  def get(self, request):
      return HttpResponse("¡Hola, Mundo desde una vista basada en clase!")

Vistas Genéricas de Django

Django incluye vistas genéricas que cubren casos comunes como listas de objetos, detalles, creación, actualización y eliminación de elementos.

Ejemplo: Vista de Detalles de un Modelo

python
# views.py
from django.shortcuts import render
from django.views.generic import DetailView
from .models import Post

class PostDetailView(DetailView):
  model = Post
  template_name = 'post_detail.html'

Esta vista genérica muestra los detalles de un objeto Post en un template.

Renderizado de Plantillas

Django permite renderizar plantillas HTML usando su sistema de plantillas incorporado, lo que facilita la separación de la lógica del servidor de la presentación de la interfaz de usuario.

Renderizado Básico de Plantillas

python
# views.py
from django.shortcuts import render

def home(request):
  return render(request, 'home.html', {'message': '¡Bienvenido a Django!'})

En este ejemplo, la vista home renderiza el template home.html y pasa una variable message al template.

Template home.html

html
<!-- home.html -->
<html>
<head><title>Mi Página</title></head>
<body>
  <h1>{{ message }}</h1>
</body>
</html>

En el template, la variable message será sustituida por ‘¡Bienvenido a Django!’.

Uso de Plantillas con Herencia

Django soporta la herencia de plantillas, lo que permite crear una estructura base que se extiende en otras plantillas.

Plantilla Base

html
<!-- base.html -->
<html>
<head><title>{% block title %}Mi Página{% endblock %}</title></head>
<body>
  <header>
    <h1>Bienvenidos</h1>
  </header>
  <main>
    {% block content %}{% endblock %}
  </main>
</body>
</html>

Plantilla Hija

html
<!-- home.html -->
{% extends 'base.html' %}

{% block content %}
<h2>{{ message }}</h2>
{% endblock %}

Aquí, home.html extiende de base.html y reemplaza el bloque content con un mensaje.

Manejo de Formularios y Validación de Datos

Django proporciona un potente sistema para manejar formularios, lo que facilita la validación de datos y la gestión de errores.

Creación de Formularios con Django

Django tiene una clase llamada forms.Form que se utiliza para definir formularios. Cada campo en el formulario se define como un atributo de la clase de formulario.

Ejemplo de Formulario

python
# forms.py
from django import forms

class ContactForm(forms.Form):
  name = forms.CharField(max_length=100)
  email = forms.EmailField()
  message = forms.CharField(widget=forms.Textarea)

Este formulario tiene tres campos: name, email y message.

Mostrar y Procesar Formularios en la Vista

En la vista, podemos procesar los datos del formulario, validarlos y renderizar el formulario de vuelta con los errores, si los hay.

python
# views.py
from django.shortcuts import render
from .forms import ContactForm

def contact(request):
  if request.method == 'POST':
      form = ContactForm(request.POST)
      if form.is_valid():
          # Procesar los datos del formulario
          name = form.cleaned_data['name']
          email = form.cleaned_data['email']
          message = form.cleaned_data['message']
          # Aquí se puede guardar en la base de datos o enviar un correo
          return HttpResponse("¡Formulario enviado!")
      else:
          # Si el formulario no es válido, lo mostramos nuevamente con los errores
          return render(request, 'contact.html', {'form': form})
  else:
      form = ContactForm()
  return render(request, 'contact.html', {'form': form})

Validación de Formulario

Django realiza la validación de los campos de formulario automáticamente, pero también permite agregar validaciones personalizadas.

Ejemplo de Validación Personalizada

python
# forms.py
from django.core.exceptions import ValidationError

class ContactForm(forms.Form):
  name = forms.CharField(max_length=100)
  email = forms.EmailField()
  message = forms.CharField(widget=forms.Textarea)

  def clean_name(self):
      name = self.cleaned_data.get('name')
      if "badword" in name:
          raise ValidationError("El nombre contiene palabras inapropiadas")
      return name

En este ejemplo, el método clean_name realiza una validación personalizada del campo name.

Manejo de Errores de Formularios

Si un formulario no es válido, Django pasará los errores al template. Los errores se pueden acceder a través del atributo errors.

Ejemplo de Template con Errores

html
<!-- contact.html -->
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Enviar</button>
</form>

{% if form.errors %}
<div class="errors">
  <ul>
    {% for field in form %}
      {% for error in field.errors %}
        <li>{{ error }}</li>
      {% endfor %}
    {% endfor %}
  </ul>
</div>
{% endif %}

Este template muestra los errores del formulario si existen.

Casos de Uso Comunes


1Formulario de Registro de Usuario
python
# forms.py
from django.contrib.auth.forms import UserCreationForm

class RegisterForm(UserCreationForm):
  email = forms.EmailField()

# views.py
from django.shortcuts import render, redirect
from .forms import RegisterForm

def register(request):
  if request.method == 'POST':
      form = RegisterForm(request.POST)
      if form.is_valid():
          form.save()
          return redirect('login')
  else:
      form = RegisterForm()
  return render(request, 'register.html', {'form': form})
2Vista que Muestra un Listado de Objetos
python
# views.py
from django.shortcuts import render
from .models import Post

def post_list(request):
  posts = Post.objects.all()
  return render(request, 'post_list.html', {'posts': posts})
3Vista para Actualizar un Objeto Existente
python
# views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
from .forms import PostForm

def post_edit(request, pk):
  post = get_object_or_404(Post, pk=pk)
  if request.method == 'POST':
      form = PostForm(request.POST, instance=post)
      if form.is_valid():
          form.save()
          return redirect('post_detail', pk=post.pk)
  else:
      form = PostForm(instance=post)
  return render(request, 'post_edit.html', {'form': form})