2단계: 보기 및 페이지 템플릿을 사용하여 Django 앱 만들기

이전 단계: Visual Studio 프로젝트 및 솔루션 만들기

Visual Studio 프로젝트에는 하나 이상의 Django 을 실행할 수 있는 Django 프로젝트의 사이트 수준 구성 요소만 있습니다. 다음 단계에서는 단일 페이지로 구성된 첫 번째 앱을 만듭니다.

이 단계에서는 다음 방법을 학습합니다.

  • 단일 페이지로 구성된 Django 앱 만들기(2-1단계)
  • Django 프로젝트에서 앱 실행(2-2단계)
  • HTML을 사용하여 보기 렌더링(2-3단계)
  • Django 페이지 템플릿을 사용하여 보기 렌더링(2-4단계)

2-1단계: 기본 구조로 앱 만들기

Django 앱은 특정 용도로 관련 파일 집합을 포함하는 별도의 Python 패키지입니다. Django 프로젝트에는 수많은 앱이 포함될 수 있으며, 이는 웹 호스트가 단일 도메인 이름에서 많은 개별 진입점을 제공하는 데 도움이 됩니다. 예를 들어 do기본 같은 contoso.com Django 프로젝트에는 하나의 앱, 두 번째 앱 www.contoso.comsupport.contoso.com및 세 번째 앱이 docs.contoso.com포함될 수 있습니다. 이 경우 Django 프로젝트는 사이트 수준 URL 라우팅 및 설정을 (urls.pysettings.py 파일에서) 처리합니다. 각 앱에는 내부 라우팅, 보기, 모델, 정적 파일 및 관리 인터페이스를 통해 고유한 스타일과 동작이 있습니다.

Django 앱은 대체로 표준 파일 집합으로 시작합니다. Visual Studio는 Django 프로젝트 내에서 Django 앱을 초기화하는 템플릿을 동일한 용도로 사용되는 통합 메뉴 명령과 함께 제공합니다.

  • 템플릿: 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가>새 항목을 선택합니다. 새 항목 추가 대화 상자에서 Django 1.9 앱 템플릿을 선택하고, 이름 필드에 앱 이름을 지정하고, 추가를 선택합니다.

Screenshot of Solution Explorer.

Screenshot of Add New Item window.

  • 통합 명령: 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가>Django 앱을 선택합니다. 이 명령은 이름을 묻는 메시지를 표시합니다. 새 앱 이름 필드에서 앱 이름을 지정하고 확인을 선택합니다.

    Menu command for adding a Django app.

    Menu command to enter a Django app name.

두 방법 중 하나를 사용하여 “HelloDjangoApp”이라는 이름으로 앱을 만듭니다. 이제 프로젝트에 ‘HelloDjangoApp’ 폴더가 생성됩니다. 폴더에는 다음 항목이 포함됩니다.

Django app files in Solution Explorer.

항목 설명
migrations Django가 모델의 변경 내용에 맞게 데이터베이스를 업데이트하는 스크립트를 저장하는 폴더입니다. Django의 마이그레이션 도구는 현재 모델과 일치하도록 이전 버전의 데이터베이스에 필요한 변경 내용을 적용합니다. 마이그레이션을 사용하여 모델에 초점을 맞추고 Django에서 기본 데이터베이스 스키마를 처리하도록 합니다. 마이그레이션은 Django 설명서에서 설명합니다. 지금 폴더에는 폴더가 고유한 Python 패키지를 정의한다고 나타내는 __init__.py 파일이 포함됩니다.
__init__.py 앱을 패키지로 식별하는 파일입니다.
templates 단일 파일 index.html을 포함하는 Django 페이지 템플릿의 폴더입니다. index.html 파일은 앱 이름과 동일한 폴더에 배치됩니다. (Visual Studio 2017 15.7 이전 버전에서 파일은 템플릿 바로 아래에 배치되며 2-4단계에서는 사용자가 하위 폴더를 만들도록 지시합니다.) 템플릿은 보기에서 페이지를 동적으로 렌더링하기 위해 정보를 추가할 수 있는 HTML의 블록입니다. index.html{{ content }}와 같은 페이지 템플릿 "변수"는 이 아티클의 뒷부분(2단계)에서 설명하는 동적 값의 자리 표시자입니다. 일반적으로 Django 앱은 앱 이름과 일치하는 하위 폴더에 템플릿을 저장하여 해당 템플릿에 대한 네임스페이스를 만듭니다.
admin.py 데이터베이스의 데이터를 보고 편집하는 데 사용되는 앱의 관리 인터페이스를 확장하는 Python 파일입니다. 처음에는 이 파일에 from django.contrib import admin 문만 포함되어 있습니다. 기본적으로 Django에는 Django 프로젝트의 settings.py 파일에 있는 항목을 통해 표준 관리 인터페이스가 포함됩니다. 인터페이스를 켜기 위해 urls.py 파일에서 기존 항목의 주석 처리를 제거할 수 있습니다.
apps.py 앱에 대한 구성 클래스를 정의하는 Python 파일입니다(이 표 다음의 아래 참조).
models.py 모델은 뷰가 앱의 기본 데이터베이스와 상호 작용하는 데 사용하는 데이터 개체로, 함수로 식별됩니다. Django는 앱이 모델 세부 정보에 신경을 쓸 필요가 없도록 데이터베이스 연결 계층을 제공합니다. models.py 파일은 모델을 생성하는 기본 위치입니다. 처음에 models.py 파일에는 from django.db import models 문만 포함됩니다.
tests.py 단위 테스트의 기본 구조를 포함하는 Python 파일입니다.
views.py 보기는 웹 페이지와 비슷하며, HTTP 요청을 받고 HTTP 응답을 반환합니다. 일반적으로 보기는 HTML로 렌더링되며 웹 브라우저는 이를 표시하는 방법을 알고 있지만 중간 양식처럼 보기가 반드시 표시되어야 하는 것은 아닙니다. 보기는 HTML을 브라우저로 렌더링하는 역할을 하는 Python 함수에 의해 정의됩니다. views.py 파일은 보기를 생성하는 기본 위치입니다. 처음에 views.py 파일에는 from django.shortcuts import render 문만 포함됩니다.

‘HelloDjangoApp’이라는 이름을 사용하면 apps.py 파일의 내용이 다음과 같이 표시됩니다.

from django.apps import AppConfig

class HelloDjangoAppConfig(AppConfig):
    name = 'HelloDjango'

질문: Visual Studio에서 Django 앱을 만들면 명령줄에서 앱을 만드는 것과 다른가요?

대답: 추가>Django 앱 명령을 실행하거나 Django 앱 템플릿에서 추가>새 항목을 사용하면 Django 명령 manage.py startapp <app_name>과 동일한 파일이 생성됩니다. Visual Studio에서 앱을 만들면 앱 폴더와 모든 파일이 프로젝트에 자동으로 통합되는 장점이 있습니다. 동일한 Visual Studio 명령을 사용하여 프로젝트에 많은 앱을 만들 수 있습니다.

2-2단계: Django 프로젝트에서 앱 실행

이때 Visual Studio에서 도구 모음 단추나 디버그>디버깅 시작을 사용하여 프로젝트를 다시 실행하면 기본 페이지가 계속 표시됩니다. 앱 관련 페이지를 정의하고 Django 프로젝트에 앱을 추가해야 하므로 앱 콘텐츠가 나타나지 않습니다.

  1. HelloDjangoApp 폴더에서 ‘index’라는 뷰를 정의하도록 views.py 파일을 수정합니다.

    from django.shortcuts import render
    from django.http import HttpResponse
    
    def index(request):
        return HttpResponse("Hello, Django!")
    
  2. 1단계에서 만든 BasicProject 폴더에서 다음 코드와 일치하도록 urls.py 파일을 수정합니다. 원한다면 유용한 주석을 계속 유지할 수 있습니다.

    from django.urls import include, re_path
    import HelloDjangoApp.views
    
    # Django processes URL patterns in the order they appear in the array
    urlpatterns = [
        re_path(r'^$', HelloDjangoApp.views.index, name='index'),
        re_path(r'^home$', HelloDjangoApp.views.index, name='home')
    ]
    

    각 URL 패턴은 Django가 특정 사이트 기준 URL(즉, https://www.domain.com/ 다음에 오는 부분)을 라우팅하는 보기를 설명합니다. 정규식 ^$로 시작하는 urlPatterns의 첫 번째 항목은 사이트 루트 “/”에 대한 라우팅입니다. 두 번째 항목인 ^home$은 특히 “/home”을 라우팅합니다. 동일한 보기에 대해 여러 개의 라우팅이 존재할 수 있습니다.

  3. 프로젝트를 다시 실행하여 보기에 정의된 대로 Hello, Django! 메시지를 확인합니다. 완료되면 서버를 중지합니다.

소스 제어에 커밋

코드를 변경하고 성공적으로 테스트한 후에는 소스 제어를 검토하고 커밋할 수 있습니다. 이후 단계에서 이 자습서가 소스 제어에 다시 커밋하라는 알림을 표시하면 이 섹션을 참조할 수 있습니다.

  1. Visual Studio의 아래쪽(아래 원)에 있는 변경 단추를 선택하여 팀 탐색기로 이동합니다.

    Source control changes button on the Visual Studio status bar.

  2. 팀 탐색기에서 “Create initial Django app”과 같은 커밋 메시지를 입력하고 모두 커밋을 선택합니다. 커밋이 완료되면 커밋 <해시>가 로컬로 생성된 메시지가 표시됩니다. 동기화하여 변경 내용을 서버와 공유합니다. 원격 리포지토리에 변경 내용을 푸시하려면 동기화를 선택한 다음 나가는 커밋에서 푸시를 선택합니다. 원격에 푸시하기 전에 여러 개의 로컬 커밋을 누적할 수도 있습니다.

    Push commits to remote repository in Team Explorer.

질문: 라우팅 문자열 앞에 있는 'r' 접두사는 무엇인가요?

대답: Python에서 문자열의 ‘r’ 접두사는 “원시”를 의미하며, Python에서 문자열 내의 문자를 이스케이프하지 않도록 지시합니다. 정규식은 많은 특수 문자를 사용합니다. 'r' 접두사를 사용하면 문자열을 이스케이프 문자 '\'보다 훨씬 더 쉽게 읽을 수 있습니다.

질문: URL 라우팅 항목에서 ^ 및 $ 문자의 의미는 무엇인가요?

대답: URL 패턴을 정의하는 정규식에서 ^는 ‘줄의 시작’을 의미하고 $는 ‘줄의 끝’을 의미합니다. 이때 URL은 사이트 루트(https://www.domain.com/ 다음에 오는 부분)에 상대적입니다. 정규식 ^$는 결과적으로 ‘공백’을 의미하며 전체 URL https://www.domain.com/(사이트 루트에 아무것도 추가되지 않음)과 일치합니다. ^home$ 패턴은 https://www.domain.com/home/과 정확히 일치합니다. Django는 패턴 일치에서 후행 /를 사용하지 않습니다.

^home과 마찬가지로 정규식에서 후행 $를 사용하지 않으면 URL 패턴이 “home”으로 시작하는 ‘모든’ URL(예: “home”, “homework”, “homestead” 및 “home192837”)과 일치합니다.

다른 정규식으로 실험하려면 pythex.org에서 regex101.com과 같은 온라인 도구를 사용해 보세요.

2-3단계: HTML을 사용하여 보기 렌더링

views.py 파일에 있는 index 함수는 페이지에 대한 일반 텍스트 HTTP 응답을 생성합니다. 대부분의 실제 웹 페이지는 라이브 데이터를 통합하는 서식 있는 HTML 페이지로 응답합니다. 실제로 함수를 사용하여 보기를 정의하는 주된 이유는 콘텐츠를 동적으로 생성하기 위함입니다.

HttpResponse에 대한 인수는 단순한 문자열이므로 문자열 내에서 원하는 HTML을 작성할 수 있습니다. 간단한 예제로 index 함수를 다음 코드로 바꿉니다(기존 from 문 유지). 그러면 index 함수는 페이지를 새로 고칠 때마다 업데이트되는 동적 콘텐츠를 사용하여 HTML 응답을 생성합니다.

from datetime import datetime

def index(request):
    now = datetime.now()

    html_content = "<html><head><title>Hello, Django</title></head><body>"
    html_content += "<strong>Hello Django!</strong> on " + now.strftime("%A, %d %B, %Y at %X")
    html_content += "</body></html>"

    return HttpResponse(html_content)

이제 프로젝트를 다시 실행하면 ‘Hello Django! 2018년 4월 16일 월요일 16:28:10’ 같은 메시지가 표시됩니다. 페이지를 새로 고쳐 시간을 업데이트하고 각 요청과 함께 콘텐츠가 생성되는지 확인합니다. 완료되면 서버를 중지합니다.

프로젝트를 중지했다가 다시 시작하는 바로 가기는 디버그>다시 시작 메뉴 명령(Ctrl+Shift+F5)이나 디버깅 도구 모음의 다시 시작 단추를 사용하는 것입니다.

Restart button on the debugging toolbar in Visual Studio.

2-4단계: 페이지 템플릿을 사용하여 보기 렌더링

코드에서 HTML을 생성하는 것은 작은 페이지에 적합합니다. 그러나 페이지가 더 정교해짐에 따라 페이지의 정적 HTML 부분(CSS 및 JavaScript 파일에 대한 참조와 함께)을 ‘페이지 템플릿’으로 유지 관리해야 합니다. 그런 다음 동적 코드 생성 콘텐츠를 페이지 템플릿에 삽입할 수 있습니다. 이전 섹션에서는 now.strftime 호출의 날짜와 시간만 동적이며, 이는 다른 모든 콘텐츠를 페이지 템플릿에 배치할 수 있음을 의미합니다.

Django 페이지 템플릿은 ‘변수’라고 하는 여러 대체 토큰을 포함하는 HTML 블록입니다. 변수는 {{}}로 구분됩니다(예: {{ content }}). 이렇게 하면 Django의 템플릿 모듈은 코드에서 제공하는 동적 콘텐츠로 변수를 바꿉니다.

다음 단계에서는 페이지 템플릿의 사용을 보여줍니다.

  1. Django 프로젝트가 포함된 BasicProject 폴더에서 settings.py 파일을 엽니다. 앱 이름 ‘HelloDjangoApp’을 INSTALLED_APPS 목록에 추가합니다. 목록에 앱을 추가하면 앱이 포함된 ‘HelloDjangoApp’이라는 이름의 폴더가 있음을 Django 프로젝트에 알립니다.

    INSTALLED_APPS = [
        'HelloDjangoApp',
        # Other entries...
    ]
    
  2. settings.py 파일에서 TEMPLATES 개체에 다음 줄이 포함되어 있는지 확인합니다(기본적으로 포함됨). 다음 코드는 설치된 앱의 템플릿 폴더에서 템플릿을 찾도록 Django에 지시합니다.

    'APP_DIRS': True,
    
  3. HelloDjangoApp 폴더에서 templates/HelloDjangoApp/index.html 페이지 템플릿 파일(또는 VS 2017 15.7 이전에서 templates/index.html)을 열어 하나의 변수인 {{ content }}가 포함되어 있는지 확인합니다.

    <html>
      <head>
        <title></title>
      </head>
    
      <body>
        {{ content }}
      </body>
    </html>
    
  4. HelloDjangoApp 폴더에서 views.py 파일을 열고 index 함수를 django.shortcuts.render 도우미 함수를 사용하는 다음 코드로 바꿉니다. render 도우미는 페이지 템플릿 작업을 위한 간단한 인터페이스를 제공합니다. 기존의 모든 from 문을 유지해야 합니다.

    from django.shortcuts import render   # Added for this step
    
    def index(request):
        now = datetime.now()
    
        return render(
            request,
            "HelloDjangoApp/index.html",  # Relative path from the 'templates' folder to the template file
            # "index.html", # Use this code for VS 2017 15.7 and earlier
            {
                'content': "<strong>Hello Django!</strong> on " + now.strftime("%A, %d %B, %Y at %X")
            }
        )
    

    여기서 render에 대한 첫 번째 인수는 요청 개체이며, 앱의 templates 폴더 내에 있는 템플릿 파일의 상대 경로가 그 뒤에 옵니다. 해당하는 경우 템플릿 파일의 이름은 보기에 대해 지정됩니다. render에 대한 세 번째 인수는 템플릿이 참조하는 변수의 사전입니다. 사전에 개체를 포함할 수 있으며, 이 경우 템플릿의 변수는 {{ object.property }}를 참조할 수 있습니다.

  5. 프로젝트를 실행하고 출력을 확인합니다. 2-2단계와 유사한 메시지가 표시되어 템플릿이 작동함을 나타냅니다.

    content 속성에 사용된 HTML은 render 함수가 HTML을 자동으로 이스케이프하기 때문에 일반 텍스트로만 렌더링됩니다. 자동 이스케이프는 삽입 공격에 대한 우발적인 취약성을 방지합니다. 개발자는 종종 한 페이지에서 입력을 수집하고 템플릿 자리 표시자를 통해 그 입력을 다른 페이지의 값으로 사용합니다. 이스케이프는 HTML을 페이지 템플릿에 두고 코드에는 넣지 않는 것이 최선이라는 것을 상기시켜 주는 역할도 합니다. 또한 필요하다면 더 많은 변수를 간편하게 만들 수 있습니다. 예를 들어 템플릿이 있는 index.html 파일을 다음 마크업과 일치하도록 변경합니다. 다음 태그는 페이지 제목을 추가하고 페이지 템플릿의 모든 형식을 유지합니다.

    <html>
      <head>
        <title>{{ title }}</title>
      </head>
      <body>
        <strong>{{ message }}</strong>{{ content }}
      </body>
    </html>
    

    그런 다음, 페이지 템플릿의 모든 변수에 대해 값을 제공하기 위해 index 보기 함수를 다음과 같이 작성합니다.

    def index(request):
        now = datetime.now()
    
        return render(
            request,
            "HelloDjangoApp/index.html",  # Relative path from the 'templates' folder to the template file
            # "index.html", # Use this code for VS 2017 15.7 and earlier
            {
                'title' : "Hello Django",
                'message' : "Hello Django!",
                'content' : " on " + now.strftime("%A, %d %B, %Y at %X")
            }
        )
    
  6. 서버를 중지하고 프로젝트를 다시 시작합니다. 페이지가 제대로 렌더링되는지 확인합니다.

    Running app using the template.

  7. Visual Studio 2017 버전 15.7 및 이전 버전: 마지막 단계에서는 템플릿을 앱과 동일한 이름의 하위 폴더로 이동합니다. 하위 폴더는 네임스페이스를 생성하고 프로젝트에 추가할 수 있는 다른 앱과의 잠재적인 충돌을 방지합니다. (VS 2017 15.8+의 템플릿은 이 작업을 자동으로 수행합니다.) 즉, HelloDjangoApp이라는 templates의 하위 폴더를 만들고, index.html 파일을 해당 하위 폴더로 이동하며, index 보기 함수를 수정합니다. index 보기 함수는 템플릿의 새 경로인 HelloDjangoApp/index.html을 참조합니다. 그런 다음, 프로젝트를 실행하고 페이지가 올바르게 렌더링되는지 확인한 후 서버를 중지합니다.

  8. 필요하다면 2-2단계에 설명된 대로 변경 내용을 소스 제어에 커밋하고 원격 리포지토리를 업데이트합니다.

질문: 페이지 템플릿은 별도의 파일에 있어야 하나요?

답변: 일반적으로 템플릿은 별도의 HTML 파일에서 유지 관리됩니다. 인라인 템플릿을 사용할 수도 있습니다. 태그와 코드를 명확하게 분리하려면 별도의 파일을 사용하는 것이 좋습니다.

질문: 템플릿은 .html 파일 확장명을 사용해야 하나요?

대답: render 함수에 대한 두 번째 인수에서 파일의 정확한 상대 경로를 식별하므로 페이지 템플릿 파일의 .html 확장명은 전적으로 선택 사항입니다. 그러나 Visual Studio(및 기타 편집기)는 .html 파일을 사용하여 코드 완성 및 구문 색 지정과 같은 기능을 제공하는데, 이는 페이지 템플릿이 엄격하게 HTML이 아니라는 사실보다 중요합니다.

실제로 Django 프로젝트로 작업할 때 Visual Studio는 HTML 파일이 Django 템플릿을 포함하고 있음을 자동으로 감지하고 특정 자동 완성 기능을 제공합니다. 예를 들어 Django 페이지 템플릿 주석 {#을 입력하기 시작하면 Visual Studio에서 닫는 #} 문자를 자동으로 제공합니다. Comment Selection(선택 영역을 주석으로 처리)Uncomment Selection(선택 영역의 주석 처리 제거) 명령(편집>고급 메뉴 및 도구 모음)에서도 HTML 주석 대신 템플릿 주석을 사용합니다.

질문: 프로젝트를 실행하면 템플릿을 찾을 수 없다는 오류가 표시됩니다. 무엇이 문제인가요?

대답: 템플릿을 찾을 수 없다는 오류가 표시되면 INSTALLED_APPS 목록에서 Django 프로젝트의 settings.py에 앱을 추가했는지 확인하세요. 해당 항목이 없으면 Django에서는 앱의 templates 폴더에서 무엇을 찾을지 알 수 없습니다.

질문: 템플릿 네임스페이스 지정이 중요한 이유는 무엇인가요?

대답: Django가 render 함수에서 참조된 템플릿을 찾는 경우 상대 경로와 일치하는 첫 번째 파일을 사용합니다. 템플릿에 동일한 폴더 구조를 사용하는 동일한 프로젝트에 여러 Django 앱이 있는 경우, 자칫하면 한 앱에서 다른 앱의 템플릿을 실수로 사용할 수 있습니다. 이러한 오류를 방지하려면 항상 앱의 이름과 일치하는 앱의 templates 폴더 아래에 하위 폴더를 만들어 중복을 방지하세요.

다음 단계

자세히 알아보기