📚 PARTE 2: TEMPLATES Y CÓDIGO COMPLETO

Sistema de Biblioteca Híbrido Django + MySQL + MongoDB

Universidad Tecnológica de Hermosillo - Servicios Web

📌 Contenido de esta Guía - PARTE 2

Esta es la continuación de la PARTE 1. Aquí encontrarás:

  • ✅ Todos los templates HTML (base, dashboard, crear, editar, listar, etc.)
  • ✅ Código completo de views.py con todas las funciones
  • ✅ Configuración completa de urls.py
  • ✅ Código de models.py con el modelo Libro
  • ✅ Código de admin.py personalizado
  • ✅ Utilidades de MongoDB (mongo_utils.py)
  • ✅ Scripts auxiliares y configuraciones finales

📄 SECCIÓN 9: TEMPLATES HTML COMPLETOS

📂 Estructura de Carpetas para Templates:
biblioteca_project/
└── biblioteca/
    └── templates/
        └── biblioteca/
            ├── base.html
            ├── inicio.html
            ├── dashboard.html
            ├── listar_libros.html
            ├── crear_libro.html
            ├── editar_libro.html
            ├── detalle_libro.html
            ├── confirmar_eliminacion.html
            └── estadisticas.html

9.1 Template Base (base.html)

📄 biblioteca/templates/biblioteca/base.html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Sistema Biblioteca{% endblock %}</title>
    
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    
    <!-- Chart.js para gráficas -->
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    
    <style>
        :root {
            --primary-color: #f093fb;
            --secondary-color: #f5576c;
            --dark-color: #2c3e50;
            --light-bg: #f8f9fa;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
            min-height: 100vh;
        }
        
        .navbar {
            background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)) !important;
            box-shadow: 0 4px 12px rgba(0,0,0,0.2);
        }
        
        .navbar-brand {
            font-weight: bold;
            font-size: 1.5em;
        }
        
        .main-container {
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            margin: 30px auto;
            padding: 40px;
            max-width: 1200px;
        }
        
        .card {
            border: none;
            border-radius: 12px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            transition: transform 0.3s;
        }
        
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 8px 20px rgba(0,0,0,0.15);
        }
        
        .btn-primary {
            background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
            border: none;
            padding: 10px 25px;
            border-radius: 8px;
            font-weight: 600;
            transition: 0.3s;
        }
        
        .btn-primary:hover {
            transform: scale(1.05);
            box-shadow: 0 5px 15px rgba(240, 147, 251, 0.4);
        }
        
        footer {
            background: var(--dark-color);
            color: white;
            padding: 30px 0;
            margin-top: 50px;
            text-align: center;
        }
    </style>
    
    {% block extra_css %}{% endblock %}
</head>
<body>
    <!-- Navbar -->
    <nav class="navbar navbar-expand-lg navbar-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="{% url 'inicio' %}">
                📚 Biblioteca UTH
            </a>
            
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'inicio' %}">🏠 Inicio</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'listar_libros' %}">📖 Catálogo</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'crear_libro' %}">➕ Agregar Libro</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'estadisticas' %}">📊 Estadísticas</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <!-- Mensajes de Django -->
    {% if messages %}
        <div class="container mt-4">
            {% for message in messages %}
                <div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
                    {{ message }}
                    <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
                </div>
            {% endfor %}
        </div>
    {% endif %}

    <!-- Contenido principal -->
    <div class="main-container">
        {% block content %}{% endblock %}
    </div>

    <!-- Footer -->
    <footer>
        <div class="container">
            <p><strong>Universidad Tecnológica de Hermosillo</strong></p>
            <p>Sistema Híbrido de Biblioteca - MySQL + MongoDB</p>
            <p style="opacity: 0.7; margin-top: 15px;">© 2026 UTH - Servicios Web</p>
        </div>
    </footer>

    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    
    {% block extra_js %}{% endblock %}
</body>
</html>

9.2 Página de Inicio (inicio.html)

📄 biblioteca/templates/biblioteca/inicio.html
{% extends 'biblioteca/base.html' %}

{% block title %}Inicio - Sistema Biblioteca{% endblock %}

{% block content %}
<div class="text-center mb-5">
    <h1 class="display-3">📚 Bienvenido al Sistema de Biblioteca</h1>
    <p class="lead text-muted">Sistema Híbrido MySQL + MongoDB</p>
</div>

<!-- Estadísticas Generales -->
<div class="row mb-5">
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #f093fb; font-size: 3em;">{{ total_libros_mysql }}</h2>
                <p class="text-muted">Libros en MySQL</p>
                <small class="badge bg-info">Base de Datos SQL</small>
            </div>
        </div>
    </div>
    
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #f5576c; font-size: 3em;">{{ total_libros_mongo }}</h2>
                <p class="text-muted">Documentos en MongoDB</p>
                <small class="badge bg-success">Base de Datos NoSQL</small>
            </div>
        </div>
    </div>
    
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #667eea; font-size: 3em;">2</h2>
                <p class="text-muted">Bases de Datos Activas</p>
                <small class="badge bg-warning text-dark">Sistema Híbrido</small>
            </div>
        </div>
    </div>
</div>

<!-- Top Libros Más Vistos -->
<div class="card mb-4">
    <div class="card-header" style="background: linear-gradient(90deg, #f093fb, #f5576c); color: white;">
        <h3>🔥 Top 5 Libros Más Vistos</h3>
    </div>
    <div class="card-body">
        {% if top_libros %}
            <div class="list-group">
                {% for libro in top_libros %}
                    <div class="list-group-item d-flex justify-content-between align-items-center">
                        <div>
                            <h5>{{ forloop.counter }}. {{ libro.titulo }}</h5>
                            <small class="text-muted">Libro ID: {{ libro.libro_id }}</small>
                        </div>
                        <span class="badge bg-primary rounded-pill">👁️ {{ libro.views }} vistas</span>
                    </div>
                {% endfor %}
            </div>
        {% else %}
            <p class="text-muted text-center">No hay datos de estadísticas aún</p>
        {% endif %}
    </div>
</div>

<!-- Acciones Rápidas -->
<div class="row">
    <div class="col-md-6 mb-3">
        <div class="card h-100">
            <div class="card-body text-center">
                <div style="font-size: 4em; margin-bottom: 20px;">📖</div>
                <h4>Ver Catálogo</h4>
                <p class="text-muted">Explora todos los libros disponibles</p>
                <a href="{% url 'listar_libros' %}" class="btn btn-primary">Ir al Catálogo</a>
            </div>
        </div>
    </div>
    
    <div class="col-md-6 mb-3">
        <div class="card h-100">
            <div class="card-body text-center">
                <div style="font-size: 4em; margin-bottom: 20px;">📊</div>
                <h4>Ver Estadísticas</h4>
                <p class="text-muted">Dashboard con métricas y gráficas</p>
                <a href="{% url 'estadisticas' %}" class="btn btn-primary">Ver Dashboard</a>
            </div>
        </div>
    </div>
</div>
{% endblock %}

9.3 Listado de Libros (listar_libros.html)

📄 biblioteca/templates/biblioteca/listar_libros.html
{% extends 'biblioteca/base.html' %}

{% block title %}Listado de Libros{% endblock %}

{% block content %}
<div class="container mt-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <h1>📚 Listado de Libros</h1>
        <a href="{% url 'crear_libro' %}" class="btn btn-success">
            <i class="fas fa-plus"></i> Agregar Nuevo Libro
        </a>
    </div>

    <!-- Barra de búsqueda -->
    <div class="card mb-4">
        <div class="card-body">
            <form method="get" action="{% url 'listar_libros' %}">
                <div class="input-group">
                    <input type="text" class="form-control" name="q" value="{{ query }}" 
                           placeholder="Buscar por título o autor...">
                    <button class="btn btn-primary" type="submit">
                        <i class="fas fa-search"></i> Buscar
                    </button>
                    {% if query %}
                        <a href="{% url 'listar_libros' %}" class="btn btn-secondary">
                            <i class="fas fa-times"></i> Limpiar
                        </a>
                    {% endif %}
                </div>
            </form>
        </div>
    </div>

    <!-- Lista de libros -->
    {% if libros %}
        <div class="row">
            {% for libro in libros %}
                <div class="col-md-4 mb-4">
                    <div class="card h-100 shadow-sm">
                        <div class="card-body">
                            <h5 class="card-title text-primary">{{ libro.titulo }}</h5>
                            <p class="card-text">
                                <strong>Autor:</strong> {{ libro.autor }}<br>
                                <strong>ISBN:</strong> {{ libro.isbn }}<br>
                                <strong>Precio:</strong> ${{ libro.precio }}<br>
                                <strong>Stock:</strong> {{ libro.stock }} unidades
                            </p>
                            
                            {% if libro.stock > 0 %}
                                <span class="badge bg-success">Disponible</span>
                            {% else %}
                                <span class="badge bg-danger">No Disponible</span>
                            {% endif %}
                        </div>
                        
                        <div class="card-footer bg-transparent">
                            <div class="btn-group w-100" role="group">
                                <a href="{% url 'detalle_libro' libro.id %}" class="btn btn-sm btn-outline-primary">Ver</a>
                                <a href="{% url 'editar_libro' libro.id %}" class="btn btn-sm btn-outline-secondary">Editar</a>
                                <a href="{% url 'eliminar_libro' libro.id %}" class="btn btn-sm btn-outline-danger">Eliminar</a>
                            </div>
                        </div>
                    </div>
                </div>
            {% endfor %}
        </div>
    {% else %}
        <div class="alert alert-warning text-center">
            <h4>No se encontraron libros</h4>
            <a href="{% url 'crear_libro' %}" class="btn btn-success">Agregar Primer Libro</a>
        </div>
    {% endif %}
</div>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
{% endblock %}

9.4 Formulario Crear Libro (crear_libro.html)

📄 biblioteca/templates/biblioteca/crear_libro.html
{% extends 'biblioteca/base.html' %}

{% block title %}Agregar Nuevo Libro{% endblock %}

{% block content %}
<div class="mb-4">
    <a href="{% url 'listar_libros' %}" class="btn btn-outline-secondary">← Volver al Catálogo</a>
</div>

<div class="card">
    <div class="card-header" style="background: linear-gradient(90deg, #f093fb, #f5576c); color: white;">
        <h2>➕ Agregar Nuevo Libro</h2>
    </div>
    <div class="card-body">
        <form method="post" action="{% url 'crear_libro' %}">
            {% csrf_token %}
            
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="titulo" class="form-label">📝 Título *</label>
                    <input type="text" class="form-control" id="titulo" name="titulo" required>
                </div>
                
                <div class="col-md-6 mb-3">
                    <label for="autor" class="form-label">✍️ Autor *</label>
                    <input type="text" class="form-control" id="autor" name="autor" required>
                </div>
            </div>
            
            <div class="row">
                <div class="col-md-4 mb-3">
                    <label for="isbn" class="form-label">🔢 ISBN *</label>
                    <input type="text" class="form-control" id="isbn" name="isbn" required>
                </div>
                
                <div class="col-md-4 mb-3">
                    <label for="fecha_publicacion" class="form-label">📅 Fecha Publicación *</label>
                    <input type="date" class="form-control" id="fecha_publicacion" name="fecha_publicacion" required>
                </div>
                
                <div class="col-md-4 mb-3">
                    <label for="precio" class="form-label">💰 Precio *</label>
                    <input type="number" step="0.01" class="form-control" id="precio" name="precio" required>
                </div>
            </div>
            
            <div class="mb-3">
                <label for="stock" class="form-label">📦 Stock</label>
                <input type="number" class="form-control" id="stock" name="stock" value="1">
            </div>
            
            <div class="mb-3">
                <label for="descripcion" class="form-label">📄 Descripción</label>
                <textarea class="form-control" id="descripcion" name="descripcion" rows="4"></textarea>
            </div>
            
            <div class="alert alert-info">
                <strong>💡 Nota:</strong> Al crear el libro se guardará en MySQL y MongoDB
            </div>
            
            <div class="d-flex justify-content-between">
                <a href="{% url 'listar_libros' %}" class="btn btn-secondary">Cancelar</a>
                <button type="submit" class="btn btn-primary">💾 Guardar Libro</button>
            </div>
        </form>
    </div>
</div>
{% endblock %}

9.5 Detalle de Libro (detalle_libro.html)

📄 biblioteca/templates/biblioteca/detalle_libro.html
{% extends 'biblioteca/base.html' %}

{% block title %}{{ libro.titulo }} - Detalle{% endblock %}

{% block content %}
<div class="mb-4">
    <a href="{% url 'listar_libros' %}" class="btn btn-outline-secondary">← Volver al Catálogo</a>
</div>

<div class="row">
    <div class="col-md-8">
        <div class="card">
            <div class="card-header" style="background: linear-gradient(90deg, #f093fb, #f5576c); color: white;">
                <h2>📖 {{ libro.titulo }}</h2>
            </div>
            <div class="card-body">
                <table class="table table-borderless">
                    <tbody>
                        <tr>
                            <th width="200">📝 Título:</th>
                            <td><strong>{{ libro.titulo }}</strong></td>
                        </tr>
                        <tr>
                            <th>✍️ Autor:</th>
                            <td>{{ libro.autor }}</td>
                        </tr>
                        <tr>
                            <th>🔢 ISBN:</th>
                            <td><code>{{ libro.isbn }}</code></td>
                        </tr>
                        <tr>
                            <th>📅 Fecha Publicación:</th>
                            <td>{{ libro.fecha_publicacion }}</td>
                        </tr>
                        <tr>
                            <th>💰 Precio:</th>
                            <td><span class="badge bg-success">${{ libro.precio }}</span></td>
                        </tr>
                        <tr>
                            <th>📦 Stock:</th>
                            <td>
                                {% if libro.stock > 0 %}
                                    <span class="badge bg-info">{{ libro.stock }} unidades</span>
                                {% else %}
                                    <span class="badge bg-danger">Agotado</span>
                                {% endif %}
                            </td>
                        </tr>
                    </tbody>
                </table>
                
                {% if libro.descripcion %}
                    <hr>
                    <h5>📄 Descripción:</h5>
                    <p>{{ libro.descripcion }}</p>
                {% endif %}
            </div>
        </div>
        
        <div class="mt-4">
            <a href="{% url 'editar_libro' libro.id %}" class="btn btn-primary">✏️ Editar Libro</a>
            <a href="{% url 'eliminar_libro' libro.id %}" class="btn btn-danger">🗑️ Eliminar Libro</a>
        </div>
    </div>
    
    <div class="col-md-4">
        <div class="card mb-3">
            <div class="card-header bg-info text-white">
                <h5>📊 Estadísticas (MongoDB)</h5>
            </div>
            <div class="card-body text-center">
                <div class="mb-3">
                    <h2 style="color: #f093fb;">{{ views }}</h2>
                    <p class="text-muted">👁️ Vistas Totales</p>
                </div>
                
                <div>
                    <h2 style="color: #f5576c;">{{ prestamos }}</h2>
                    <p class="text-muted">📚 Préstamos Realizados</p>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

9.6 Dashboard Principal (dashboard.html)

📄 biblioteca/templates/biblioteca/dashboard.html
{% extends 'biblioteca/base.html' %}

{% block title %}Dashboard - Sistema Biblioteca{% endblock %}

{% block content %}
<div class="container mt-4">
    <h1 class="mb-4">
        <i class="fas fa-chart-line"></i> Panel de Control
    </h1>

    <!-- Tarjetas de Estadísticas -->
    <div class="row mb-4">
        <div class="col-md-3">
            <div class="card text-white bg-primary mb-3">
                <div class="card-body">
                    <h5 class="card-title">
                        <i class="fas fa-book"></i> Total Libros
                    </h5>
                    <h2 class="card-text">{{ total_libros }}</h2>
                </div>
            </div>
        </div>

        <div class="col-md-3">
            <div class="card text-white bg-success mb-3">
                <div class="card-body">
                    <h5 class="card-title">
                        <i class="fas fa-check-circle"></i> Disponibles
                    </h5>
                    <h2 class="card-text">{{ libros_disponibles }}</h2>
                </div>
            </div>
        </div>

        <div class="col-md-3">
            <div class="card text-white bg-warning mb-3">
                <div class="card-body">
                    <h5 class="card-title">
                        <i class="fas fa-hand-holding"></i> Préstamos Activos
                    </h5>
                    <h2 class="card-text">{{ total_prestamos_activos }}</h2>
                </div>
            </div>
        </div>

        <div class="col-md-3">
            <div class="card text-white bg-info mb-3">
                <div class="card-body">
                    <h5 class="card-title">
                        <i class="fas fa-history"></i> Total Préstamos
                    </h5>
                    <h2 class="card-text">{{ total_prestamos_historico }}</h2>
                </div>
            </div>
        </div>
    </div>

    <!-- Acciones Rápidas -->
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header bg-dark text-white">
                    <h5><i class="fas fa-bolt"></i> Acciones Rápidas</h5>
                </div>
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-4 mb-3">
                            <a href="{% url 'listar_libros' %}" class="btn btn-primary btn-lg w-100">
                                <i class="fas fa-list"></i> Ver Todos los Libros
                            </a>
                        </div>
                        <div class="col-md-4 mb-3">
                            <a href="{% url 'crear_libro' %}" class="btn btn-success btn-lg w-100">
                                <i class="fas fa-plus"></i> Agregar Nuevo Libro
                            </a>
                        </div>
                        <div class="col-md-4 mb-3">
                            <a href="/admin/" class="btn btn-info btn-lg w-100">
                                <i class="fas fa-cog"></i> Panel de Administración
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Información del Sistema -->
    <div class="row mt-4">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header bg-dark text-white">
                    <h5><i class="fas fa-database"></i> Estadísticas de Bases de Datos</h5>
                </div>
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-6">
                            <h6><i class="fas fa-server"></i> MySQL (Relacional)</h6>
                            <ul class="list-group">
                                <li class="list-group-item d-flex justify-content-between">
                                    <strong>Libros</strong>
                                    <span class="badge bg-primary">{{ total_libros }}</span>
                                </li>
                                <li class="list-group-item d-flex justify-content-between">
                                    <strong>Estado</strong>
                                    <span class="badge bg-success">✅ Conectado</span>
                                </li>
                            </ul>
                        </div>
                        
                        <div class="col-md-6">
                            <h6><i class="fas fa-leaf"></i> MongoDB (NoSQL)</h6>
                            {% if mongodb_stats.mongodb_conectado %}
                            <ul class="list-group">
                                <li class="list-group-item d-flex justify-content-between">
                                    <strong>Logs</strong>
                                    <span class="badge bg-warning text-dark">{{ mongodb_stats.logs_count }}</span>
                                </li>
                                <li class="list-group-item d-flex justify-content-between">
                                    <strong>Total Documentos</strong>
                                    <span class="badge bg-primary">{{ mongodb_stats.total_documentos }}</span>
                                </li>
                                <li class="list-group-item d-flex justify-content-between">
                                    <strong>Estado</strong>
                                    <span class="badge bg-success">✅ Conectado</span>
                                </li>
                            </ul>
                            {% else %}
                            <div class="alert alert-warning">MongoDB no disponible</div>
                            {% endif %}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
{% endblock %}

9.7 Formulario Editar Libro (editar_libro.html)

📄 biblioteca/templates/biblioteca/editar_libro.html
{% extends 'biblioteca/base.html' %}

{% block title %}Editar: {{ libro.titulo }}{% endblock %}

{% block content %}
<div class="mb-4">
    <a href="{% url 'detalle_libro' libro.id %}" class="btn btn-outline-secondary">← Volver a Detalles</a>
</div>

<div class="card">
    <div class="card-header" style="background: linear-gradient(90deg, #f093fb, #f5576c); color: white;">
        <h2>✏️ Editar Libro: {{ libro.titulo }}</h2>
    </div>
    <div class="card-body">
        <form method="post" action="{% url 'editar_libro' libro.id %}">
            {% csrf_token %}
            
            <div class="row">
                <div class="col-md-6 mb-3">
                    <label for="titulo" class="form-label">📝 Título *</label>
                    <input type="text" class="form-control" id="titulo" name="titulo" 
                           value="{{ libro.titulo }}" required>
                </div>
                
                <div class="col-md-6 mb-3">
                    <label for="autor" class="form-label">✍️ Autor *</label>
                    <input type="text" class="form-control" id="autor" name="autor" 
                           value="{{ libro.autor }}" required>
                </div>
            </div>
            
            <div class="row">
                <div class="col-md-4 mb-3">
                    <label for="isbn" class="form-label">🔢 ISBN *</label>
                    <input type="text" class="form-control" id="isbn" name="isbn" 
                           value="{{ libro.isbn }}" required>
                </div>
                
                <div class="col-md-4 mb-3">
                    <label for="fecha_publicacion" class="form-label">📅 Fecha Publicación *</label>
                    <input type="date" class="form-control" id="fecha_publicacion" name="fecha_publicacion" 
                           value="{{ libro.fecha_publicacion|date:'Y-m-d' }}" required>
                </div>
                
                <div class="col-md-4 mb-3">
                    <label for="precio" class="form-label">💰 Precio *</label>
                    <input type="number" step="0.01" class="form-control" id="precio" name="precio" 
                           value="{{ libro.precio }}" required>
                </div>
            </div>
            
            <div class="mb-3">
                <label for="stock" class="form-label">📦 Stock</label>
                <input type="number" class="form-control" id="stock" name="stock" 
                       value="{{ libro.stock }}">
            </div>
            
            <div class="mb-3">
                <label for="descripcion" class="form-label">📄 Descripción</label>
                <textarea class="form-control" id="descripcion" name="descripcion" 
                          rows="4">{{ libro.descripcion }}</textarea>
            </div>
            
            <div class="alert alert-warning">
                <strong>⚠️ Importante:</strong> Al actualizar el libro se modificará en MySQL y MongoDB
            </div>
            
            <div class="d-flex justify-content-between">
                <a href="{% url 'detalle_libro' libro.id %}" class="btn btn-secondary">Cancelar</a>
                <button type="submit" class="btn btn-primary">💾 Guardar Cambios</button>
            </div>
        </form>
    </div>
</div>
{% endblock %}

9.8 Confirmar Eliminación (confirmar_eliminacion.html)

📄 biblioteca/templates/biblioteca/confirmar_eliminacion.html
{% extends 'biblioteca/base.html' %}

{% block title %}Confirmar Eliminación{% endblock %}

{% block content %}
<div class="mb-4">
    <a href="{% url 'detalle_libro' libro.id %}" class="btn btn-outline-secondary">← Volver a Detalles</a>
</div>

<div class="card border-danger">
    <div class="card-header bg-danger text-white">
        <h2>⚠️ Confirmar Eliminación</h2>
    </div>
    <div class="card-body">
        <div class="alert alert-danger">
            <h4>🗑️ ¿Estás seguro de eliminar este libro?</h4>
            <p>Esta acción <strong>NO se puede deshacer</strong>.</p>
        </div>
        
        <h5>Información del Libro a Eliminar:</h5>
        <table class="table table-bordered">
            <tbody>
                <tr>
                    <th width="200">Título:</th>
                    <td><strong>{{ libro.titulo }}</strong></td>
                </tr>
                <tr>
                    <th>Autor:</th>
                    <td>{{ libro.autor }}</td>
                </tr>
                <tr>
                    <th>ISBN:</th>
                    <td>{{ libro.isbn }}</td>
                </tr>
                <tr>
                    <th>Stock:</th>
                    <td>{{ libro.stock }} unidades</td>
                </tr>
            </tbody>
        </table>
        
        <form method="post" action="{% url 'eliminar_libro' libro.id %}">
            {% csrf_token %}
            
            <div class="mb-3">
                <label for="motivo" class="form-label">Motivo de Eliminación (Opcional):</label>
                <textarea class="form-control" id="motivo" name="motivo" rows="3" 
                          placeholder="Ej: Libro descontinuado, duplicado, etc."></textarea>
            </div>
            
            <div class="alert alert-info">
                <strong>📝 Nota:</strong> Al eliminar el libro se borrará de MySQL y se archivará en MongoDB
            </div>
            
            <div class="d-flex justify-content-between">
                <a href="{% url 'detalle_libro' libro.id %}" class="btn btn-secondary">❌ Cancelar</a>
                <button type="submit" class="btn btn-danger">🗑️ Sí, Eliminar Definitivamente</button>
            </div>
        </form>
    </div>
</div>
{% endblock %}

9.9 Página de Estadísticas (estadisticas.html)

📄 biblioteca/templates/biblioteca/estadisticas.html
{% extends 'biblioteca/base.html' %}

{% block title %}Estadísticas del Sistema{% endblock %}

{% block content %}
<h1 class="mb-4">📊 Dashboard de Estadísticas</h1>

<!-- Resumen General -->
<div class="row mb-4">
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #f093fb;">{{ total_libros }}</h2>
                <p class="text-muted">Total Libros (MySQL)</p>
            </div>
        </div>
    </div>
    
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #f5576c;">{{ total_stock }}</h2>
                <p class="text-muted">Stock Total</p>
            </div>
        </div>
    </div>
    
    <div class="col-md-4">
        <div class="card text-center">
            <div class="card-body">
                <h2 style="color: #667eea;">{{ total_views }}</h2>
                <p class="text-muted">Vistas Totales (MongoDB)</p>
            </div>
        </div>
    </div>
</div>

<!-- Gráficas -->
<div class="row mb-4">
    <div class="col-md-6">
        <div class="card">
            <div class="card-header bg-info text-white">
                <h5>👁️ Top 10 Más Vistos</h5>
            </div>
            <div class="card-body">
                <canvas id="chartVistos"></canvas>
            </div>
        </div>
    </div>
    
    <div class="col-md-6">
        <div class="card">
            <div class="card-header bg-success text-white">
                <h5>📚 Top 10 Más Prestados</h5>
            </div>
            <div class="card-body">
                <canvas id="chartPrestados"></canvas>
            </div>
        </div>
    </div>
</div>

<!-- Actividad Reciente -->
<div class="card">
    <div class="card-header bg-warning">
        <h5>📝 Actividad Reciente (MongoDB Logs)</h5>
    </div>
    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-hover">
                <thead>
                    <tr>
                        <th>Acción</th>
                        <th>Libro</th>
                        <th>Fecha y Hora</th>
                    </tr>
                </thead>
                <tbody>
                    {% for log in logs_recientes %}
                        <tr>
                            <td>
                                {% if log.accion == 'crear_libro' %}
                                    <span class="badge bg-success">➕ Crear</span>
                                {% elif log.accion == 'ver_detalle' %}
                                    <span class="badge bg-info">👁️ Ver</span>
                                {% endif %}
                            </td>
                            <td>{{ log.libro_titulo|default:"N/A" }}</td>
                            <td><small>{{ log.timestamp|date:"d/m/Y H:i:s" }}</small></td>
                        </tr>
                    {% empty %}
                        <tr>
                            <td colspan="3" class="text-center text-muted">No hay actividad registrada</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>

<script>
// Datos para gráfica de libros más vistos
const dataVistos = {
    labels: [
        {% for libro in top_vistos %}
            '{{ libro.titulo|truncatechars:30 }}'{% if not forloop.last %},{% endif %}
        {% endfor %}
    ],
    datasets: [{
        label: 'Vistas',
        data: [
            {% for libro in top_vistos %}
                {{ libro.views|default:0 }}{% if not forloop.last %},{% endif %}
            {% endfor %}
        ],
        backgroundColor: 'rgba(54, 162, 235, 0.5)',
        borderColor: 'rgba(54, 162, 235, 1)',
        borderWidth: 2
    }]
};

// Crear gráfica
const ctxVistos = document.getElementById('chartVistos');
if (ctxVistos) {
    new Chart(ctxVistos, {
        type: 'bar',
        data: dataVistos,
        options: {
            responsive: true,
            scales: {
                y: {
                    beginAtZero: true
                }
            }
        }
    });
}
</script>

{% endblock %}

9.10 Listado de Préstamos (mis_prestamos.html)

📄 biblioteca/templates/biblioteca/mis_prestamos.html
{% extends 'biblioteca/base.html' %}

{% block title %}Mis Préstamos{% endblock %}

{% block content %}
<div class="row mb-4">
    <div class="col-12">
        <h1>📚 Mis Préstamos</h1>
    </div>
</div>

<div class="alert alert-info">
    Total de préstamos: <strong>{{ total_prestamos }}</strong>
</div>

<div class="row">
    {% for prestamo in prestamos %}
    <div class="col-md-6 mb-4">
        <div class="card h-100 shadow-sm">
            <div class="card-header" 
                 {% if prestamo.estado == 'ACTIVO' %}
                     style="background-color: #28a745; color: white;"
                 {% else %}
                     style="background-color: #6c757d; color: white;"
                 {% endif %}>
                <strong>Préstamo #{{ prestamo.id }}</strong>
                <span class="badge bg-light text-dark float-end">{{ prestamo.estado }}</span>
            </div>
            <div class="card-body">
                <h5 class="card-title">{{ prestamo.libro.titulo }}</h5>
                <p class="mb-1">
                    <strong>Autor:</strong> {{ prestamo.libro.autor }}
                </p>
                <p class="mb-1">
                    <strong>Fecha préstamo:</strong> 
                    {{ prestamo.fecha_prestamo|date:"d/m/Y H:i" }}
                </p>
                {% if prestamo.fecha_devolucion %}
                <p class="mb-1">
                    <strong>Fecha devolución:</strong> 
                    {{ prestamo.fecha_devolucion|date:"d/m/Y H:i" }}
                </p>
                {% endif %}
            </div>
            
            {% if prestamo.estado == 'ACTIVO' %}
            <div class="card-footer">
                <form method="POST" action="{% url 'devolver_libro' prestamo.id %}">
                    {% csrf_token %}
                    <button type="submit" class="btn btn-warning w-100">
                        Devolver Libro
                    </button>
                </form>
            </div>
            {% endif %}
        </div>
    </div>
    {% empty %}
    <div class="col-12">
        <div class="alert alert-warning text-center">
            <h4>📭 No tienes préstamos registrados</h4>
            <a href="{% url 'listar_libros' %}" class="btn btn-primary">Ver Catálogo</a>
        </div>
    </div>
    {% endfor %}
</div>
{% endblock %}

9.11 Formulario Registrar Préstamo (registrar_prestamo.html)

📄 biblioteca/templates/biblioteca/registrar_prestamo.html
{% extends 'biblioteca/base.html' %}

{% block title %}Registrar Préstamo{% endblock %}

{% block content %}
<div class="row justify-content-center">
    <div class="col-md-8">
        <div class="card shadow">
            <div class="card-header bg-gradient" style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">
                <h2 class="text-white mb-0">📚 Registrar Nuevo Préstamo</h2>
            </div>
            <div class="card-body">
                <form method="post">
                    {% csrf_token %}
                    
                    <div class="mb-3">
                        <label for="libro_id" class="form-label">Libro ID</label>
                        <input type="text" class="form-control" id="libro_id" name="libro_id" required>
                    </div>

                    <div class="mb-3">
                        <label for="usuario" class="form-label">Usuario</label>
                        <input type="text" class="form-control" id="usuario" name="usuario" required>
                    </div>

                    <div class="mb-3">
                        <label for="fecha_prestamo" class="form-label">Fecha de Préstamo</label>
                        <input type="date" class="form-control" id="fecha_prestamo" name="fecha_prestamo" required>
                    </div>

                    <div class="d-grid gap-2">
                        <button type="submit" class="btn btn-primary btn-lg">
                            💾 Registrar Préstamo
                        </button>
                        <a href="{% url 'mis_prestamos' %}" class="btn btn-secondary">Cancelar</a>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
{% endblock %}

✅ Templates Completos

¡Has terminado de crear todos los templates HTML! Ahora tu sistema tiene:

⚙️ SECCIÓN 10: ARCHIVOS DE CONFIGURACIÓN Y CÓDIGO BACKEND

10.1 admin.py - Panel de Administración

📄 biblioteca/admin.py
from django.contrib import admin
from .models import Libro

# Registrar modelo Libro con configuración personalizada
@admin.register(Libro)
class LibroAdmin(admin.ModelAdmin):
    """Configuración del admin para el modelo Libro"""
    
    # Campos a mostrar en la lista
    list_display = [
        'titulo', 
        'autor', 
        'isbn', 
        'precio', 
        'stock', 
        'disponible',
        'activo'
    ]
    
    # Filtros laterales
    list_filter = [
        'activo',
        'fecha_publicacion', 
        'fecha_creacion'
    ]
    
    # Campos de búsqueda
    search_fields = [
        'titulo', 
        'autor', 
        'isbn'
    ]
    
    # Campos editables en la lista
    list_editable = [
        'precio', 
        'stock', 
        'activo'
    ]
    
    # Ordenamiento
    ordering = ['-fecha_creacion']
    
    # Campos de solo lectura
    readonly_fields = [
        'fecha_creacion', 
        'fecha_actualizacion'
    ]
    
    # Jerarquía de fechas
    date_hierarchy = 'fecha_creacion'
    
    # Paginación
    list_per_page = 25

# Personalización del sitio admin
admin.site.site_header = "Sistema de Biblioteca UTH"
admin.site.site_title = "Biblioteca UTH Admin"
admin.site.index_title = "Panel de Administración"

10.2 urls.py - Configuración de URLs

📄 biblioteca/urls.py
from django.urls import path
from . import views

urlpatterns = [
    # Dashboard e Inicio
    path('', views.dashboard, name='dashboard'),
    path('inicio/', views.inicio, name='inicio'),
    
    # CRUD de libros
    path('libros/', views.listar_libros, name='listar_libros'),
    path('libro/crear/', views.crear_libro, name='crear_libro'),
    path('libro/<int:libro_id>/', views.detalle_libro, name='detalle_libro'),
    path('libro/<int:libro_id>/editar/', views.editar_libro, name='editar_libro'),
    path('libro/<int:libro_id>/eliminar/', views.eliminar_libro, name='eliminar_libro'),
    
    # Préstamos
    path('prestamo/crear/<int:libro_id>/', views.prestar_libro, name='prestar_libro'),
    path('prestamo/devolver/<int:prestamo_id>/', views.devolver_libro, name='devolver_libro'),
    path('prestamos/mis-prestamos/', views.mis_prestamos, name='mis_prestamos'),
    
    # Estadísticas
    path('estadisticas/', views.estadisticas, name='estadisticas'),
]
📄 biblioteca_project/urls.py
from django.contrib import admin
from django.urls import path, include

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

10.3 Script de Gráficas con Chart.js

📊 Script para gráficas de préstamos

Este código JavaScript se puede agregar en el template de estadísticas o dashboard

📄 script_grafica_prestamos.js
// Configuración de Chart.js para mostrar estadísticas de préstamos
const ctx = document.getElementById('graficaPrestamos').getContext('2d');

const dataPrestamos = {
    labels: [
        'Enero', 'Febrero', 'Marzo', 'Abril', 
        'Mayo', 'Junio', 'Julio'
    ],
    datasets: [{
        label: 'Préstamos Activos',
        data: [12, 19, 15, 25, 22, 30, 28],
        backgroundColor: 'rgba(54, 162, 235, 0.5)',
        borderColor: 'rgba(54, 162, 235, 1)',
        borderWidth: 2
    }, {
        label: 'Préstamos Devueltos',
        data: [8, 15, 12, 20, 18, 25, 23],
        backgroundColor: 'rgba(75, 192, 192, 0.5)',
        borderColor: 'rgba(75, 192, 192, 1)',
        borderWidth: 2
    }]
};

const config = {
    type: 'bar',
    data: dataPrestamos,
    options: {
        responsive: true,
        plugins: {
            legend: {
                position: 'top',
            },
            title: {
                display: true,
                text: 'Estadísticas de Préstamos Mensuales'
            }
        },
        scales: {
            y: {
                beginAtZero: true
            }
        }
    }
};

const graficaPrestamos = new Chart(ctx, config);
💡 Uso en Template HTML:
<canvas id="graficaPrestamos" width="400" height="200"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
    // Código del script aquí
</script>

🧪 SECCIÓN 11: TESTING Y VALIDACIÓN

PASO 1: Verificar que el servidor corre sin errores
python manage.py runserver

✅ Salida Esperada:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
January 30, 2026 - 10:30:00
Django version 4.1.13, using settings 'biblioteca_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
PASO 2: Probar las URLs principales
URLs a probar en el navegador:
PASO 3: Verificar MongoDB
python test_mongo.py
✅ Conexión exitosa a MongoDB Atlas
✅ Bases de datos disponibles
✅ Colecciones creadas correctamente
PASO 4: Crear libro de prueba
  1. Ve a http://127.0.0.1:8000/libro/crear/
  2. Llena el formulario con datos de prueba
  3. Haz clic en "Guardar Libro"
  4. Verifica que aparece en el listado
  5. Verifica que se creó en MongoDB (logs y estadísticas)

🔧 SECCIÓN 12: SOLUCIÓN DE PROBLEMAS COMUNES

Problema 1: "TemplateDoesNotExist"

Error: TemplateDoesNotExist at /
✅ Solución:
  1. Verifica que la carpeta templates/biblioteca/ existe
  2. Verifica que TEMPLATES en settings.py tiene 'APP_DIRS': True
  3. Asegúrate de que 'biblioteca' está en INSTALLED_APPS

Problema 2: "MongoDB Permission Error"

Error: user is not allowed to do action [insert]
✅ Solución:
  1. Ve a MongoDB Atlas → Database Access
  2. Edita tu usuario
  3. Selecciona "Atlas admin" o "Read and write to any database"
  4. Guarda cambios

Problema 3: "Table doesn't exist"

Error: Table 'biblioteca_libro' doesn't exist
✅ Solución:
python manage.py makemigrations python manage.py migrate

Problema 4: "NoReverseMatch"

Error: Reverse for 'nombre_url' not found
✅ Solución:
  1. Verifica que el nombre de la URL existe en urls.py
  2. Asegúrate de usar {% url 'nombre_correcto' %}
  3. Verifica que no hay errores de sintaxis en urls.py

🎯 CONCLUSIÓN

🎉 ¡Felicitaciones!

Has completado la PARTE 2 de la guía. Ahora tienes:

📚 Recursos Adicionales

⚠️ Recordatorios Importantes

← Volver a PARTE 1 🏠 Inicio - Introducción

🎉 ¡Felicitaciones! Has completado la guía completa

Ahora tienes un sistema de biblioteca híbrido completamente funcional con Django, MySQL y MongoDB.