Saltar a contenido

Estándares de Código

Convenciones y mejores prácticas para el código del Sistema A3.

Python

Formateador: Black

black --line-length 90 .

Configuración (pyproject.toml):

[tool.black]
line-length = 90
target-version = ['py311']

Imports: isort

isort .

Orden de imports: 1. Standard library 2. Third-party packages 3. Local imports

# Correcto
import os
from datetime import datetime

from django.db import models
from rest_framework import serializers

from inventario.models import Casa

Naming Conventions

Variables y funciones: snake_case

mi_variable = "valor"
def calcular_precio():
    pass

Clases: PascalCase

class MiClase:
    pass

Constantes: UPPER_SNAKE_CASE

MAX_INTENTOS = 3
BASE_URL = "https://api.example.com"

Docstrings

def crear_apartado(casa, cliente, tipo_venta):
    """
    Crea un nuevo apartado de venta.

    Args:
        casa (Casa): Propiedad a apartar
        cliente (Cliente): Cliente comprador
        tipo_venta (str): CREDITO, CONTADO, etc.

    Returns:
        Apartado: El apartado creado

    Raises:
        ValueError: Si la casa no está disponible
    """
    pass

JavaScript

Estilo

// Variables con const/let (no var)
const BASE_URL = '/api/';
let contador = 0;

// Funciones descriptivas
function abrirVentana(titulo, contenido) {
    // ...
}

// Comentarios claros
// Abre una nueva ventana en el gestor SPA
function mostrarDetalle(id) {
    // ...
}

jQuery

// Usar $ para variables jQuery
const $ventana = $('.ventana');

// Event handlers con arrow functions
$('.boton').on('click', () => {
    // ...
});

CSS

Naming: BEM-like

/* Bloque */
.card {}

/* Elemento */
.card__title {}
.card__body {}

/* Modificador */
.card--destacado {}

Orden de Propiedades

  1. Layout (display, position)
  2. Box model (width, height, padding, margin)
  3. Tipografía
  4. Visual
  5. Otros
.elemento {
    /* Layout */
    display: flex;
    position: relative;

    /* Box model */
    width: 100%;
    padding: 10px;
    margin-bottom: 20px;

    /* Tipografía */
    font-size: 16px;
    color: #333;

    /* Visual */
    background: #fff;
    border: 1px solid #ccc;
}

Django

Views

# Function-based views
@login_required
def mi_vista(request):
    context = {...}
    return render(request, 'template.html', context)

# Class-based views
class MiVista(LoginRequiredMixin, ListView):
    model = MiModelo
    template_name = 'template.html'

Models

class MiModelo(models.Model):
    # Campos en orden lógico
    # 1. Identificación
    nombre = models.CharField(max_length=100)

    # 2. Relaciones
    usuario = models.ForeignKey(User, on_delete=models.PROTECT)

    # 3. Datos
    descripcion = models.TextField()

    # 4. Metadatos
    activo = models.BooleanField(default=True)
    fecha_creacion = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-fecha_creacion']

    def __str__(self):
        return self.nombre

Seguridad

  • Nunca commitear .env o secrets
  • Validar inputs del usuario
  • Sanitizar queries SQL
  • Usar Django ORM (no SQL crudo)
  • CSRF tokens en forms
  • Permisos en views

Performance

  • Select related: Para ForeignKey
  • Prefetch related: Para ManyToMany
  • Caché: Para queries frecuentes
  • Índices: En campos de búsqueda
# Bueno
casas = Casa.objects.select_related('usuario_creacion').all()

# Malo
casas = Casa.objects.all()
for casa in casas:
    print(casa.usuario_creacion.username)  # N+1 queries

Herramientas

# Formatear código
black .
isort .

# Verificar estilo
flake8

# Tests
pytest

# Type checking (opcional)
mypy .

Ver también: Guía para Agentes IA