HTMX, 파이썬, 장고를 사용한 동적 웹 앱 살펴보기
컨텐츠 정보
- 조회 733
본문
파이썬은 현재 가장 인기 있는 프로그래밍 언어 중 하나인데, 그러한 인기를 끄는 요인 중 하나는 데이터 과학과 AI 애플리케이션을 위한 방대한 툴 생태계다. 그러나 파이썬은 특히 장고 웹 프레임워크를 사용하는 웹 앱 개발 용도로도 널리 사용된다. HTMX가 자바(스프링 부트를 통해), 자바스크립트(자바스크립트 런타임인 번을 통해)를 포함한 다양한 기술 및 스택과 어떻게 통합되는지에 대해서는 그 동안 몇 차례 기사를 썼다. 이번에는 파이썬, 장고, HTMX를 함께 살펴보자.
장고는 직접적인 자바스크립트 코딩 없이 HTMX와 결합해 완전한 인터랙티브 웹 애플리케이션을 개발할 수 있는 성숙한 프레임워크다. 시작하려면 파이썬 3을 설치한 다음 장고 프레임워크를 설치해야 한다. 개발 환경에서 설치가 완료되면 django-admin 명령을 사용해서 디렉터리를 만들고 새 프로젝트를 시작할 수 있다.
$ mkdir quoteproject$ django-admin startproject quoteproject quoteproject/$ cd quoteproject
별칭을 설정해서 $ python에서 python3 런타임을 참조하도록 하는 것도 좋은 방법이다.
$ alias python=python3
localhost 외부에서 개발 서버에 액세스해야 하는 경우 quoteproject/settings.py에서 허용되는 호스트 설정을 수정하면 된다.
ALLOWED_HOSTS = ['*']
참고로 이렇게 하면 모든 수신 요청이 허용되므로 그다지 안전하지는 않다. 설정을 세부적으로 조정해서 클라이언트 IP만 허용하는 것도 가능하다. 어떤 식으로 설정하든 이제 개발 서버를 실행할 수 있다.
$ python manage.py runserver 3000
외부 호스트를 원한다면 $ python manage.py runserver 0.0.0.0:3000를 사용하자. 호스트 서버를 확인하면 다음과 같은 시작 화면이 표시될 것이다.
구성요소
여기서는 인용구를 나열하고 생성하는 애플리케이션을 빌드한다. 이 예제는 서버 측 애플리케이션 기능을 잘 보여주므로 이전 기사에서도 사용한 바 있다. 예제는 HTMX를 사용해 빌드할 다음과 같은 세 가지 기본 구성요소로 이뤄진다.
- 모델
- 뷰
- 경로
모델-뷰-템플릿(MVT) 프레임워크인 장고는 익스프레스, 스프링과 같은 MVC(모델-뷰-컨트롤러) 프레임워크와는 약간 다르지만 이 구분이 그렇게 중요한 것은 아니다. 장고 애플리케이션의 주된 작업인 요청 라우팅, 모델 준비, 응답 렌더링은 모두 잘 정의된 구성요소에 의해 처리된다.
또한 장고에는 기본적으로 지속성이 내장돼 있으므로 SQL 데이터베이스에서 데이터를 저장하고 스키마를 관리하기가 매우 간단하다. 예제 애플리케이션에는 개발에 사용할 SQLite 데이터베이스 인스턴스가 포함돼 있다.
주요 구성요소를 살펴보자.
장고에서 모델 개발하기
이 예제에서는 인용구를 처리할 모델 하나만 있으면 된다.
// quoteapp/models.py from django.db import modelsclass Quote(models.Model): text = models.TextField() author = models.CharField(max_length=255)from django.db import models
Quote라는 영구 객체에 대한 장고의 ORM 구문이다. 여기에는 text라는 큰 TextField, 그리고 author라는 255자 길이의 CharField, 두 개의 필드가 있다. 이를 통해 Quote 객체를 나열하고 CRUD 작업을 수행하는 등 많은 작업이 가능하다.
데이터베이스에 변경 작업을 수행할 때마다 장고 툴을 사용해 스키마를 업데이트할 수 있다.
$ python manage.py makemigrations$ python manage.py migrate
makemigrations 명령은 스키마 변경이 감지될 경우 새 마이그레이션 파일을 생성한다. (해당 파일은 quoteapp/migrations에 있지만 일반적으로 직접 다룰 필요는 없다.) migrate 명령은 변경 사항을 적용한다.
뷰 구성
다음으로, 요청을 수락하고 모델을 준비(필요한 경우)해서 응답으로 렌더링되도록 전달하는 뷰를 살펴보자. 여기서는 quoteapp/views.py에 있는 뷰 하나만 필요하다.
// cat quoteapp/views.py from django.shortcuts import renderfrom django.template.loader import render_to_stringfrom django.http import HttpResponsefrom .models import Quotedef index(request): if request.method == 'POST': text = request.POST.get('text') author = request.POST.get('author') if text and author: new_quote = Quote.objects.create(text=text, author=author) # Render the new quote HTML html = render_to_string('quoteapp/quote_item.html', {'quote': new_quote}) return HttpResponse(html) quotes = Quote.objects.all() return render(request, 'quoteapp/index.html', {'quotes': quotes})이 뷰에서 Quote 모델을 가져와 index 함수에서 응답을 만드는 데 사용한다. request 인수는 클라이언트로부터 필요한 모든 정보에 대한 액세스를 제공한다. 메서드가 POST인 경우 새 Quote 객체를 조합하고 Quote.objects.create()를 사용해 데이터베이스에 삽입한다. 새 인용구에 대한 마크업만 응답으로 다시 보낸다. HTMX는 프런트 엔드의 목록에 이를 삽입한다.
메서드가 GET인 경우 Quote.objects.all()을 사용해서 기존 인용구 집합을 복구하고 quoteapp/index.html에서 페이지 전체의 마크업을 보낼 수 있다.
장고 템플릿과 HTMX
quote_item.html과 index.html은 모두 템플릿으로, 이를 통해 뷰에서 제공하는 모델을 가져와 마크업을 구성할 수 있다. 두 템플릿은 특수한 템플릿 경로에 있다. 다음은 항목을 렌더링하는 간단한 인용구 항목 템플릿이다.
// quoteapp/templates/quoteapp/quote_item.html{{ quote.text }} - {{ quote.author }}
다음은 주 인덱스 템플릿이다.
// quoteapp/templates/quoteapp/index.html
Quotes
- {% for quote in quotes %}
- {{ quote.text }} - {{ quote.author }} {% endfor %}
이러한 템플릿은 퍼그(Pug) 또는 타임리프(Thymeleaf)와 작동 방식이 비슷한 장고 템플릿 언어를 사용한다. 장고의 템플릿 언어는 노출된 Quote 모델에 액세스할 수 있는 HTML을 사용할 수 있게 해준다. {{ }}, {% %} 변수와 태그를 사용해서 파이썬에서 변수에 액세스한다. 예를 들어 {% for quote in quotes %}를 사용해 인용구를 반복하는 루프를 설정해서 각 반복에서 quote 변수를 노출할 수 있다.
HTMX는 HTML의 확장이므로 다른 HTML과 마찬가지로 장고 템플릿에서 HTMX 속성을 사용할 수 있다.
- hx-post : 이 양식이
POST되어야 한다는 점과 데이터를 보낼 위치를 가리킨다. 여기서는views.py의 인덱스 엔드포인트에 게시한다. - hx-target : 서버의 응답을 배치할 위치를 가리킨다. 여기서는 서버가 새 인용구 항목을 보낼 것이므로 목록에 추가한다.
- hx-swap : 응답을 정확히 어떻게 처리할지 세밀하게 조정할 수 있게 해준다. 여기서는
beforeend에 붙인다. 즉, 목록의 마지막 요소가 되도록 한다.
요청 라우팅
이제 어느 요청이 어디로 가는지를 장고에 알려줘야 한다. 장고는 프로젝트와 앱 개념을 사용하는데, 프로젝트 하나에 다수의 앱이 포함될 수 있다. 기본 라우팅은 프로젝트를 만든 사람이 생성한 프로젝트에서 이뤄진다. 이제 애플리케이션을 위한 새 경로를 추가한다.
// quoteproject/urls.py from django.contrib import adminfrom django.urls import path, includeurlpatterns = [ path('admin/', admin.site.urls), path('', include('quoteapp.urls'))]관심사는 여기서 정의하는, 포함된 quoteapp.urls로 루트 경로(“)를 라우팅하는 것이다.
// quoteapp/urls.py from django.urls import pathfrom . import viewsurlpatterns = [ path('', views.index, name='index'),]이는 빈 '' 경로가 어디로 가야 하는지도 알려주는데, 앞서 views.py에서 본 index 함수를 호출하는 것이다. name 인수는 프로젝트의 링크에서 사용할 수 있는 경로에 대한 핸들을 제공한다. path 함수와 URL 처리에 대한 자세한 내용은 장고 문서에서 볼 수 있다.
앱 실행
이제 애플리케이션을 실행하고 테스트할 준비가 거의 다 됐다. 마지막 단계는 quoteapp이 quoteproject의 일부임을 장고에 알리는 것으로, 이 작업은 settings.py에서 수행한다.
// quoteproject/settings.pyINSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'quoteapp']
quoteapp 디렉터리를 INSTALLED_APPS 배열에 추가했다.
이제 $ python manage.py runserver 3000으로 앱을 실행하면 간단하지만 작동하는 UI가 표시된다.
결론
이 기사에서는 파이썬, 장고, HTMX를 사용해 웹 애플리케이션을 빌드하기 위한 기본 요소를 살펴봤다. 부가적인 작업을 많이 하지 않고도 동일한 라우팅 및 엔드포인트 로직을 사용해 API를 빌드할 수 있었다(장고 REST를 고려하면). 장고는 잘 설계되고 성숙한 파이썬용 프레임워크다. 원활하게 작동하며 문제를 일으키는 경우가 거의 없다. 장고는 SQL 데이터베이스를 지향하므로 몽고DB와 같은 NoSQL 데이터베이스를 선호한다면 최선의 선택이 아닐 수 있다. 반면 SQL 데이터 저장소를 매우 편리하게 사용할 수 있게 해준다.
파이썬 개발자라면 장고는 SQL 기반, 데이터 중심 웹 애플리케이션을 빌드하는 데 있어 확실한 선택지고, 비교적 간단한 RESTful API의 경우 팔콘, 플라스크와 같이 특정 부분에 초점을 둔 프레임워크가 더 나을 수 있다.
당연한 말이지만 파이썬, 장고, HTMX를 함께 사용하는 경험은 자바와 스프링 부트, 자바스크립트와 익스프레스, 또는 C# 및 닷넷과 함께 HTMX를 사용할 때의 경험과 비교할 만하다. 어느 프레임워크 또는 스택을 선택하든 HTMX는 부가적인 코딩을 최소화하면서 일상적인 HTML UI를 더 강력하게 만들어 주는 본래의 목적을 충실히 달성하는 것으로 보인다.
dl-itworldkorea@foundryco.com
관련자료
-
링크
-
이전
-
다음





