"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > Django, HTMX, Alpine, Tailwind 및 Plaid를 사용한 개인 금융 관리 앱

Django, HTMX, Alpine, Tailwind 및 Plaid를 사용한 개인 금융 관리 앱

2024년 11월 15일에 게시됨
검색:550

특히 DjangoCon Europe 2022 강연을 시청한 후 HTMX에 대해 관심이 생겼습니다. React에서 실제 SaaS 프로젝트의 HTMX까지. 저는 최근 일상 업무에서 HTMX와 Alpine을 사용해 왔으며, 특히 프런트엔드 개발을 별로 좋아하지 않는 사람으로서 대화형 웹 앱 개발을 훨씬 더 즐겁게 만들었습니다.

저는 Django 템플릿을 별로 좋아하지 않았지만 HTMX, Alpine.js 및 Django Cotton이 제 관점을 바꾸기 시작했습니다. 그리고 Tailwind CSS를 맨 위에 올려서 지금까지 작업한 최고의 스택 중 하나가 되었습니다.

이 프로젝트는 Plaid를 통합하여 은행 계좌를 연결하고 금융 통찰력을 제공하는 개인 금융 관리 앱입니다. 참고 자료로 Plaid의 저장소에 있는 공식 예제를 사용했습니다.

코드에 대한 간략한 개요를 원하시나요? GitHub에서 확인해보세요

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

특징

  • 은행 계좌를 연결하고, 실시간 계좌 데이터를 가져오고, 거래를 추적하는 격자 무늬 통합.
  • 자동화된 웹훅:
    • 새 거래가 가능할 때마다 은행 데이터를 자동으로 동기화하고 업데이트합니다.
    • 계정이 잘못된 상태에 들어갈 때(예: 로그인 필요) 쉽게 업데이트하고 재인증할 수 있습니다.
    • 새 은행 계좌를 자동으로 감지하고 사용자에게 새로 감지된 계좌를 추가하라는 메시지를 표시합니다.
  • 순자산, 계정별 세부정보, 카테고리 기반 지출 내역 등 재무 통찰력을 제공합니다.
  • 추가 보안 계층을 위한 인증 앱을 사용한 2단계 인증(2FA).

시를 이용한 의존성 관리

이 프로젝트에서는 종속성을 관리하기 위해 Poetry를 사용했습니다. Poetry는 패키지 관리 프로세스를 단순화하고 종속성과 관련된 많은 무거운 작업을 자동화합니다. 이는 현재 최신 Python 프로젝트의 빌드 요구 사항을 정의하기 위한 표준인 pyproject.toml 파일을 사용합니다.

왜 시인가?

  • 종속성 해결이 더 쉬워졌습니다.
  • 가상 환경을 생성하고 관리하므로 가상 환경 생성/활성화를 잊어버린 경우 Poetry가 도와드립니다.
  • 패키지의 정확한 버전을 잠가서 환경이 재현 가능한지 확인합니다. 이는 특히 대규모 팀에서 작업할 때 매우 유용합니다.

러프 및 사전 커밋

저는 Rust로 구축된 매우 빠른 Python 린터이자 코드 포맷터인 Ruff를 사용해 왔습니다. Black, isort 등과 같은 여러 도구를 하나로 처리합니다.

내가 Ruff의 장점:

  • 모든 것을 깔끔하게 중앙 집중화하는 pyproject.toml을 사용하여 구성할 수 있습니다.
  • 올인원 제품이라 블랙, 아이소트 등 별도의 도구를 관리할 필요가 없습니다.

저는 또한 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와 잘 결합되는 재사용 가능성이 높은 구성 요소를 만들 수 있습니다. 예를 들어:

AllAuth를 통한 2단계 인증

이 프로젝트에서는 인증을 구현하기 위해 MFA(다단계 인증)도 지원하는 AllAuth 라이브러리를 사용했습니다. 기존 사용자 인증 설정과 원활하게 통합되는 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