Volver al inicio

Rastreador de eventos para MVP en Django y SQLite: análisis rápidos

El artículo describe la creación de un rastreador de eventos minimalista para MVP en Django y SQLite. La solución permite la recopilación rápida de métricas clave mediante píxel, ahorra tiempo y recursos al inicio del proyecto. Se proporcionan ejemplos de código para backend y frontend Next.js.

Rastreador de eventos ligero: Django + SQLite para MVP rápido
Advertisement 728x90

Rastreador Minimalista de Eventos para MVP: Django, SQLite y Píxel de Seguimiento

Al lanzar un MVP, es clave validar rápidamente y con bajo costo las acciones principales de los usuarios. En vez de integrar plataformas pesadas de análisis, despliega un backend ligero en Django que recolecta eventos mediante un píxel de seguimiento y los guarda en SQLite. Este enfoque ahorra tiempo, evita infraestructuras complejas y te permite centrarte en probar tu hipótesis principal.

Arquitectura de un Rastreador de Eventos Simple

La solución gira en torno a un backend minimalista desplegado una sola vez en un servicio de hosting para soportar múltiples frontends. El frontend envía una petición GET al endpoint /t.gif con parámetros de evento y fuente. El backend incrementa de forma atómica un contador en la base de datos. Consulta las estadísticas mediante el endpoint protegido /api/stats, que devuelve datos en JSON.

Componentes clave del sistema:

Google AdInline article slot
  • Frontend: Llama a track(event, src) creando un objeto Image.
  • Backend (Django): Procesa la petición y actualiza el contador en SQLite.
  • Base de datos: Una sola tabla con campos event, src, count y updated_at.
  • API de estadísticas: Acceso autenticado por clave a datos agregados.

Este rastreador brilla en proyectos con hosting gratuito donde el sistema de archivos es efímero y los servicios se duermen tras inactividad.

Implementación con Django y SQLite

El modelo de datos es súper simple, con un índice único en la pareja event y src.

# tracker/models.py
from django.db import models

class Counter(models.Model):
    event = models.CharField(max_length=120)
    src = models.CharField(max_length=120, blank=True, default="")
    count = models.PositiveBigIntegerField(default=0)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        unique_together = ("event", "src")

    def __str__(self) -> str:
        return f"{self.src}:{self.event}={self.count}"

El endpoint de registro de eventos sirve un píxel 1×1 codificado en base64 para evitar problemas de CORS y librerías extras del cliente.

Google AdInline article slot
# tracker/views.py
import base64

from django.conf import settings
from django.db import transaction
from django.db.models import F
from django.http import HttpResponse, JsonResponse
from django.views.decorators.http import require_GET

from .models import Counter

_GIF_1x1 = base64.b64decode(
    "R0lGODlhAQABAPAAAAAAAAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="
)

@require_GET
def pixel(request):
    event = _clean(request.GET.get("e", ""), 120)
    src = _clean(request.GET.get("src", ""), 120)

    if not event:
        return _gif_response()

    with transaction.atomic():
        obj, created = Counter.objects.get_or_create(event=event, src=src)

        if created:
            obj.count = 1
            obj.save(update_fields=["count"])
        else:
            Counter.objects.filter(pk=obj.pk).update(count=F("count") + 1)

    return _gif_response()

Las actualizaciones atómicas con F("count") + 1 garantizan integridad de datos bajo peticiones concurrentes. El endpoint de estadísticas filtra por evento y fuente si se proporcionan parámetros.

Integración en Frontend con Next.js

En el lado del cliente, una función auxiliar portátil funciona sin cambios en distintos proyectos.

// src/utils/track.ts
const TRACK_BASE = "https://tu-dominio.com/t.gif";

export const track = (event: string, src: string) => {
  const img = new Image();
  img.src =
    `${TRACK_BASE}?` +
    `e=${encodeURIComponent(event)}` +
    `&src=${encodeURIComponent(src)}` +
    `&t=${Date.now()}`;
};

Ejemplo en un componente de Next.js para rastrear clics en el botón de crear proyecto:

Google AdInline article slot
// src/app/_ui/HomePageClient.tsx
"use client";

import { useRouter } from "next/navigation";
import { track } from "@/utils/track";

export default function HomePageClient() {
  const router = useRouter();

  return (
    <section className="mt-8 space-y-2">
      <div
        className="app-card app-card--soft cursor-pointer hover:border-slate-500/70 hover:bg-white/5 transition-colors"
        role="button"
        tabIndex={0}
        onClick={() => {
          router.push("/demo");
          track("create_project_click", "demo_project");
        }}
      >
        Crear Proyecto
      </div>
    </section>
  );
}

Obtén estadísticas llamando a /api/stats con una clave de autenticación. La respuesta lista eventos con conteos de activaciones y tiempos de última actualización.

Ventajas y Desventajas de Este Enfoque

Un rastreador ligero para MVP ofrece beneficios prácticos:

  • Pruebas Rápidas de Hipótesis: Enfócate en una acción clave en lugar de métricas infinitas.
  • Ahorro de Recursos: Sin herramientas analíticas pesadas ni bases de datos separadas.
  • Versatilidad: Un solo backend atiende múltiples frontends y proyectos.
  • Despliegue Fácil: Requisitos mínimos de hosting — ideal para planes gratuitos.

Pero tiene límites naturales:

  • Sin rastreo de usuarios únicos ni sesiones.
  • Falta embudos, retención o segmentación.
  • Sin pruebas A/B ni reportes avanzados.

Agrégalo después, cuando tu MVP demuestre viabilidad.

Lecciones Clave

  • Una Métrica Vence a Veinte: Para MVP, clava una acción central que pruebe tu hipótesis principal.
  • Infraestructura Ligera: SQLite y un píxel evitan dolores de despliegue.
  • Operaciones Atómicas: F("count") + 1 mantiene datos sólidos bajo carga.
  • Auxiliar Portátil: 10 líneas de código cliente para cualquier framework moderno.
  • Lanzamiento Rápido: Despliega en horas y empieza a recolectar datos ya.

Este rastreador no reemplaza suites analíticas completas, pero responde barato la gran pregunta: ¿Está ocurriendo la acción clave? Si no, el problema es el producto, no la falta de métricas.

— Editorial Team

Advertisement 728x90

Leer después