«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Приложение для управления личными финансами с Django, HTMX, Alpine, Tailwind и Plaid

Приложение для управления личными финансами с Django, HTMX, Alpine, Tailwind и Plaid

Опубликовано 15 ноября 2024 г.
Просматривать:571

Мне очень хотелось погрузиться в HTMX, особенно после просмотра доклада на DjangoCon Europe 2022 От React до HTMX в реальном SaaS-проекте. В последнее время я использую HTMX и Alpine в своей повседневной работе, и вместе они сделали разработку интерактивных веб-приложений намного более увлекательной, особенно для человека, который не особо любит фронтенд-разработку.

Я не большой поклонник шаблонов Django, но HTMX, Alpine.js и Django Cotton начали менять мою точку зрения. А благодаря Tailwind CSS он стал одним из лучших стеков, с которыми я когда-либо работал.

Этот проект представляет собой приложение для управления личными финансами, которое интегрирует Plaid для связи банковских счетов и предоставления финансовой информации. В качестве справочного материала я использовал официальные примеры Plaid из их репозитория.

Хотите получить краткий обзор кода? Проверьте это на GitHub

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

Функции

  • Интеграция Plaid для связывания банковских счетов, получения данных об счетах в реальном времени и отслеживания транзакций.
  • Автоматические вебхуки для:
    • Автоматическая синхронизация и обновление банковских данных при появлении новых транзакций.
    • Легко обновляйте и повторно аутентифицируйте учетные записи, когда они переходят в неправильное состояние (например, требуется вход в систему).
    • Автоматически обнаруживать новые банковские счета и предлагать пользователям добавлять вновь обнаруженные счета.
  • Предоставляет финансовую информацию, такую ​​как собственный капитал, подробную информацию по аккаунтам и разбивку расходов по категориям.
  • Двухфакторная аутентификация (2FA) с приложением-аутентификатором для дополнительного уровня безопасности.

Управление зависимостями с помощью поэзии

Для управления зависимостями в этом проекте я использовал Poetry. Poetry упрощает процесс управления пакетами и автоматизирует большую часть тяжелой работы, связанной с зависимостями. Он основан на файле pyproject.toml, который теперь является стандартом для определения требований сборки в современных проектах Python.

Почему поэзия?

  • Упрощенное разрешение зависимостей.
  • Он создает виртуальные среды и управляет ими, поэтому, если вы когда-нибудь забудете создать/активировать ее, Poetry поддержит вас.
  • Он фиксирует точные версии пакетов, обеспечивая воспроизводимость среды. Это очень полезно, особенно при работе в большой команде.

Ерш и предварительная фиксация

Я использую Ruff — очень быстрый линтер и форматировщик кода Python, встроенный в Rust. Он поддерживает множество инструментов в одном, таких как Black, isort и другие.

Что мне нравится в Раффе:

  • Вы можете настроить его с помощью pyproject.toml, который обеспечивает чистоту и централизацию.
  • Это все-в-одном, поэтому нет необходимости управлять отдельными инструментами, такими как Black, isort и т. д.

Я также использовал djlint для проверки шаблонов Django. Это неплохо, но я все еще ищу что-то получше. Если вы знаете какие-либо хорошие альтернативы, поделитесь ими!

Подробнее о настройке перехватчиков Pre-commit для форматирования кода и проверки в Django можно прочитать в моей статье здесь.

Структура проекта

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

В обычном приложении я добавляю команды управления, проверки, базовые модели, теги шаблонов и т. д. Базовая модель выглядит следующим образом:

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

Я также создал специальную команду startapp для создания приложений Django с предопределенными файлами и содержимым, подходящим для моего варианта использования.

Тесты

Для написания тестов я использую pytest вместе с Factory_boy, что позволяет легко объявлять поля, специфичные для теста, и создавать тестовые данные.

Изначально я помещал папку с тестами в каждое приложение Django. Однако с тех пор я переключился на одну папку тестов в корне проекта с подпапками для каждого приложения. Такой подход сделал навигацию намного более плавной и все организовало. Кроме того, это значительно упрощает совместное использование общих приборов, поскольку их можно определить на более высоком уровне и повторно использовать в нескольких тестовых модулях.

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

Пример теста:

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

Интерфейс

Этот проект сочетает в себе следующие инструменты внешнего интерфейса:

HTMX позволяет добавлять в проект динамические взаимодействия без использования тяжелых фреймворков JavaScript. Вы можете организовать свои шаблоны Django с помощью небольших многократно используемых фрагментов HTMX. Это позволяет обновлять отдельные части страницы в зависимости от действий пользователя, не требуя полной перезагрузки страницы. Этот шаблон отлично работает с представлениями Django, поскольку каждый фрагмент контента можно рассматривать как отдельное представление, а затем динамически внедрять в DOM.

Alpine.js — еще одна легкая среда JavaScript, используемая для добавления интерактивности. Он прекрасно сочетается со структурой шаблонов Django и обеспечивает быстрое декларативное поведение для таких вещей, как модальные окна, раскрывающиеся списки или переключатели. В сочетании с HTMX Alpine может предоставить вам ровно столько JavaScript, чтобы улучшить UX без необходимости иметь дело с чем-то вроде React или Vue. Например, вы можете использовать Alpine для управления состоянием во внешнем интерфейсе, например открытия и закрытия модальных окон или обработки проверки на стороне клиента.

Tailwind CSS отвечает за стиль в этом проекте, что ускоряет разработку чистых и отзывчивых пользовательских интерфейсов. В этом проекте также используется Flowbite для готовых компонентов пользовательского интерфейса, таких как модальные окна, всплывающие подсказки и кнопки. Flowbite хорошо интегрируется с Tailwind и помогает вам не изобретать велосипед для общих элементов пользовательского интерфейса.

Django Cotton позволяет создавать многократно используемые шаблоны Django. Я обнаружил эту потрясающую библиотеку в середине проекта, пытаясь сделать модальное окно многоразового использования. Сначала я пробовал использовать тег шаблона include Django, но при передаче большого количества контекстных данных он быстро становился загроможденным. Django-Cotton позволяет создавать компоненты с возможностью многократного использования, которые хорошо связываются с вашими HTMX и Tailwind с помощью синтаксиса, подобного HTML-тегам. Например:

Двухфакторная аутентификация с AllAuth

Для реализации аутентификации в этом проекте я использовал библиотеку AllAuth, которая также обеспечивает поддержку многофакторной аутентификации (MFA). Он предлагает модуль MFA, который легко интегрируется с существующей настройкой аутентификации пользователя. Вы можете включить 2FA через приложение для аутентификации, добавив дополнительный уровень безопасности. Вы также можете легко настроить шаблоны, предоставляемые AllAuth, в соответствии с внешним видом вашего приложения.

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

Заключение

В целом, этот проект в первую очередь носит образовательный характер и имеет достаточно функций, чтобы вы могли начать работу с интеграцией Django, HTMX, Alpine.js, Tailwind и Plaid.

При этом помните, что здесь и там могут быть некоторые ошибки, и всегда есть возможности для улучшения и дальнейшего повторного использования компонентов. Но в целом это прочная основа для всех, кто хочет изучить эти технологии.

Ознакомьтесь с проектом на GitHub

Если вы хотите, чтобы я более подробно рассмотрел упомянутые здесь темы, дайте мне знать в комментариях.

Удачного программирования! ?

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/earthcomfy/personal-finance-management-app-with-django-htmx-alpine-tailwind-and-plaid-2bl0?1 Если есть какие-либо нарушения, свяжитесь с Study_golang. @163.com удалить
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3