Saltar al contenido principal

🐍 Configuración Proyecto Django

Setup completo para proyecto Django con Tailwind CSS, Alpine.js y tooling de calidad.

📋 Contexto​

Configurar Django moderno requiere integrar múltiples herramientas: frontend, calidad de código, type hints y base de datos.

🎯 Objetivo​

Tener un proyecto Django funcional con:

  • Tailwind CSS y Alpine.js vía CDN
  • Black, flake8 y mypy configurados
  • Type hints en modelos y vistas
  • Estructura preparada para escalar

📦 Alcance​

Incluye:

  • Instalación con Pipenv
  • Configuración settings.py
  • Template base con Tailwind/Alpine
  • Tooling de calidad
  • Type hints con mypy

🏛️ Estructura​

command-center/
├── app/
│ ├── models.py
│ ├── views.py
│ └── urls.py
├── command_center/
│ ├── settings.py
│ └── urls.py
├── templates/
│ ├── base.html
│ └── home.html
├── static/
├── docs/
└── tests/

⚙️ Setup Inicial​

1. Instalación con Pipenv​

# Crear entorno
pipenv --python 3.12

# Instalar Django
pipenv install django

# Dependencias de desarrollo
pipenv install --dev black flake8 mypy django-stubs

# Activar
pipenv shell

2. Crear Proyecto​

django-admin startproject command_center .
python manage.py startapp app

3. Settings Esenciales​

# command_center/settings.py
INSTALLED_APPS = [
# ... defaults
'app',
]

TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
# ...
}]

LANGUAGE_CODE = 'es-mx'
TIME_ZONE = 'America/Cancun'
USE_I18N = True
USE_TZ = True

STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']

🎨 Frontend​

Template Base (templates/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 %}Command Center{% endblock %}</title>
<script src="https://cdn.tailwindcss.com"></script>
<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>
</head>
<body class="bg-gray-100">
<div class="container mx-auto p-4">{% block content %}{% endblock %}</div>
</body>
</html>

🔧 Tooling de Calidad​

Black (pyproject.toml)​

[tool.black]
line-length = 88
target-version = ['py312']
extend-exclude = '''
/(
migrations
| manage\.py
| asgi\.py
| wsgi\.py
)/
'''

Flake8 (.flake8)​

[flake8]
max-line-length = 88
exclude = .git,__pycache__,migrations,manage.py
ignore = E203,W503

MyPy (mypy.ini)​

[mypy]
python_version = 3.12
plugins = mypy_django_plugin.main
ignore_missing_imports = True

[mypy.plugins.django-stubs]
django_settings_module = "command_center.settings"

[mypy-*.migrations.*]
ignore_errors = True

📝 Type Hints​

Modelos (app/models.py)​

from django.db import models
from django.db.models import QuerySet
from typing import Optional

class Task(models.Model):
title: str = models.CharField(max_length=255)
completed: bool = models.BooleanField(default=False)
created_at: models.DateTimeField = models.DateTimeField(auto_now_add=True)

@classmethod
def get_pending(cls) -> QuerySet['Task']:
return cls.objects.filter(completed=False)

def mark_completed(self) -> None:
self.completed = True
self.save()

Vistas (app/views.py)​

from django.http import HttpRequest, HttpResponse, JsonResponse
from django.shortcuts import render
from django.db.models import QuerySet
from typing import Dict, Any

from .models import Task

def home(request: HttpRequest) -> HttpResponse:
tasks: QuerySet[Task] = Task.get_pending()
return render(request, 'home.html', {'tasks': tasks})

def task_detail(request: HttpRequest, task_id: int) -> HttpResponse:
task: Task = get_object_or_404(Task, pk=task_id)
data: Dict[str, Any] = {
'id': task.pk,
'title': task.title,
'completed': task.completed,
}
return JsonResponse(data)

✅ Checklist Setup​

  • Entorno Pipenv creado
  • Proyecto Django inicializado
  • Tailwind + Alpine en base.html
  • Black configurado
  • Flake8 configurado
  • MyPy con django-stubs
  • Type hints en modelos
  • Type hints en vistas
  • Pre-commit hooks (opcional)

📚 Referencias​