특히 DjangoCon Europe 2022 강연을 시청한 후 HTMX에 대해 관심이 생겼습니다. React에서 실제 SaaS 프로젝트의 HTMX까지. 저는 최근 일상 업무에서 HTMX와 Alpine을 사용해 왔으며, 특히 프런트엔드 개발을 별로 좋아하지 않는 사람으로서 대화형 웹 앱 개발을 훨씬 더 즐겁게 만들었습니다.
저는 Django 템플릿을 별로 좋아하지 않았지만 HTMX, Alpine.js 및 Django Cotton이 제 관점을 바꾸기 시작했습니다. 그리고 Tailwind CSS를 맨 위에 올려서 지금까지 작업한 최고의 스택 중 하나가 되었습니다.
이 프로젝트는 Plaid를 통합하여 은행 계좌를 연결하고 금융 통찰력을 제공하는 개인 금융 관리 앱입니다. 참고 자료로 Plaid의 저장소에 있는 공식 예제를 사용했습니다.
코드에 대한 간략한 개요를 원하시나요? GitHub에서 확인해보세요
이 프로젝트에서는 종속성을 관리하기 위해 Poetry를 사용했습니다. Poetry는 패키지 관리 프로세스를 단순화하고 종속성과 관련된 많은 무거운 작업을 자동화합니다. 이는 현재 최신 Python 프로젝트의 빌드 요구 사항을 정의하기 위한 표준인 pyproject.toml 파일을 사용합니다.
왜 시인가?
저는 Rust로 구축된 매우 빠른 Python 린터이자 코드 포맷터인 Ruff를 사용해 왔습니다. Black, isort 등과 같은 여러 도구를 하나로 처리합니다.
내가 Ruff의 장점:
저는 또한 Django 템플릿을 Linting하기 위해 djlint를 사용했습니다. 괜찮은 편이지만 여전히 더 나은 것을 찾고 있습니다. 좋은 대안을 알고 계시다면 자유롭게 공유해 주세요!
Django에서 코드 형식 지정 및 Linting을 위한 사전 커밋 후크 설정에 대한 자세한 내용은 여기에서 내 기사를 확인하세요.
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
공용 앱에 관리 명령, 유효성 검사, 기본 모델, 템플릿 태그 등을 추가합니다. BaseModel은 다음과 같습니다.
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()
또한 내 사용 사례에 적합한 사전 정의된 파일과 콘텐츠로 Django 앱을 생성하기 위해 사용자 정의 startapp 명령을 만들었습니다.
테스트 작성을 위해 Factory_boy와 함께 pytest를 사용하는데, 이를 통해 테스트 관련 필드를 쉽게 선언하고 테스트 데이터를 생성할 수 있습니다.
처음에는 각 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 프레임워크 없이도 프로젝트에 동적 상호 작용을 추가할 수 있습니다. 작고 재사용 가능한 HTMX 스니펫을 사용하여 Django 템플릿을 구성할 수 있습니다. 이를 통해 전체 페이지를 다시 로드하지 않고도 사용자 작업에 따라 페이지의 특정 부분을 업데이트할 수 있습니다. 이 패턴은 각 콘텐츠가 자체 뷰로 처리된 다음 동적으로 DOM에 주입될 수 있기 때문에 Django의 뷰와 잘 작동합니다.
Alpine.js는 대화형 기능을 추가하는 데 사용되는 또 다른 경량 JavaScript 프레임워크입니다. 이는 Django의 템플릿 구조와 잘 작동하며 모달, 드롭다운 또는 토글과 같은 항목에 대한 빠르고 선언적인 동작을 제공합니다. HTMX와 함께 Alpine은 React나 Vue와 같은 것을 처리할 필요 없이 UX를 향상시키기에 충분한 JavaScript를 제공할 수 있습니다. 예를 들어 Alpine을 사용하여 모달 열기 및 닫기, 클라이언트 측 유효성 검사 처리 등 프런트엔드에서 상태를 관리할 수 있습니다.
Tailwind CSS는 이 프로젝트의 스타일을 처리하여 깔끔하고 반응성이 뛰어난 UI 개발 속도를 높입니다. 이 프로젝트에서는 모달, 툴팁, 버튼과 같은 사전 구축된 UI 구성 요소에도 Flowbite를 사용합니다. Flowbite는 Tailwind와 잘 통합되며 일반적인 UI 요소에 대해 수고를 덜 수 있도록 도와줍니다.
Django Cotton을 사용하면 재사용 가능한 Django 템플릿을 만들 수 있습니다. 모달을 재사용 가능하게 만들려고 노력하던 중 프로젝트 중간에 이 멋진 라이브러리를 발견했습니다. 처음에는 Django의 포함 템플릿 태그를 사용해 보았지만 많은 컨텍스트 데이터를 전달하면 금방 복잡해졌습니다. Django-Cotton을 사용하면 HTML 태그와 같은 구문으로 HTMX 및 Tailwind와 잘 결합되는 재사용 가능성이 높은 구성 요소를 만들 수 있습니다. 예를 들어:
이 프로젝트에서는 인증을 구현하기 위해 MFA(다단계 인증)도 지원하는 AllAuth 라이브러리를 사용했습니다. 기존 사용자 인증 설정과 원활하게 통합되는 MFA 모듈을 제공합니다. 인증 앱을 통해 2FA를 활성화하여 추가 보안 계층을 추가할 수 있습니다. 또한 AllAuth가 제공하는 템플릿을 앱의 디자인과 느낌에 맞게 쉽게 맞춤설정할 수도 있습니다.
전반적으로 이 프로젝트는 주로 교육적이며 Django, HTMX, Alpine.js, Tailwind 및 Plaid 통합을 시작하는 데 충분한 기능을 갖추고 있습니다.
즉, 여기저기에 몇 가지 버그가 있을 수 있으며 구성 요소를 개선하고 추가로 재사용할 여지는 항상 있다는 점에 유의하세요. 그러나 전반적으로 이는 이러한 기술을 탐구하려는 모든 사람에게 견고한 기반입니다.
GitHub에서 프로젝트 확인
여기에 언급된 주제를 더 자세히 살펴보고 싶다면 댓글로 알려주시기 바랍니다.
즐거운 코딩 되세요! ?
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3