다음을 통해 공유


3단계: Django 앱을 사용하여 정적 파일 제공, 페이지 추가 및 템플릿 상속 사용

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

자습서의 이전 단계에서는 단일 HTML 페이지로 최소 Django 앱을 만드는 방법을 학습했습니다. 그러나 최신 웹앱에는 많은 페이지가 포함되어 있습니다. 최신 웹 페이지는 CSS와 JavaScript 파일 같은 공유 리소스를 사용하여 일관된 스타일과 동작을 제공합니다.

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

  • Visual Studio 항목 템플릿을 사용하여 편리한 상용구 코드로 신속하게 다양한 형식의 새 파일 추가(3-1단계)
  • 정적 파일을 제공하도록 Django 프로젝트 설정(3-2단계)
  • 앱에 페이지 추가(3-3단계)
  • 템플릿 상속을 사용하여 전체 페이지에서 사용되는 헤더 및 탐색 모음 만들기(3-4단계)

3-1단계: 항목 템플릿 익히기

Django 앱을 개발하는 경우 일반적으로 많은 Python, HTML, CSS 및 JavaScript 파일을 추가합니다. 각 파일 형식(배포에 필요할 수 있는 web.config와 같은 파일)에 대해 Visual Studio는 시작하는 데 도움이 되는 편리한 항목 템플릿을 제공합니다.

사용 가능한 템플릿을 보려면 솔루션 탐색기로 이동하여 항목을 만들 폴더를 마우스 오른쪽 단추로 클릭한 다음 추가>새 항목을 선택합니다.

Add new item dialog in Visual Studio.

템플릿을 사용하려면 원하는 템플릿을 선택하고 파일 이름을 지정한 다음 추가를 선택합니다. 이런 방식으로 항목을 추가하면 파일이 Visual Studio 프로젝트에 자동으로 추가되고 소스 제어에 대한 변경 내용이 표시됩니다.

질문: Visual Studio에서는 제공할 항목 템플릿을 어떻게 알 수 있나요?

대답: Visual Studio 프로젝트 파일( .pyproj)에는 Python 프로젝트로 표시하는 프로젝트 형식 식별자가 포함되어 있습니다. Visual Studio에서는 형식 식별자를 사용하여 프로젝트 형식에 적합한 항목 템플릿만 표시합니다. 이런 방식으로 Visual Studio에서는 매번 정렬 여부를 묻는 메시지를 표시하지 않고 여러 프로젝트 형식에 대해 다양한 항목 템플릿을 제공할 수 있습니다.

3-2단계: 앱에서 정적 파일 제공

Python(모든 프레임워크 사용)으로 빌드된 웹앱에서 Python 파일은 항상 웹 호스트의 서버에서 실행됩니다. 또한 Python 파일은 사용자의 컴퓨터로 전송되지 않습니다. CSS 및 JavaScript 같은 다른 파일은 브라우저에서만 사용합니다. 따라서 호스트 서버는 요청이 있을 때마다 이러한 파일을 있는 그대로 전달합니다. 이러한 파일을 “정적” 파일이라고 하며 Django에서는 코드를 작성할 필요 없이 이러한 파일을 자동으로 제공할 수 있습니다.

Django 프로젝트는 Django 프로젝트의 settings.py 파일에 있는 다음 줄 덕분에 앱의 static 폴더에서 정적 파일을 제공하도록 기본적으로 설정되어 있습니다.

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/

STATIC_URL = '/static/'

STATIC_ROOT = posixpath.join(*(BASE_DIR.split(os.path.sep) + ['static']))

원하는 폴더 구조를 사용하여 static 내에서 파일을 구성한 다음, 해당 폴더 내의 상대 경로를 사용하여 파일을 참조할 수 있습니다. 이 프로세스를 보여주기 위해 아래 단계에 따라 앱에 CSS 파일을 추가한 다음, index.html 템플릿에서 해당 스타일시트를 사용합니다.

  1. 솔루션 탐색기에서 Visual Studio 프로젝트의 HelloDjangoApp 폴더를 마우스 오른쪽 단추로 클릭하고, 추가>새 폴더를 선택하고, 폴더의 이름을 static으로 지정합니다.

  2. static 폴더를 마우스 오른쪽 단추로 클릭하고 추가>새 항목을 선택합니다. 대화 상자가 표시되면 스타일시트 템플릿을 선택하고 파일의 이름을 site.css로 지정하고 추가를 선택합니다.

    Add new item dialog for static file.

    site.css 파일이 프로젝트에 표시되고 편집기에서 열립니다. 폴더 구조는 아래 이미지와 유사합니다.

    Static file structure as shown in Solution Explorer.

  3. site.css 파일의 내용을 다음 코드로 바꾸고 파일을 저장합니다.

    .message {
        font-weight: 600;
        color: blue;
    }
    
  4. 앱의 templates/HelloDjangoApp/index.html 파일의 내용을 다음 코드로 바꿉니다. 이 코드는 2단계에서 사용한 <strong> 요소를 message 스타일 클래스를 참조하는 <span>로 교체합니다. 스타일 클래스를 사용하면 더 유연하게 요소의 스타일을 지정할 수 있습니다. VS 2017 15.7 이전을 사용할 때 index.html 파일을 templates의 하위 폴더로 이동하지 않은 경우 2-4단계의 템플릿 네임스페이스 지정을 참조하세요.

    <html>
        <head>
            <title>{{ title }}</title>
            {% load static %} <!-- Instruct Django to load static files -->
            <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
        </head>
        <body>
            <span class="message">{{ message }}</span>{{ content }}
        </body>
    </html>
    
  5. 프로젝트를 실행하여 결과를 확인합니다. 완료되면 서버를 중지하고, 원하는 경우 소스 제어에 변경 내용을 커밋합니다(자세한 내용은 2단계 참조).

질문: {% load stati %} 태그의 용도는 무엇인가요?

대답: {% load static %} 줄은 <head><body> 같은 요소에서 정적 파일을 참조하기 전에 필요합니다. 이 섹션에 표시된 예제에서 “staticfiles”는 사용자 지정 Django 템플릿 태그 집합을 참조하며, {% static %} 구문을 사용하여 정적 파일을 참조할 수 있게 합니다. {% load static %}가 없으면 앱이 실행될 때 예외가 표시됩니다.

질문: 정적 파일 구성에 대한 규칙이 있나요?

대답: 원하는 방식으로 static 폴더에서 다른 CSS, JavaScript 및 HTML 파일을 추가할 수 있습니다. 일반적으로 정적 파일을 구성하려면 스타일시트 및 다른 모든 파일에 대해 fonts, scriptscontent라는 하위 폴더를 만듭니다. 각각의 경우 {% static %} 참조의 상대 파일 경로에 해당 폴더를 포함해야 합니다.

질문: {% load static %} 태그를 사용하지 않고 동일한 작업을 완료할 수 있나요?

대답: 예, 가능합니다.

<html>
    <head>
        <title>{{ title }}</title>
        <link rel="stylesheet" type="text/css" href="../../static/site.css" />
    </head>
    <body>
        <span class="message">{{ message }}</span>{{ content }}
    </body>
</html>

3-3단계: 앱에 페이지 추가

앱에 다른 페이지를 추가하면 다음과 같은 작업이 진행됩니다.

  • 보기를 정의하는 Python 함수를 추가합니다.
  • 페이지의 태그에 대한 템플릿을 추가합니다.
  • Django 프로젝트의 urls.py 파일에 필요한 라우팅을 추가합니다.

다음 단계에서는 “HelloDjangoApp” 프로젝트에 “About” 페이지를 추가하고 홈페이지에서 이 페이지에 연결합니다.

  1. 솔루션 탐색기에서 templates/HelloDjangoApp 폴더를 마우스 오른쪽 단추로 클릭합니다. 추가>새 항목을 선택하고 HTML 페이지 항목 템플릿을 선택합니다. 파일 이름을 about.html으로 지정하고 추가를 선택합니다.

    Add new item dialog for about file.

    새 항목 명령이 추가 메뉴에 나타나지 않으면 Visual Studio가 디버깅 모드를 종료하도록 서버를 중지했는지 확인하세요.

  2. about.html의 내용을 아래 태그로 바꿉니다. 홈페이지에 대한 명시적 링크를 3-4단계의 간단한 탐색 모음으로 바꿉니다.

    <html>
        <head>
            <title>{{ title }}</title>
            {% load static %}
            <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
        </head>
        <body>
            <div><a href="home">Home</a></div>
            {{ content }}
        </body>
    </html>
    
  3. 앱의 views.py 파일을 열고 템플릿을 사용하는 about이라는 함수를 추가합니다.

    def about(request):
        return render(
            request,
            "HelloDjangoApp/about.html",
            {
                'title' : "About HelloDjangoApp",
                'content' : "Example app page for Django."
            }
        )
    
  4. Django 프로젝트의 urls.py 파일을 열고 다음 줄을 urlPatterns 배열에 추가합니다.

    re_path(r'^about$', HelloDjangoApp.views.about, name='about'),
    
  5. templates/HelloDjangoApp/index.html 파일을 열고 <body> 요소 아래에서 다음 줄을 추가하여 About 페이지에 연결합니다. 이 링크는 3-4단계에서 탐색 모음으로 다시 바꿉니다.

    <div><a href="about">About</a></div>
    
  6. 파일>모두 저장 메뉴 명령을 사용하여 모든 파일을 저장하거나, Ctrl+Shift+S를 누르기만 하면 됩니다. (Visual Studio에서 실행하는 프로젝트는 파일을 자동으로 저장하기 때문에 이 단계는 엄밀히 말하면 필요하지 않습니다. 하지만 알아두면 좋은 명령입니다.)

  7. 프로젝트를 실행하여 결과를 확인하고 페이지 간 탐색을 확인합니다. 완료되면 서버를 닫습니다.

대답: views.py 파일의 보기 함수 이름이 index인 경우에도 Django 프로젝트의 urls.py 파일에 있는 URL 라우팅 패턴에는 문자열 "ndex"와 일치하는 정규식이 포함되지 않습니다. 문자열과 일치하려면 ^index$ 패턴에 대한 다른 항목을 추가해야 합니다.

다음 섹션에 표시된 대로 페이지 템플릿에서 {% url '<pattern_name>' %} 태그를 사용하여 패턴의 name을 참조하는 것이 더 좋습니다. 이 경우 Django에서 적절한 URL을 대신 만듭니다. 예를 들어 about.html<div><a href="home">Home</a></div><div><a href="{% url 'index' %}">Home</a></div>으로 바꿉니다. 여기서는 urls.py의 첫 번째 URL 패턴 이름이 실제로 'index'(name='index' 인수 사용)이기 때문에 'index'를 사용합니다. 또한 ‘home’을 사용하여 두 번째 패턴을 참조할 수도 있습니다.

3-4단계: 템플릿 상속을 사용하여 헤더 및 탐색 모음 만들기

최신 웹앱은 각 페이지에 명시적 링크를 남기는 대신 브랜딩 헤더와 탐색 모음을 사용합니다. 탐색 모음은 가장 중요한 페이지 링크와 팝업 메뉴 등을 제공합니다. 헤더 및 탐색 모음을 모든 페이지에서 동일하게 표시하기 위해, 모든 페이지 템플릿에서 동일한 코드를 반복하지 마세요. 대신 모든 페이지에서 공통되는 부분을 한 곳에서 정의하려고 합니다.

Django의 템플릿 시스템은 여러 템플릿에서 특정 요소를 다시 사용할 수 있는 두 가지 방법(포함과 상속)을 제공합니다.

  • ‘포함’은 {% include <template_path> %} 구문을 사용하여 참조 템플릿의 특정 위치에 삽입하는 다른 페이지 템플릿입니다. 코드에서 동적으로 경로를 변경하려는 경우 변수를 사용할 수도 있습니다. 포함은 페이지의 특정 위치에서 공유 템플릿을 풀하기 위해 페이지 본문에 사용됩니다.

  • ‘상속’은 페이지 템플릿 시작 부분에서 {% extends <template_path> %}를 사용하여 참조 템플릿의 기반이 되는 공유 기본 템플릿을 지정합니다. 일반적으로 상속은 공유 레이아웃, 탐색 모음 및 기타 앱 페이지 구조를 정의하는 데 사용되므로, 참조 템플릿에서는 블록이라는 기본 템플릿의 특정 영역을 추가하거나 수정할 수만 있습니다.

두 경우 모두 <template_path>는 앱의 templates 폴더(../ 또는 ./도 허용됨)에 대해 상대적입니다.

기본 템플릿은 {% block <block_name> %}{% endblock %} 태그를 사용하여 블록을 나타냅니다. 참조 템플릿에서 블록 이름이 같은 태그를 사용하는 경우 해당 블록 콘텐츠가 기본 템플릿의 콘텐츠를 재정의합니다.

다음 단계에서는 상속을 보여줍니다.

  1. 앱의 templates/HelloDjangoApp 폴더에서 새 HTML 파일을 만듭니다. templates/HelloDjangoApp 폴더를 마우스 오른쪽 단추로 클릭하고, 추가>새 항목을 선택한 다음 HTML 페이지 항목 템플릿을 선택합니다. 파일 이름을 layout.html으로 지정하고 추가를 선택합니다.

    Add new item dialog for layout file.

  2. layout.html 파일의 내용을 아래 태그로 바꿉니다. 참조 페이지에서 바꿔야 하는 “content”라는 블록이 이 템플릿에 포함되어 있음을 알 수 있습니다.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title>{{ title }}</title>
        {% load static %}
        <link rel="stylesheet" type="text/css" href="{% static 'site.css' %}" />
    </head>
    
    <body>
        <div class="navbar">
           <a href="/" class="navbar-brand">Hello Django</a>
           <a href="{% url 'home' %}" class="navbar-item">Home</a>
           <a href="{% url 'about' %}" class="navbar-item">About</a>
        </div>
    
        <div class="body-content">
    {% block content %}{% endblock %}
            <hr/>
            <footer>
                <p>&copy; 2018</p>
            </footer>
        </div>
    </body>
    </html>
    
  3. 앱의 static/site.css 파일에 다음 스타일을 추가합니다. 이 연습에서는 반응이 빠른 디자인을 보여주려는 것이 아니며, 이러한 스타일은 단순히 흥미로운 결과를 생성하기 위한 것입니다.

    .navbar {
        background-color: lightslategray;
        font-size: 1em;
        font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
        color: white;
        padding: 8px 5px 8px 5px;
    }
    
    .navbar a {
        text-decoration: none;
        color: inherit;
    }
    
    .navbar-brand {
        font-size: 1.2em;
        font-weight: 600;
    }
    
    .navbar-item {
        font-variant: small-caps;
        margin-left: 30px;
    }
    
    .body-content {
        padding: 5px;
        font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    }
    
  4. 기본 템플릿을 참조하고 페이지 내에서 사용할 수 있도록 templates/HelloDjangoApp/index.html 파일을 수정합니다. 다음 줄을 HTML 페이지에 줄 1로 추가합니다(html 태그 위).

    {% extends "HelloDjangoApp/layout.html" %}
    
  5. 상속을 사용하면 이 템플릿을 본문 태그 내에서 간단하게 구현하여 콘텐츠 블록을 재정의할 수 있습니다.

    {% block content %}
    <span class="message">{{ message }}</span>{{ content }}
    {% endblock %}
    
  6. 레이아웃 템플릿을 사용할 수 있도록 templates/HelloDjangoApp/about.html 파일을 동일한 방식으로 수정합니다. 1단계와 동일한 줄을 HTML 페이지에 추가합니다(html 태그 위).

    {% extends "HelloDjangoApp/layout.html" %}
    
  7. 그런 다음 상속을 사용하여 본문 태그 내에 템플릿을 구현하여 콘텐츠 블록을 재정의합니다.

    {% block content %}
    {{ content }}
    {% endblock %}
    
  8. 서버를 실행하여 결과를 확인합니다. 완료되면 서버를 닫습니다.

    Running app showing the nav bar.

  9. 앱이 많이 변경되었으므로 다시 소스 제어에 변경 내용을 커밋하는 것이 좋습니다.

다음 단계

자세히 알아보기