Tenía muchas ganas de sumergirme en HTMX, especialmente después de ver la charla de DjangoCon Europe 2022 De React a HTMX en un proyecto SaaS del mundo real. He estado usando HTMX y Alpine en mi trabajo diario últimamente y juntos han hecho que el desarrollo de aplicaciones web interactivas sea mucho más divertido, especialmente para alguien a quien no le gusta mucho el desarrollo front-end.
No he sido un gran admirador de las plantillas de Django, pero HTMX, Alpine.js y Django Cotton han comenzado a cambiar mi perspectiva. Y con Tailwind CSS encima, se ha convertido en una de las mejores pilas con las que he trabajado hasta ahora.
Este proyecto es una aplicación de gestión de finanzas personales que integra Plaid para vincular cuentas bancarias y proporcionar información financiera. Utilicé los ejemplos oficiales de Plaid de su repositorio como referencia.
¿Quieres una descripción general rápida del código? Compruébalo en GitHub
Para gestionar las dependencias en este proyecto, utilicé Poetry. Poetry simplifica el proceso de gestión de paquetes y automatiza gran parte del trabajo pesado relacionado con las dependencias. Se basa en el archivo pyproject.toml, que ahora es el estándar para definir los requisitos de compilación en proyectos Python modernos.
¿Por qué poesía?
He estado usando Ruff, que es un formateador de código y linter de Python muy rápido, integrado en Rust. Maneja un montón de herramientas todo en uno, como Black, isort y más.
Lo que me gusta de Ruff:
También usé djlint para crear plantillas de Django. Es decente, pero todavía estoy buscando algo mejor. Si conoces alguna buena alternativa, ¡no dudes en compartirla!
Para obtener más información sobre cómo configurar ganchos de confirmación previa para formatear código y linting en Django, consulta mi artículo aquí.
django_finance/ ├── apps/ │ ├── accounts/ │ ├── common/ │ └── plaid/ ├── config/ │ ├── app_template/ │ ├── settings/ │ ├── asgi.py │ ├── celery.py │ ├── urls.py │ └── wsgi.py ├── static/ │ ├── css/ │ ├── images/ │ └── js/ ├── templates/ │ ├── account/ │ ├── components/ │ ├── errors/ │ ├── layouts/ │ ├── mfa/ │ ├── plaid/ │ ├── _base_dashboard.html │ ├── _base.html │ └── index.html ├── tests/ │ ├── accounts/ │ ├── common/ │ ├── plaid/ │ └── conftest.py ├── theme/ ├── .pre-commit-config.yaml ├── db.sqlite3 ├── manage.py ├── poetry.lock ├── pyproject.toml └── README.md
En la aplicación común, agrego comandos de administración, validación, modelos base, etiquetas de plantilla, etc. El modelo base se ve así:
class BaseModel(models.Model): """ Base model for common fields and methods. """ id = models.AutoField(primary_key=True) uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) is_active = models.BooleanField(default=True, db_index=True, help_text="Used for soft deleting records.") objects = BaseModelManager() class Meta: abstract = True def soft_delete(self): self.is_active = False self.save() def restore(self): self.is_active = True self.save()
También he creado un comando de inicio de aplicación personalizado para generar aplicaciones Django con archivos predefinidos y contenido adecuado para mi caso de uso.
Para escribir pruebas, uso pytest junto con factory_boy, lo que facilita la declaración de campos específicos de la prueba y la creación de datos de prueba.
Al principio, solía colocar una carpeta de pruebas dentro de cada aplicación Django. Sin embargo, desde entonces cambié a tener una única carpeta de pruebas en la raíz del proyecto, con subcarpetas para cada aplicación. Este enfoque ha hecho que la navegación sea mucho más fluida y mantiene todo organizado. Además, hace que compartir dispositivos comunes sea mucho más fácil, ya que pueden definirse en un nivel superior y reutilizarse en múltiples módulos de prueba.
tests/ ├── accounts/ │ ├── __init__.py │ ├── factories.py │ ├── test_managers.py │ ├── test_models.py ├── common/ │ ├── __init__.py │ ├── test_validators.py ├── plaid/ │ ├── conftest.py │ ├── dummy_data.py │ ├── factories.py │ ├── test_models.py │ ├── test_services.py │ ├── test_tasks.py │ ├── test_views.py │ ├── test_webhooks.py ├── __init__.py/ └── conftest.py
Una prueba de muestra:
class TestCreatePlaidLinkToken: LINK_TOKEN = "link_token" class MockLinkTokenResponse: def to_dict(self): return { "link_token": TestCreatePlaidLinkToken.LINK_TOKEN, "expiration": "2020-03-27T12:56:34Z", "request_id": "request_id", } @pytest.fixture def setup_mocks(self, mocker): return { "mock_link_token": mocker.patch( "django_finance.apps.plaid.views.plaid_config.client.link_token_create", return_value=self.MockLinkTokenResponse(), ), "mock_logger": mocker.patch("django_finance.apps.plaid.views.logger"), } @pytest.fixture def create_link_token(self, client): def _create_link_token(data=None): return client.post( reverse("create_link_token"), json.dumps(data) if data else None, content_type="application/json", ) return _create_link_token def test_create_plaid_link_token_success(self, login, setup_mocks, create_link_token): login() response = create_link_token() assert response.status_code == 201 data = json.loads(response.content) assert "link_token" in data assert data["link_token"] == self.LINK_TOKEN setup_mocks["mock_link_token"].assert_called_once()
Este proyecto combina las siguientes herramientas frontend:
HTMX le permite agregar interacciones dinámicas a su proyecto sin necesidad de marcos de JavaScript pesados. Puedes organizar tus plantillas de Django con pequeños fragmentos HTMX reutilizables. Esto le permite actualizar partes específicas de la página según las acciones del usuario, sin necesidad de recargar la página completa. Este patrón funciona muy bien con las vistas de Django porque cada contenido puede tratarse como su propia vista y luego inyectarse dinámicamente en el DOM.
Alpine.js es otro marco de JavaScript liviano que se utiliza para agregar interactividad. Funciona muy bien con la estructura de plantillas de Django y proporciona un comportamiento declarativo rápido para cosas como modales, menús desplegables o alternancias. En combinación con HTMX, Alpine puede brindarle suficiente JavaScript para mejorar la UX sin tener que lidiar con algo como React o Vue. Por ejemplo, puede usar Alpine para administrar el estado en la interfaz, como abrir y cerrar modales o manejar la validación del lado del cliente.
Tailwind CSS maneja el estilo en este proyecto, lo que acelera el desarrollo de UI limpias y responsivas. Este proyecto también utiliza Flowbite para componentes de interfaz de usuario prediseñados como modales, información sobre herramientas y botones. Flowbite se integra bien con Tailwind y te ayuda a evitar reinventar la rueda para elementos comunes de la interfaz de usuario.
Django Cotton te permite crear plantillas Django reutilizables. Descubrí esta increíble biblioteca a mitad del proyecto mientras intentaba hacer un modal reutilizable. Inicialmente, intenté usar la etiqueta de plantilla de inclusión de Django, pero al pasar muchos datos de contexto, rápidamente se volvió abarrotada. Django-Cotton le permite crear componentes altamente reutilizables que se vinculan bien con su HTMX y Tailwind en una sintaxis similar a una etiqueta HTML. Por ejemplo:
Para implementar la autenticación en este proyecto, utilicé la biblioteca AllAuth, que también brinda soporte para la autenticación multifactor (MFA). Ofrece un módulo MFA que se integra perfectamente con su configuración de autenticación de usuario existente. Puede habilitar 2FA a través de una aplicación de autenticación, agregando una capa adicional de seguridad. También puedes personalizar fácilmente las plantillas que proporciona AllAuth para que coincidan con la apariencia de tu aplicación.
En general, este proyecto es principalmente educativo y tiene características suficientes para comenzar a integrar Django, HTMX, Alpine.js, Tailwind y Plaid.
Dicho esto, tenga en cuenta que puede haber algunos errores aquí y allá, y siempre hay margen de mejora y reutilización adicional de los componentes. Pero, en general, es una base sólida para cualquiera que desee explorar estas tecnologías.
Ver el proyecto en GitHub
Si quieres que explore los temas mencionados aquí con más detalle, házmelo saber en los comentarios.
¡Feliz codificación! ?
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3