"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Application de gestion des finances personnelles avec Django, HTMX, Alpine, Tailwind et Plaid

Application de gestion des finances personnelles avec Django, HTMX, Alpine, Tailwind et Plaid

Publié le 2024-11-15
Parcourir:263

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

Personal Finance Management App with Django, HTMX, Alpine, Tailwind, and Plaid

Caractéristiques

  • Intégration Plaid pour lier les comptes bancaires, récupérer les données de compte en temps réel et suivre les transactions.
  • Webhooks automatisés pour :
    • Synchronisez et mettez à jour automatiquement les données bancaires chaque fois que de nouvelles transactions sont disponibles.
    • Mettez à jour et réauthentifiez facilement les comptes lorsqu'ils entrent dans un mauvais état (par exemple, connexion requise).
    • Détectez automatiquement les nouveaux comptes bancaires et invitez les utilisateurs à ajouter les comptes nouvellement détectés.
  • Fournit des informations financières telles que la valeur nette, les détails spécifiques au compte et la répartition des dépenses par catégorie.
  • Authentification à deux facteurs (2FA) avec une application d'authentification pour une couche de sécurité supplémentaire.

Gestion des dépendances avec la poésie

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 ?

  • Résolution plus facile des dépendances.
  • Il crée et gère des environnements virtuels, donc si jamais vous oubliez d'en créer/activer un, Poetry est là pour vous.
  • Il verrouille les versions exactes des packages, garantissant ainsi la reproduction de l'environnement. Ceci est très utile, surtout lorsque vous travaillez dans une équipe plus grande.

Ruff et pré-commit

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 :

  • Vous pouvez le configurer à l'aide de pyproject.toml, qui garde les choses propres et centralisées.
  • C'est tout-en-un, donc pas besoin de gérer des outils séparés comme Black, isort, etc.

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.

Structure du projet

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.

Essais

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()

Le front-end

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:

Authentification à deux facteurs avec AllAuth

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.

Personal Finance Management App with Django, HTMX, Alpine, Tailwind, and Plaid Personal Finance Management App with Django, HTMX, Alpine, Tailwind, and Plaid

Conclusion

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 ! ?

Déclaration de sortie Cet article est reproduit sur : https://dev.to/earthcomfy/personal-finance-management-app-with-django-htmx-alpine-tailwind-and-plaid-2bl0?1 En cas d'infraction, veuillez contacter study_golang @163.com supprimer
Dernier tutoriel Plus>

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