Guía Completa de Desarrollo Web con Django

¿Qué es Django?

Django es un framework de desarrollo web de alto nivel en Python que fomenta un desarrollo rápido y un diseño limpio y pragmático. Creado por Adrian Holovaty y Simon Willison en 2003, Django sigue el principio de “baterías incluidas” (batteries included), lo que significa que proporciona casi todo lo que un desarrollador podría querer hacer.

  Características Principales

  • ORM (Object-Relational Mapping) Potente: Abstracción de bases de datos
  • Administración Automática: Panel de administración generado automáticamente
  • Seguridad Integrada: Protección contra ataques comunes
  • Escalabilidad: Utilizado por empresas como Instagram, Mozilla, Pinterest
  • Arquitectura MTV (Model-Template-View): Similar al patrón MVC

  Requisitos Previos

  1. Python: Versión 3.8 o superior
  2. Conocimientos Básicos:
    • Programación en Python
    • Conceptos de programación web
    • HTML, CSS básico
    • Fundamentos de bases de datos

1Instalación de Python

  • Descargar desde python.org
  • Durante la instalación, asegúrate de marcar la opción “Añadir Python al PATH” para evitar problemas en la configuración. Observa la imagen a continuación para más detalles.
Urian Viera Full Stack Developer autodidacta

2Crear Entorno Virtual

Si tienes dudas sobre cómo crear un entorno virtual, te recomiendo visitar esta completa Guía sobre Entornos Virtuales en Python, donde encontrarás todo lo que necesitas saber, desde la creación hasta la gestión de entornos virtuales.

bash
# Crear entorno virtual
python -m venv django_project_env

# Activar entorno virtual
# Windows
django_project_envScriptsactivate

# macOS/Linux
source django_project_env/bin/activate

3Instalación de Django

En este paso, actualizamos pip, el gestor de paquetes de Python (aunque no es estrictamente necesario), y luego instalamos el framework Django.

bash
# Actualizar pip
python -m pip install --upgrade pip

# Instalar Django
pip install django

# Verificar instalación
python -m django --version

4Creación del Proyecto Django

Para crear un nuevo proyecto Django, simplemente ejecuta el comando django-admin startproject nombre-del-proyecto, y automáticamente se generará la estructura básica del proyecto.

bash
# Crear proyecto
django-admin startproject universidad_project

# Cambiar al directorio del proyecto
cd universidad_project

4Estructura de Directorios

bash
universidad_project/
│
├── manage.py
│
└── universidad_project/
  ├── __init__.py
  ├── settings.py
  ├── urls.py
  ├── asgi.py
  └── wsgi.py
  Archivos Principales en un Proyecto Django

  • manage.py: Herramienta administrativa para gestionar el proyecto Django (ejecutar comandos como migraciones, crear superusuario, etc.)
  • settings.py: Archivo de configuración principal del proyecto, donde se definen ajustes como bases de datos, aplicaciones instaladas, rutas, y más.
  • urls.py: Archivo que contiene la configuración de rutas y URL del proyecto, esencial para la navegación y el enrutamiento dentro de la aplicación.
  • __init__.py: Archivo que indica que el directorio debe ser tratado como un paquete de Python, permitiendo la importación de módulos dentro de él.

Crear Primera Aplicación en Django

En este paso, vamos a crear nuestra primera aplicación Django utilizando el comando python manage.py startapp nombre-de-la-aplicacion.

Una aplicación en Django es un módulo que contiene la lógica de negocio y funcionalidades específicas para tu proyecto.

bash
# Crear la aplicación 'estudiantes'
python manage.py startapp estudiantes

Estructura de la Aplicación

bash
estudiantes/
│
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── tests.py
├── views.py
└── migrations/
  └── __init__.py

Definición del Modelo

En este paso, vamos a definir el modelo Estudiante en Django dentro de estudiantes/models.py. El modelo es una representación de la estructura de la base de datos, y en este caso, creamos dos modelos: Carrera y Estudiante. Cada modelo es una tabla en la base de datos que contiene los atributos que hemos definido como campos.

Este modelo permite almacenar información sobre los estudiantes, como su nombre, edad, correo electrónico, y estado, así como su relación con la carrera que cursan.

python
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils.translation import gettext_lazy as _

class Carrera(models.Model):
  nombre = models.CharField(
      max_length=100, 
      verbose_name=_("Nombre de la Carrera")
  )
  descripcion = models.TextField(
      blank=True, 
      verbose_name=_("Descripción")
  )

  def __str__(self):
      return self.nombre

class Estudiante(models.Model):
  ESTADO_CHOICES = [
      ('activo', _('Activo')),
      ('inactivo', _('Inactivo')),
      ('graduado', _('Graduado'))
  ]

  nombres = models.CharField(
      max_length=100, 
      verbose_name=_("Nombres")
  )
  apellidos = models.CharField(
      max_length=100, 
      verbose_name=_("Apellidos")
  )
  carrera = models.ForeignKey(
      Carrera, 
      on_delete=models.SET_NULL, 
      null=True,
      verbose_name=_("Carrera")
  )
  edad = models.IntegerField(
      validators=[
          MinValueValidator(16, _("La edad mínima es 16")),
          MaxValueValidator(100, _("La edad máxima es 100"))
      ],
      verbose_name=_("Edad")
  )
  email = models.EmailField(
      unique=True, 
      verbose_name=_("Correo Electrónico")
  )
  fecha_inscripcion = models.DateTimeField(
      auto_now_add=True, 
      verbose_name=_("Fecha de Inscripción")
  )
  estado = models.CharField(
      max_length=10,
      choices=ESTADO_CHOICES,
      default='activo',
      verbose_name=_("Estado")
  )

  class Meta:
      verbose_name = _("Estudiante")
      verbose_name_plural = _("Estudiantes")
      ordering = ['apellidos', 'nombres']

  def nombre_completo(self):
      return f"{self.nombres} {self.apellidos}"

  def __str__(self):
      return self.nombre_completo()

Migrar Base de Datos

Una vez que hemos definido nuestros modelos en Django, es necesario crear y aplicar las migraciones para que los cambios se reflejen en la base de datos. Las migraciones son una forma de gestionar el esquema de la base de datos de manera automática y ordenada.

Para migrar la base de datos, primero generamos las migraciones y luego las aplicamos:

bash
# Crear migraciones
python manage.py makemigrations estudiantes

# Aplicar migraciones
python manage.py migrate

Vistas Basadas en función (FBV)

En Django, las Vistas Basadas en Función (FBV) son una forma simple y directa de manejar las solicitudes HTTP y generar las respuestas adecuadas. Cada vista es una función de Python que recibe una solicitud (request) y devuelve una respuesta (response).

En el siguiente ejemplo, vamos a crear vistas basadas en función para manejar operaciones básicas en el modelo Estudiante, como listar, ver, crear, actualizar y eliminar registros. En estudiantes/views.py:

python
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse_lazy
from .models import Estudiante
from .forms import EstudianteForm
from django.http import HttpResponse

# Vista para listar estudiantes
def lista_estudiantes(request):
  estudiantes = Estudiante.objects.all()
  return render(request, 'estudiantes/lista_estudiantes.html', {'estudiantes': estudiantes})

# Vista para ver los detalles de un estudiante
def detalle_estudiante(request, pk):
  estudiante = get_object_or_404(Estudiante, pk=pk)
  return render(request, 'estudiantes/detalle_estudiante.html', {'estudiante': estudiante})

# Vista para crear un nuevo estudiante
def crear_estudiante(request):
  if request.method == 'POST':
      form = EstudianteForm(request.POST)
      if form.is_valid():
          form.save()
          return redirect('lista_estudiantes')
  else:
      form = EstudianteForm()
  return render(request, 'estudiantes/crear_estudiante.html', {'form': form})

# Vista para actualizar un estudiante existente
def editar_estudiante(request, pk):
  estudiante = get_object_or_404(Estudiante, pk=pk)
  if request.method == 'POST':
      form = EstudianteForm(request.POST, instance=estudiante)
      if form.is_valid():
          form.save()
          return redirect('lista_estudiantes')
  else:
      form = EstudianteForm(instance=estudiante)
  return render(request, 'estudiantes/editar_estudiante.html', {'form': form})

# Vista para eliminar un estudiante
def eliminar_estudiante(request, pk):
  estudiante = get_object_or_404(Estudiante, pk=pk)
  if request.method == 'POST':
      estudiante.delete()
      return redirect('lista_estudiantes')
  return render(request, 'estudiantes/eliminar_estudiante.html', {'estudiante': estudiante})

Configuración de URLs

En Django, la configuración de URLs se realiza en un archivo específico donde se definen las rutas que los usuarios pueden visitar. Cada URL se asigna a una vista que manejará la lógica de la solicitud y mostrará la respuesta correspondiente. A continuación, veremos cómo configurar las URLs para las vistas de nuestro proyecto.

En estudiantes/urls.py:

python
from django.urls import path
from .views import (
  estudiante_list, 
  estudiante_detail, 
  estudiante_create, 
  estudiante_update, 
  estudiante_delete
)

urlpatterns = [
  path('', estudiante_list, name='lista_estudiantes'),
  path('estudiante/<int:pk>/', estudiante_detail, name='detalle_estudiante'),
  path('nuevo/', estudiante_create, name='crear_estudiante'),
  path('editar/<int:pk>/', estudiante_update, name='editar_estudiante'),
  path('eliminar/<int:pk>/', estudiante_delete, name='eliminar_estudiante'),
]

El archivo universidad_project/urls.py, se encarga de incluir y gestionar las rutas globales del proyecto. Aquí se configuran las URLs que corresponden a las aplicaciones y vistas específicas dentro del proyecto Django, y es donde se conecta todo el flujo de enrutamiento de la aplicación.

python
from django.contrib import admin
from django.urls import path, include

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

Ejemplo de Plantilla Base y Templates

En Django, las plantillas base permiten definir una estructura común para todas las páginas del sitio. A través de la herencia de plantillas, se puede reutilizar código y mantener la coherencia visual en toda la aplicación. Aquí te mostramos cómo definir una plantilla base en templates/base.html para usar en otras plantillas.

html
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>{% block titulo %}Universidad{% endblock %}</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
      <!-- Menú de navegación -->
  </nav>

  <div class="container mt-4">
      {% block contenido %}
      {% endblock %}
  </div>

  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

Configuraciones de Seguridad

Django proporciona varias opciones para proteger tu aplicación en producción. Es importante deshabilitar el modo DEBUG, configurar ALLOWED_HOSTS con los dominios permitidos, y habilitar medidas de seguridad adicionales como redirección SSL y cookies seguras. A continuación, un ejemplo de configuraciones en settings.py:

python
# Configuraciones de seguridad
SECRET_KEY = 'tu_clave_secreta_aqui'
DEBUG = False
ALLOWED_HOSTS = ['tudominio.com', 'www.tudominio.com']

# Configuraciones de seguridad adicionales
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True