J'avais hâte de me plonger dans HTMX, surtout après avoir regardé la conférence de la DjangoCon Europe 2022 De React à HTMX sur un projet SaaS du monde réel. J'utilise HTMX et Alpine dans mon travail quotidien ces derniers temps, et ensemble, ils ont rendu le développement d'applications Web interactives beaucoup plus agréable, surtout en tant que personne qui n'aime pas particulièrement le développement front-end.
Je ne suis pas un grand fan des modèles Django, mais HTMX, Alpine.js et Django Cotton ont commencé à changer ma perspective. Et avec Tailwind CSS en plus, c'est devenu l'une des meilleures piles avec lesquelles j'ai travaillé jusqu'à présent.
Ce projet est une application de gestion des finances personnelles qui intègre Plaid pour relier les comptes bancaires et fournir des informations financières. J'ai utilisé les exemples officiels de Plaid de leur référentiel comme référence.
Vous voulez un aperçu rapide du code ? Découvrez-le sur GitHub
Pour gérer les dépendances dans ce projet, j'ai utilisé Poetry. Poetry simplifie le processus de gestion des packages et automatise une grande partie du gros travail lié aux dépendances. Il s'appuie sur le fichier pyproject.toml, qui est désormais la norme pour définir les exigences de build dans les projets Python modernes.
Pourquoi la poésie ?
J'utilise Ruff, qui est un formateur de linter et de code Python très rapide, construit dans Rust. Il gère de nombreux outils tout-en-un, comme Black, isort, etc.
Ce que j'aime chez Ruff :
J'ai également utilisé djlint pour pelucher les modèles Django. C'est correct, mais je suis toujours à la recherche de quelque chose de mieux. Si vous connaissez de bonnes alternatives, n'hésitez pas à les partager !
Pour en savoir plus sur la configuration des hooks de pré-commit pour le formatage du code et le peluchage dans Django, consultez mon article ici.
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
Dans l'application commune, j'ajoute des commandes de gestion, de validation, des modèles de base, des balises de modèle, etc. Le BaseModel ressemble à ceci :
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()
J'ai également créé une commande startapp personnalisée pour générer des applications Django avec des fichiers prédéfinis et du contenu adaptés à mon cas d'utilisation.
Pour écrire des tests, j'utilise pytest avec factory_boy, ce qui facilite la déclaration de champs spécifiques aux tests et la création de données de test.
Au départ, j'avais l'habitude de placer un dossier de tests dans chaque application Django. Cependant, depuis, je suis passé à un seul dossier de tests à la racine du projet, avec des sous-dossiers pour chaque application. Cette approche a rendu la navigation beaucoup plus fluide et maintient tout organisé. De plus, cela facilite grandement le partage des appareils communs puisqu'ils peuvent être définis à un niveau supérieur et réutilisés dans plusieurs modules de test.
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
Un exemple de test :
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()
Ce projet combine les outils frontend suivants :
HTMX vous permet d'ajouter des interactions dynamiques à votre projet sans avoir besoin de frameworks JavaScript lourds. Vous pouvez organiser vos modèles Django avec de petits extraits HTMX réutilisables. Cela vous permet de mettre à jour des parties spécifiques de la page en fonction des actions de l'utilisateur, sans nécessiter un rechargement complet de la page. Ce modèle fonctionne très bien avec les vues de Django car chaque élément de contenu peut être traité comme sa propre vue puis injecté dynamiquement dans le DOM.
Alpine.js est un autre framework JavaScript léger utilisé pour ajouter de l'interactivité. Il fonctionne bien avec la structure des modèles de Django et fournit un comportement déclaratif rapide pour des éléments tels que les modaux, les listes déroulantes ou les bascules. En combinaison avec HTMX, Alpine peut vous fournir juste assez de JavaScript pour améliorer l'UX sans avoir à gérer quelque chose comme React ou Vue. Par exemple, vous pouvez utiliser Alpine pour gérer l'état dans le frontend, comme l'ouverture et la fermeture des modaux ou la gestion de la validation côté client.
Tailwind CSS gère le style de ce projet, ce qui accélère le développement d'interfaces utilisateur propres et réactives. Ce projet utilise également Flowbite pour les composants d'interface utilisateur prédéfinis tels que les modaux, les info-bulles et les boutons. Flowbite s'intègre bien à Tailwind et vous aide à éviter de réinventer la roue pour les éléments d'interface utilisateur courants.
Django Cotton vous permet de créer des modèles Django réutilisables. J'ai découvert cette superbe bibliothèque à mi-chemin du projet en essayant de rendre un modal réutilisable. Au départ, j'ai essayé d'utiliser la balise include template de Django, mais lors du passage de nombreuses données contextuelles, elle est rapidement devenue encombrée. Django-Cotton vous permet de créer des composants hautement réutilisables qui se lient bien à votre HTMX et Tailwind dans une syntaxe de type balise HTML. Par exemple:
Pour implémenter l'authentification dans ce projet, j'ai utilisé la bibliothèque AllAuth, qui prend également en charge l'authentification multifacteur (MFA). Il propose un module MFA qui s'intègre parfaitement à votre configuration d'authentification utilisateur existante. Vous pouvez activer 2FA via une application d'authentification, ajoutant ainsi une couche de sécurité supplémentaire. Vous pouvez également facilement personnaliser les modèles fournis par AllAuth pour qu'ils correspondent à l'apparence de votre application.
Dans l'ensemble, ce projet est avant tout éducatif et possède juste assez de fonctionnalités pour vous permettre de démarrer l'intégration de Django, HTMX, Alpine.js, Tailwind et Plaid.
Cela étant dit, attention, il peut y avoir quelques bugs ici et là, et il est toujours possible d'améliorer et de réutiliser davantage les composants. Mais dans l’ensemble, il s’agit d’une base solide pour quiconque souhaite explorer ces technologies.
Découvrez le projet sur GitHub
Si vous souhaitez que j'explore les sujets mentionnés ici plus en détail, faites-le-moi savoir dans les commentaires.
Bon codage ! ?
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3