Cómo Organizar tus Vistas en Django: Separa un views.py Gigante en Archivos Limpios Modulares
Índice de contenido
- Por qué dividir el archivo views.py
- Beneficios de modularizar: legibilidad, escalabilidad y mantenimiento
- En proyectos grandes, modularizar se traduce en tranquilidad.
- Uso del archivo __init__.py para importar las vistas
- Ejemplo práctico paso a paso
- Cómo mantener urls.py sin cambios
- Precauciones y buenas prácticas antes de refactorizar
- Consejos basados en experiencia real
- Preguntas frecuentes
- Conclusión
Si trabajas con proyectos medianos o grandes, habrás notado que llega un punto donde el archivo views.py se convierte en un monstruo difícil de mantener. En mi caso, llegamos a tener más de 13 clases de vistas en un solo archivo, y créeme, mantener eso era un dolor.
Por qué dividir el archivo views.py
El problema de tener demasiadas vistas en un solo archivo
Cuando creamos una tienda online o cualquier app con varias secciones (productos, pagos, usuarios, etc.), es común agrupar todo en views.py. Pero llega un momento en que el archivo supera las 500 líneas y mantenerlo se vuelve caótico.
En mi caso, cada vez que quería modificar una vista de pago tenía que desplazarme entre vistas de productos o listados. Además, los conflictos de importaciones y duplicación de lógica eran frecuentes. No era práctico.
Beneficios de modularizar: legibilidad, escalabilidad y mantenimiento
Separar las vistas en distintos archivos no cambia el rendimiento, pero mejora radicalmente la legibilidad.
También facilita el trabajo en equipo, permite pruebas unitarias más limpias y ayuda a escalar sin miedo a romper algo.
En proyectos grandes, modularizar se traduce en tranquilidad.
Estructura recomendada para separar las vistas
Cómo crear la carpeta views como paquete Python
La idea es simple: convertir views.py en un paquete (una carpeta con su propio __init__.py), dentro del cual creamos varios archivos separados por tipo o entidad.
Ejemplo de estructura de carpetas en un proyecto Django
store/
│
├── views/
│ ├── __init__.py
│ ├── book_views.py
│ ├── product_views.py
│ ├── payment_views.py
│
├── models.py
├── urls.py
└── ...
En mi caso, tenía un módulo store con vistas de libros, productos y pagos. Así lo dividí:
- book_views.py: vistas de detalle y listado de libros
- product_views.py: vistas de productos
- payment_views.py: vistas relacionadas con pasarelas de pago (Stripe, etc.)
Uso del archivo __init__.py para importar las vistas
El archivo __init__.py funciona como punto de entrada del módulo.
En lugar de apuntar a views.py desde urls.py, simplemente apuntamos a views, y Django lo resolverá automáticamente.
# store/views/__init__.py
from .book_views import *
from .product_views import *
from .payment_views import *
En resumen, estos módulos permiten:
- Vistas actuales de la tienda
- En este caso, tenemos una vista adaptada a la parte de la tienda. Aquí podemos ver:
- Detalles y listados.
- Pasarelas de pago, como la creación de la sesión en Stripe.
- Vistas de pago: éxito, cancelación, error y las que sean necesarias.
- Listado de pagos de usuario.
Todo esto lo implementamos con vistas basadas en clases, lo recomendado en la mayoría de los casos, pero el problema es que son demasiadas vistas en un archivo.
Actualmente, tenemos alrededor de 13 clases en un solo archivo. Esto dificulta la reutilización y complica la organización. Si quisiéramos crear más vistas, sería poco práctico mantener todo en un único archivo.
Lo que queremos mostrar es cómo hacer el sistema completamente reutilizable, aplicando buenas prácticas:
- Modularizar y separar las vistas en archivos diferentes.
- Seguir un esquema similar al de otras tecnologías.
- Evitar que un solo archivo concentre todo.
En Python no es común definir una clase por archivo (como en PHP), sino concentrar varias en un mismo archivo. Aquí hacemos un híbrido, clasificando las vistas según la entidad: libro, producto o pago.
Ejemplo práctico paso a paso
Creamos una carpeta llamada views que contendrá varios archivos, uno por categoría. También añadimos un archivo __init__.py que actuará como punto de entrada del módulo:
store/
|- views/
| |- __init__.py
| |- book_views.py
| |- payment_views.py
| |- product_views.py
|- models.py
|- urls.py
|- ...
En urls.py, no hay que cambiar nada, ya que en lugar de apuntar a views.py, apuntaremos al módulo views y Django sabrá resolverlo.
Ahora, movemos a cada una de ellas las clases y sus importaciones; para mantener esta demostración sencilla, solamente copiaremos la firma de la clase:
store\views\payment_views.py
class UserPaymentsView(LoginRequiredMixin, ListView):
***
class PaymentBookView(LoginRequiredMixin, View, BasePayment):
***
class PaymentProductView(LoginRequiredMixin, View, BasePayment):
***
class StripeView(LoginRequiredMixin, View, BasePayment):
***
class PaymentSuccessView(LoginRequiredMixin, View):
***
class PaymentCancelView(LoginRequiredMixin, View):
***
class PaymentErrorView(LoginRequiredMixin, View):
***
store\views\book_views.py
class BookIndex(ListView):
***
class BookShow(DetailView):
***
store\views\product_views.py
class ProductIndexAbstract(ListView, ABC):
***
class ProductIndex(ProductIndexAbstract):
***
class ProductIndexByType(ProductIndexAbstract):
***
class ProductShow(DetailView):
***
Siempre recomiendo duplicar el archivo original antes de refactorizar, para tener una referencia en caso de errores. En entornos empresariales esto es clave para no perder implementaciones que ya funcionaban.
Cómo mantener urls.py sin cambios
La buena noticia: no hay que tocar nada en urls.py.
Tras la refactorización, TODO debe se seguir funcionando exactamente igual, no hace falta de hacer ningún cambio en el archivo de urls.py y con esto, nuestras vistas quedan mas reutilizables; puedes usar el mismo truco para otras clases como la de models.py si lo vez necesario; es importante aclarar que esto es solamente para mejorar la lectura del código pero no ofrece ninguna mejora de rendimiento en la aplicación. Finalmente, puedes variar la implementación colocando mas o menos archivos de vistas según consideres.
Django seguirá interpretando las rutas igual, ya que lo importante es que el módulo views exporte las clases adecuadas.
Precauciones y buenas prácticas antes de refactorizar
Un consejo que siempre doy: duplica el archivo original antes de mover nada.
En entornos empresariales esto evita perder implementaciones funcionales.
Y recuerda, separar vistas mejora la legibilidad, no el rendimiento.
Consejos basados en experiencia real
Cómo lo aplico en proyectos de tiendas online
En mi tienda, con vistas basadas en clases (CBV), separar los archivos me permitió reutilizar clases de pago y mantener un flujo claro entre StripeView, PaymentBookView y PaymentProductView.
Errores comunes al dividir vistas
- Olvidar el __init__.py en la carpeta views.
- Mover vistas sin actualizar los imports.
- Duplicar imports o clases similares en varios archivos.
Recomendaciones antes y después de refactorizar
- Usa nombres consistentes en los archivos (por ejemplo, payment_views, no payment a secas).
- Ejecuta los tests después de mover cada grupo de vistas.
- Si usas CBV, agrúpalas por entidad, no por acción (producto, libro, pago…).
- Documenta la nueva estructura en tu README.
Preguntas frecuentes
- ¿Afecta el rendimiento dividir las vistas?
No. Solo mejora la organización y legibilidad del código. - ¿Puedo aplicar lo mismo en proyectos pequeños?
Sí, aunque no siempre es necesario. Pero hacerlo desde el inicio facilita el crecimiento del proyecto. - ¿Cómo mantener ordenadas las importaciones?
Agrupa importaciones por tipo (Django, app propia, librerías externas) y usa herramientas como isort.
Conclusión
Este esquema de modularización hace el proyecto más organizado, escalable y mantenible. Aunque es opcional, recomiendo hacerlo como buena práctica, especialmente en proyectos grandes.
Dividir views.py en varios archivos no solo hace tu proyecto más limpio, sino que lo vuelve más profesional.
En mi experiencia, aplicar esta modularización en proyectos reales de e-commerce con Django marcó un antes y un después en la mantenibilidad del código.
Recuerda: no buscas optimizar rendimiento, sino claridad y escalabilidad.
Si lo aplicas, verás cómo el código respira, y tú también.
Acepto recibir anuncios de interes sobre este Blog.
Django Tips: Divide tu views.py en Múltiples Archivos y Gana Orden en tu Proyecto