Desarrollo Web con Django

Este no es un tutorial rápido. Esta es la guía completa para entender cómo funciona un Framework profesional utilizado por Instagram, Pinterest y Mozilla. Django es "opinionated": te obliga a hacer las cosas bien.

1. Filosofía y Estructura MVT

Django no es un simple archivo. Es un ecosistema. Cuando creas un proyecto, se generan varios archivos clave que debes entender sí o sí:

Arquitectura MVT: Django separa los datos (Modelo), de la lógica (Vista) y del diseño (Template).

2. Configuración Inicial Correcta

Vamos a crear un proyecto de "Blog". Sigue estos pasos en tu terminal:

Terminal
# 1. Crear entorno virtual (Siempre haz esto)
python -m venv entornovirtual

# 2. Activar entorno
entornovirtual\Scripts\activate  # Windows
source entornovirtual/bin/activate # Mac/Linux

# 3. Instalar Django
pip install django

# 4. Crear el proyecto (El punto al final es importante para no crear subcarpetas extra)
django-admin startproject mi_blog .

3. El concepto de "Apps"

Un proyecto Django se divide en pequeñas "Apps" modulares. Por ejemplo, una tienda online tendría: una app para productos, una app para usuarios y una app para pagos.

Terminal
python manage.py startapp posts

Ahora debemos decirle a Django que esta app existe. Ve a settings.py:

mi_blog/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...
    'posts', # <--- Añade tu app aquí
]

4. Modelos y ORM (La Base de Datos)

Olvídate de escribir SQL. En Django defines clases de Python y él crea las tablas por ti.

posts/models.py
from django.db import models
from django.utils import timezone

class Post(models.Model):
    titulo = models.CharField(max_length=200)
    contenido = models.TextField()
    fecha_creacion = models.DateTimeField(default=timezone.now)
    publicado = models.BooleanField(default=True)

    # Esto hace que en el panel admin se vea el título y no "Post object (1)"
    def __str__(self):
        return self.titulo
¡Las Migraciones! Cada vez que toques models.py, debes ejecutar estos dos comandos para actualizar la base de datos real:
python manage.py makemigrations (Prepara los cambios)
python manage.py migrate (Aplica los cambios)

5. Panel Admin Avanzado

Para gestionar tus posts, regístralos en el admin.

posts/admin.py
from django.contrib import admin
from .models import Post

# Clase opcional para personalizar la tabla del admin
class PostAdmin(admin.ModelAdmin):
    list_display = ('titulo', 'fecha_creacion', 'publicado')
    search_fields = ('titulo', 'contenido')
    list_filter = ('publicado',)

admin.site.register(Post, PostAdmin)

6. Vistas y URLs (El cerebro)

Cuando alguien entra a tu web, primero choca con urls.py, que lo manda a una "Vista" en views.py.

Paso 1: Crear la Vista (Lógica)

posts/views.py
from django.shortcuts import render
from .models import Post

def lista_posts(request):
    # Pedimos a la BD todos los posts
    posts = Post.objects.all()
    # Se los enviamos al HTML
    return render(request, 'posts/lista.html', {'posts': posts})

Paso 2: Crear la Ruta (URL)

mi_blog/urls.py
from django.contrib import admin
from django.urls import path
from posts import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.lista_posts, name='inicio'),
]

7. Templates y Herencia (No repitas HTML)

Django usa un sistema genial. Creas un archivo base.html con el menú y el pie de página, y el resto de páginas heredan de él.

templates/base.html
<!DOCTYPE html>
<html>
<head>
    <title>Mi Blog</title>
</head>
<body>
    <nav>Menú Principal</nav>
    
    <!-- Aquí se inyectará el contenido de las otras páginas -->
    {% block contenido %} 
    {% endblock %}

    <footer>Pie de página</footer>
</body>
</html>
templates/posts/lista.html
{% extends 'base.html' %}

{% block contenido %}
    <h1>Últimas noticias</h1>
    
    {% for post in posts %}
        <article>
            <h2>{{ post.titulo }}</h2>
            <p>{{ post.contenido }}</p>
        </article>
    {% endfor %}
{% endblock %}

9. Formularios (La forma difícil vs la forma Django)

No crees <input> HTML a mano. Django puede crear formularios basados en tus modelos automáticamente.

posts/forms.py
from django import forms
from .models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['titulo', 'contenido', 'publicado']

Esto generará un formulario HTML con validaciones de seguridad (CSRF protection) listas para usar en tu vista.

8. Archivos Estáticos (CSS, JS e Imágenes)

Tu web se ve fea porque no tiene CSS. En Django, los archivos que no cambian (imágenes del logo, hojas de estilo) se llaman "estáticos".

Estructura de Carpetas: Crea una carpeta llamada static dentro de tu app.
Ruta: posts/static/posts/estilo.css

Para cargar estos archivos en tu HTML, necesitas usar una etiqueta especial al principio del archivo:

templates/base.html
{% load static %}  <!-- Importante: Cargar esto primero -->

<!DOCTYPE html>
<html>
<head>
    <!-- Así se vincula el CSS en Django -->
    <link rel="stylesheet" href="{% static 'posts/estilo.css' %}">
</head>
<body>
    <img src="{% static 'posts/logo.png' %}" alt="Logo">
    ...
</body>
</html>

9. Formularios Profesionales (El Ciclo Completo)

Ya definimos el formulario en forms.py, pero ahora hay que usarlo. El manejo de formularios tiene 2 estados: GET (cuando pides ver el formulario vacío) y POST (cuando envías los datos).

Paso 1: La Vista (Lógica)

posts/views.py
from django.shortcuts import render, redirect
from .forms import PostForm

def crear_post(request):
    if request.method == 'POST':
        # Rellenamos el formulario con los datos recibidos
        form = PostForm(request.POST)
        # Django valida automáticamente (¿Campos vacíos? ¿Formato mal?)
        if form.is_valid():
            form.save() # Guardar en base de datos
            return redirect('inicio') # Volver al inicio
    else:
        # Si es GET, mostramos el formulario vacío
        form = PostForm()

    return render(request, 'posts/crear.html', {'form': form})

Paso 2: El Template (HTML)

Django renderiza los inputs por ti, pero no olvides el token de seguridad CSRF (evita hackeos).

templates/posts/crear.html
{% extends 'base.html' %}

{% block contenido %}
    <h2>Crear nuevo artículo</h2>
    
    <form method="post">
        {% csrf_token %}  <!-- OBLIGATORIO por seguridad -->
        
        <!-- Imprime los campos como párrafos (as_p) -->
        {{ form.as_p }}
        
        <button type="submit">Guardar</button>
    </form>
{% endblock %}

10. Despliegue (Production): Salir al mundo real

Cuando trabajas en tu PC usas runserver. Eso NUNCA debe usarse en internet. Es inseguro y lento.

Checklist de Seguridad (settings.py):
  • DEBUG = False (Para que los usuarios no vean tus errores de código).
  • ALLOWED_HOSTS = ['midominio.com'] (Solo permite entrar desde tu web).
  • SECRET_KEY (Guárdala en variables de entorno, no en el código).

La Arquitectura Real

Para poner Django online (en AWS, DigitalOcean, etc.) necesitas 3 piezas:

  1. Nginx: Recibe las peticiones del usuario (Puerto 80).
  2. Gunicorn: Es un servidor WSGI que traduce las peticiones de Nginx a Python.
  3. Django: Tu código.
Terminal (Instalar Gunicorn)
pip install gunicorn
# Ejecutar en el servidor real:
gunicorn mi_blog.wsgi:application

Archivos Estáticos en Producción

En producción, Django deja de servir imágenes CSS por rendimiento. Debes ejecutar un comando que las reúne todas en una carpeta para que Nginx las sirva:

python manage.py collectstatic