Django 하이라이트: 템플릿을 사용하면 줄바꿈(2부)

게시 됨: 2022-03-10
빠른 요약 ↬ 템플릿 및 서버 측 렌더링을 사용하여 Django에서 프론트 엔드 코드를 생성하는 것은 손으로 쓴 HTML의 세밀한 제어와 생성된 페이지의 깨끗한 코드 및 강력한 기능을 결합합니다. 복잡한 웹 페이지를 여러 템플릿으로 분해하고, 해당 구성 요소를 구성하고, 태그와 필터를 적용하여 일반 HTML 페이지를 리팩터링하는 방법을 살펴봅니다.

웹사이트 구축에 대한 일부 단순한 접근 방식에서는 개발자가 HTML의 모든 라인을 손으로 작성해야 합니다. 다른 극단적인 경우 상용 코드가 없는 사이트 빌더는 결과 코드의 가독성을 희생시키면서 사용자를 위해 모든 HTML을 자동으로 생성합니다. 템플릿은 그 스펙트럼의 중간 정도이지만 React 또는 유사한 라이브러리를 사용하여 단일 페이지 애플리케이션에서 페이지 구조를 생성하는 것보다 손으로 작성한 HTML에 더 가깝습니다. 연속체에 있는 이 스위트 스폿은 처음부터 수동 HTML(의미론적/가독성 있는 코드, 페이지 구조에 대한 완전한 제어, 빠른 페이지 로드)의 많은 이점을 제공하고, 작성하는 데 약간의 시간을 들이는 대가로 우려 사항과 간결함의 분리를 추가합니다. HTML을 손으로 수정했습니다. 이 기사에서는 Django 템플릿을 사용하여 복잡한 페이지를 작성하는 방법을 보여줍니다.

HTML 스펙트럼. (큰 미리보기)

오늘의 주제는 Django 프레임워크를 넘어 적용됩니다. Flask(또 다른 웹 프레임워크)와 Pelican(정적 사이트 생성기)은 템플릿에 동일한 접근 방식을 사용하는 다른 많은 Python 프로젝트 중 두 가지일 뿐입니다. Jinja2는 세 가지 프레임워크 모두에서 사용하는 템플릿 엔진이지만 프로젝트 설정을 변경하여 다른 프레임워크를 사용할 수도 있습니다(엄밀히 말하면 Jinja2는 Django 템플릿의 상위 집합입니다). 프레임워크 없이도 자신의 프로젝트에 통합할 수 있는 독립형 라이브러리이므로 이 기사의 기술은 광범위하게 유용합니다.

시리즈의 이전 부품 :

  • Django 하이라이트: 사용자 모델 및 인증(1부)
  • Django 하이라이트: 모델, 관리자 및 관계형 데이터베이스 활용(3부)
  • Django 하이라이트: 정적 자산 및 미디어 파일 랭글링(4부)
점프 후 더! 아래에서 계속 읽기 ↓

서버 측 렌더링

템플릿은 HTML이 추가 기호로 확장된 HTML 파일입니다. HTML이 의미하는 바를 기억 하십시오. 하이퍼 텍스트 마크 언어. 우리의 템플릿 언어인 Jinja2는 의미 있는 마크업 기호를 추가하여 단순히 언어에 추가합니다. 이러한 추가 구조는 서버가 사용자에게 일반 HTML 페이지를 제공하기 위해 템플릿을 렌더링할 때 해석됩니다(즉, 템플릿 언어의 추가 기호가 최종 출력에 포함되지 않음).

서버 측 렌더링은 요청에 대한 응답으로 웹 페이지를 구성하는 프로세스입니다. Django는 서버 측 렌더링을 사용하여 HTML 페이지를 클라이언트에 제공합니다. 실행이 끝나면 보기 함수는 HTTP 요청, 하나 이상의 템플릿, 선택적으로 함수 실행 중에 액세스되는 데이터를 결합하여 클라이언트에 응답으로 보내는 단일 HTML 페이지를 구성합니다. 데이터는 데이터베이스에서 보기를 통해 템플릿으로 이동하여 사용자에게 전달됩니다. 이 추상적인 설명이 완전히 이해되지 않더라도 걱정하지 마십시오. 이 기사의 나머지 부분에서는 구체적인 예를 살펴보겠습니다.

설정

이 예에서는 상당히 복잡한 웹 페이지인 Start Bootstrap의 관리 템플릿을 사용하고 HTML을 Jinja2 템플릿으로 다시 작성합니다. MIT 라이선스 라이브러리는 다른 템플릿 시스템(JavaScript 및 Pug 기반)을 사용하여 표시되는 페이지를 생성하지만 접근 방식이 Jinja2 스타일 템플릿과 크게 다르기 때문에 이 예제는 번역보다 리버스 엔지니어링에 가깝습니다. 그들의 우수한 오픈 소스 프로젝트. 우리가 구성할 웹 페이지를 보려면 Start Bootstrap의 라이브 미리 보기를 살펴보십시오.

이 기사에 대한 샘플 응용 프로그램을 준비했습니다. 자신의 컴퓨터에서 Django 프로젝트를 실행하려면 Python 3 가상 환경을 시작한 후 다음 명령을 실행하세요.

 pip install django git clone https://github.com/philipkiely/sm_dh_2_dashboard.git cd sm_dh_2_dashboard python manage.py migrate python manage.py createsuperuser python manage.py loaddata employee_fixture.json python manage.py runserver

그런 다음 웹 브라우저를 열고 https://127.0.0.1:8000 으로 이동합니다. 아래 이미지와 일치하는 미리보기와 동일한 페이지가 표시되어야 합니다.

대시보드 메인 페이지. (큰 미리보기)

이 튜토리얼은 프론트엔드에 초점을 맞추기 때문에 기본 Django 앱은 매우 간단합니다. 이것은 단일 웹 페이지를 표시하기 위한 많은 구성처럼 보일 수 있으며 공정합니다. 그러나 이 많은 설정은 훨씬 더 강력한 애플리케이션도 지원할 수 있습니다.

이제 이 668줄 HTML 파일을 적절하게 설계된 Django 사이트로 전환하는 프로세스를 진행할 준비가 되었습니다.

템플릿과 상속

수백 줄의 HTML을 깨끗한 코드로 리팩토링하는 첫 번째 단계는 요소를 자체 템플릿으로 분할하는 것입니다. Django는 렌더링 단계에서 이 템플릿을 단일 웹페이지로 구성합니다.

페이지/템플릿 을 살펴보세요. 5개의 파일이 표시되어야 합니다.

  • base.html , 모든 웹 페이지가 확장할 기본 템플릿입니다. 제목, CSS 가져오기 등이 포함된 <head> 가 포함되어 있습니다.
  • navbar.html , 필요한 경우 포함할 구성 요소인 상단 탐색 모음의 HTML입니다.
  • footer.html , 페이지 바닥글에 대한 코드, 필요한 경우 포함할 또 다른 구성 요소.
  • sidebar.html , 필요할 때 포함되는 세 번째 구성 요소인 사이드바의 HTML입니다.
  • index.html , 메인 페이지에 고유한 코드. 이 템플릿은 기본 템플릿을 확장하고 세 가지 구성 요소를 포함합니다.

Django는 Voltron과 같은 5개의 파일을 조합하여 인덱스 페이지를 렌더링합니다. 이를 허용하는 키워드는 {% block %} , {% include %}{% extend %} 입니다. base.html 에서:

 {% block content %} {% endblock %}

이 두 줄은 base.html 을 확장하여 자체 HTML을 삽입하는 다른 템플릿을 위한 공간을 남깁니다. content 은 변수 이름이므로 템플릿에 이름이 다른 여러 블록을 가질 수 있으므로 하위 템플릿에 유연성을 부여할 수 있습니다. index.html 에서 이것을 확장하는 방법을 봅니다.

 {% extends "base.html" %} {% block content %} <!-- HTML Goes Here --> {% endblock %}

기본 템플릿 이름과 함께 extends 키워드를 사용하면 인덱스 페이지에 구조가 지정되어 제목에서 복사하지 않아도 됩니다(파일 이름은 큰따옴표로 묶인 문자열 형식의 상대 경로입니다). 색인 페이지에는 사이트의 대부분의 페이지에 공통적인 세 가지 구성 요소가 모두 포함되어 있습니다. 다음과 같이 include 태그를 사용하여 해당 구성 요소를 가져옵니다.

 {% extends "base.html" %} {% block content %} {% include "navbar.html" %} {% include "sidebar.html" %} <!--Index-Specific HTML--> {% include "footer.html" %} <!--More Index-Specific HTML--> {% endblock %}

전반적으로 이 구조는 페이지를 개별적으로 작성하는 것보다 세 가지 주요 이점을 제공합니다.

  • DRY(자신을 반복하지 마십시오) 코드
    공통 코드를 특정 파일로 분리하여 한 곳에서만 코드를 변경하고 모든 페이지에 이러한 변경 사항을 반영할 수 있습니다.
  • 가독성 향상
    하나의 거대한 파일을 스크롤하는 대신 관심 있는 특정 구성 요소를 분리할 수 있습니다.
  • 우려의 분리
    예를 들어 사이드바에 대한 코드 이제 한 곳에 있어야 하며 코드 맨 아래에 떠 있는 불량 script 태그나 별도의 구성 요소가 되어야 하는 것 사이에 다른 혼합이 있어서는 안 됩니다. 개별 조각을 제거하면 이 좋은 코딩 방법이 적용됩니다.

base.html 템플릿에 특정 구성 요소를 추가하여 더 많은 코드 줄을 절약할 수 있지만 이를 별도로 유지하면 두 가지 이점이 있습니다. 첫 번째는 단일 블록에 속하는 위치에 정확히 삽입할 수 있다는 것입니다( content 블록의 기본 div 내부에 들어가는 footer.html 에만 관련됨). 다른 장점은 404 오류 페이지와 같은 페이지를 생성할 때 사이드바나 바닥글을 원하지 않는 경우 제외할 수 있다는 것입니다.

이러한 기능은 템플릿 과정과 동등합니다. 이제 index.html 에서 동적 기능을 제공하고 수백 줄의 코드를 저장하는 데 사용할 수 있는 강력한 태그로 전환합니다.

두 가지 기본 태그

이것은 사용 가능한 태그의 전체 목록과 거리가 멉니다. 템플릿에 대한 Django 문서는 이러한 열거를 제공합니다. 지금은 템플릿 언어의 가장 일반적인 두 가지 요소에 대한 사용 사례에 초점을 맞추고 있습니다. 내 작업에서는 기본적으로 forif 태그만 정기적으로 사용하지만, 12개 이상의 다른 태그가 고유한 사용 사례를 갖도록 제공되므로 템플릿 참조에서 검토하는 것이 좋습니다.

태그를 다루기 전에 구문에 대해 메모하고 싶습니다. {% foo %} 태그는 "foo"가 템플릿 시스템 자체의 기능 또는 기타 기능임을 의미하는 반면, {{ bar }} 태그는 "bar"가 특정 템플릿에 전달되는 변수임을 의미합니다.

For 루프

나머지 index.html 에서 수백 줄의 가장 큰 코드 섹션은 테이블입니다. 이 하드코딩된 테이블 대신 데이터베이스에서 테이블을 동적으로 생성할 수 있습니다. 설정 단계에서 python manage.py loaddata employee_fixture.json 을 호출합니다. 이 명령은 Django Fixture라는 JSON 파일을 사용하여 57개의 모든 직원 레코드를 애플리케이션의 데이터베이스에 로드했습니다. 이 데이터를 템플릿에 전달하기 위해 views.py 의 보기를 사용합니다.

 from django.shortcuts import render from .models import Employee def index(request): return render(request, "index.html", {"employees": Employee.objects.all()})

render 할 세 번째 위치 인수는 템플릿에서 사용할 수 있는 데이터 사전입니다. 이 데이터와 for 태그를 사용하여 테이블을 구성합니다. 이 웹 페이지를 적용한 원본 템플릿에서도 직원 테이블이 하드 코딩되었습니다. 우리의 새로운 접근 방식은 수백 줄의 반복적인 하드 코딩된 테이블 행을 잘라냅니다. index.html 은 이제 다음을 포함합니다:

 {% for employee in employees %} <trv <td>{{ employee.name }}</td> <td>{{ employee.position }}</td> <td>{{ employee.office }}</td> <td>{{ employee.age }}</td> vtd>{{ employee.start_date }}</td> <td>${{ employee.salary }}</td> </tr> {% endfor %}

더 큰 이점은 테이블 업데이트 프로세스를 크게 단순화한다는 것입니다. 개발자가 급여 인상 또는 신규 고용을 반영하도록 HTML을 수동으로 편집한 다음 해당 변경 사항을 프로덕션에 푸시하도록 하는 대신 관리자는 관리자 패널을 사용하여 실시간 업데이트를 수행할 수 있습니다(https://127.0.0.1/admin, 사용 액세스하기 위해 python manage.py createsuperuser 로 생성한 자격 증명). 이것은 Django를 정적 사이트 생성기 또는 다른 템플릿 접근 방식에서 자체적으로 사용하는 대신 이 렌더링 엔진과 함께 사용하는 이점입니다.

다른 경우라면

if 태그는 템플릿 내의 표현식을 평가하고 그에 따라 HTML을 조정할 수 있는 매우 강력한 태그입니다. {% if 1 == 2 %} 와 같은 줄은 매번 같은 결과로 평가되기 때문에 약간 쓸모가 없더라도 완벽하게 유효합니다. if 태그가 빛나는 곳은 뷰에서 템플릿으로 전달된 데이터와 상호 작용할 때입니다. sidebar.html 의 다음 예를 고려하십시오.

 <div class="sb-sidenav-footer"> <div class="small"> Logged in as: </div> {% if user.is_authenticated %} {{ user.username }} {% else %} Start Bootstrap {% endif %} </div>

전체 사용자 개체는 기본적으로 템플릿에 전달되며, 이를 수행하기 위해 보기에서 아무 것도 지정하지 않습니다. 이를 통해 HTML 파일에서 사용자 프로필 또는 기타 연결된 모델에 저장된 데이터에 액세스하기 위해 외래 키 관계를 따르는 것을 포함하여 사용자의 인증 상태(또는 그 부재), 사용자 이름 및 기타 기능에 액세스할 수 있습니다.

이 수준의 액세스가 보안 위험을 초래할 수 있다고 우려할 수 있습니다. 그러나 이러한 템플릿은 서버 측 렌더링 프레임워크를 위한 것임을 기억하십시오. 페이지를 구성한 후 태그는 자체적으로 소비되고 순수 HTML로 대체됩니다. 따라서 if 문이 일부 조건에서 페이지에 데이터를 도입하지만 주어진 인스턴스에서 데이터가 사용되지 않는 if 문이 서버 측에서 평가되기 때문에 해당 데이터는 클라이언트에 전혀 전송되지 않습니다. 이것은 적절하게 구성된 템플릿이 필요하지 않는 한 해당 데이터가 서버를 떠나지 않고 페이지에 중요한 데이터를 추가하는 매우 안전한 방법임을 의미합니다. 즉, Django 템플릿을 사용한다고 해서 민감한 정보를 안전하고 암호화된 방식으로 전달할 필요가 없어지는 것은 아닙니다. 이는 단순히 user.is_authenticated 와 같은 보안 검사가 HTML이 서버 측에서 처리될 때 HTML에서 안전하게 발생할 수 있음을 의미합니다.

이 기능에는 다른 여러 사용 사례가 있습니다. 예를 들어 일반 제품 홈페이지에서 로그인한 사용자를 위해 "가입" 및 "로그인" 버튼을 숨기고 "로그아웃" 버튼으로 대체할 수 있습니다. 또 다른 일반적인 용도는 양식 제출과 같은 작업에 대한 성공 또는 오류 메시지를 표시하거나 숨기는 것입니다. 일반적으로 사용자가 로그인하지 않은 경우 전체 페이지를 숨기지 않습니다. 사용자의 인증 상태에 따라 전체 웹 페이지를 변경하는 더 좋은 방법은 views.py 의 적절한 기능에서 처리하는 것입니다.

필터링

보기의 작업 중 일부는 페이지에 맞게 데이터 형식을 지정하는 것입니다. 이를 수행하기 위해 태그에 대한 강력한 확장 기능인 필터가 있습니다. Django에는 텍스트 정렬, 날짜 형식 지정, 숫자 추가와 같은 작업을 수행하는 데 사용할 수 있는 많은 필터가 있습니다. 기본적으로 필터는 태그의 변수에 적용되는 함수로 생각할 수 있습니다. 예를 들어 급여 번호가 "1200000" 대신 "$1,200,000"이기를 원합니다. 필터를 사용하여 index.html 에서 작업을 완료합니다.

 <td>${{ employee.salary|intcomma }}</td>

파이프 문자 | intcomma 명령을 employee.salary 변수에 적용하는 필터입니다. "$" 문자는 템플릿에서 온 것이 아닙니다. 매번 나타나는 것과 같은 요소의 경우 태그 외부에 붙이는 것이 더 쉽습니다.

intcomma 를 사용하려면 settings.pyINSTALLED_APPSindex.html'django.contrib.humanize', 상단에 {% load humanize %} 를 포함해야 합니다. 이 작업은 제공된 샘플 애플리케이션에서 수행됩니다.

결론

Jinja2 엔진을 사용한 서버 측 렌더링은 깨끗하고 적응 가능하며 반응이 빠른 프론트 엔드 코드를 생성하기 위한 핵심 도구를 제공합니다. 페이지를 파일로 분리하면 유연한 구성으로 DRY 구성 요소를 사용할 수 있습니다. 태그는 보기 기능에 의해 데이터베이스에서 전달된 데이터를 표시하기 위한 기본적인 기능을 제공합니다. 이 접근 방식은 사이트의 속도, SEO 기능, 보안 및 유용성을 높일 수 있으며 Django 및 유사한 프레임워크 프로그래밍의 핵심 측면입니다.

아직 수행하지 않았다면 샘플 애플리케이션을 확인하고 전체 목록을 사용하여 고유한 태그와 필터를 추가해 보십시오.

Django Highlights는 Django에서 웹 개발의 중요한 개념을 소개하는 시리즈입니다. 각 기사는 프론트 엔드 개발자와 디자이너가 코드 기반의 "나머지 절반"에 대해 더 깊이 이해할 수 있도록 돕기 위한 Django 개발 측면에 대한 독립 실행형 가이드로 작성되었습니다. 이 기사는 대부분 이론과 관례에 대한 이해를 돕기 위해 작성되었지만 Django 3.0으로 작성된 일부 코드 샘플이 포함되어 있습니다.

시리즈의 이전 부품 :

  • Django 하이라이트: 사용자 모델 및 인증(1부)
  • Django 하이라이트: 모델, 관리자 및 관계형 데이터베이스 활용(3부)
  • Django 하이라이트: 정적 자산 및 미디어 파일 랭글링(4부)