Мне очень хотелось погрузиться в HTMX, особенно после просмотра доклада на DjangoCon Europe 2022 От React до HTMX в реальном SaaS-проекте. В последнее время я использую HTMX и Alpine в своей повседневной работе, и вместе они сделали разработку интерактивных веб-приложений намного более увлекательной, особенно для человека, который не особо любит фронтенд-разработку.
Я не большой поклонник шаблонов Django, но HTMX, Alpine.js и Django Cotton начали менять мою точку зрения. А благодаря Tailwind CSS он стал одним из лучших стеков, с которыми я когда-либо работал.
Этот проект представляет собой приложение для управления личными финансами, которое интегрирует Plaid для связи банковских счетов и предоставления финансовой информации. В качестве справочного материала я использовал официальные примеры Plaid из их репозитория.
Хотите получить краткий обзор кода? Проверьте это на GitHub
Для управления зависимостями в этом проекте я использовал Poetry. Poetry упрощает процесс управления пакетами и автоматизирует большую часть тяжелой работы, связанной с зависимостями. Он основан на файле pyproject.toml, который теперь является стандартом для определения требований сборки в современных проектах Python.
Почему поэзия?
Я использую Ruff — очень быстрый линтер и форматировщик кода Python, встроенный в Rust. Он поддерживает множество инструментов в одном, таких как 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, которая также обеспечивает поддержку многофакторной аутентификации (MFA). Он предлагает модуль MFA, который легко интегрируется с существующей настройкой аутентификации пользователя. Вы можете включить 2FA через приложение для аутентификации, добавив дополнительный уровень безопасности. Вы также можете легко настроить шаблоны, предоставляемые AllAuth, в соответствии с внешним видом вашего приложения.
В целом, этот проект в первую очередь носит образовательный характер и имеет достаточно функций, чтобы вы могли начать работу с интеграцией Django, HTMX, Alpine.js, Tailwind и Plaid.
При этом помните, что здесь и там могут быть некоторые ошибки, и всегда есть возможности для улучшения и дальнейшего повторного использования компонентов. Но в целом это прочная основа для всех, кто хочет изучить эти технологии.
Ознакомьтесь с проектом на GitHub
Если вы хотите, чтобы я более подробно рассмотрел упомянутые здесь темы, дайте мне знать в комментариях.
Удачного программирования! ?
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3