본문 바로가기
Web Programming/django

[Django] 템플릿 확장

by 테리는당근을좋아해 2020. 6. 22.

목표

- 템플릿 확장을 통해 html 코드 작성을 간결하게 한다.

 

 

html 코드의 중복

html 코드를 작성하다보면, html 파일 마다 html 태그, head 태그, nav bar 등 중복되는 코드가 발생한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</head>
<body>
    {% load static %}
    <ul class="nav">
        <li class="nav-item">
            <a class="nav-link active" href="#"><img src="{% static 'img/django.png'%}" width="20" alt=""></a>
        </li>

        {% if user.is_authenticated %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'create' %}">새 글쓰기</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" >{{user.username}}</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="{% url 'logout' %}">로그아웃</a>
            </li>
        {% else %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'signup' %}">회원가입</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="{% url 'login' %}">로그인</a>
            </li>
        {% endif %}
      </ul>
      
 ...

 

이러한 소스 코드의 중복은 번거로울 뿐만 아니라 가독성마저 떨어뜨리게 된다.

Django에서는 템플릿 확장을 통해 이러한 문제점을 해결할 수 있다.

 

하나의 중복된 코드를 저장해두는 base.html을 만들고, 그 안에 담겨져야할 다른 html 코드에 적용한다.

 

 

base.html 생성

프로젝트 내에 templates 디렉터리를 하나 생성하고 그 안에 base.html 파일을 생성한다.

 

base.html 내에 중복되는 소스 코드들과 다른 소스 코드의 내용이 들어갈 '{% block content %} ... {% endblock %}' 템플릿 태그를 작성한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</head>
<body>
    {% load static %}
    <ul class="nav">
        <li class="nav-item">
            <a class="nav-link active" href="#"><img src="{% static 'img/django.png'%}" width="20" alt=""></a>
        </li>

        {% if user.is_authenticated %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'create' %}">새 글쓰기</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" >{{user.username}}</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="{% url 'logout' %}">로그아웃</a>
            </li>
        {% else %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'signup' %}">회원가입</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="{% url 'login' %}">로그인</a>
            </li>
        {% endif %}
    </ul>

    {% block content %}
    {% endblock %}
</body>
</html>

 

 

settings.py 수정

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

settings.py 에서 TEMPLATES 리스트 내의 'DIRS' 의 value로 'os.path.join(BASE_DIR, 'templates')],'를 작성한다.

 

 

템플리 확장

다른 html 코드에 base.html에 작성한 중복된 코드를 모두 제거하고, 각각의 html 파일에 필요한 소스코드만 '{% extends 'base.html %} {% block content %} ... {% endblock %}' 템플릿 태그로 감싸고 작성한다.

 

index.html

{% extends 'base.html' %}
{% block content %}
    {% for post in posts %}
        <div class="card w-75">
            <div class="card-body">
                <h5 class="card-title">{{post.title}}</h5>
                <p class="card-text">{{post.pub_date }}</p>
                <p class="card-text">{{post.user.username}}</p>
                <a href="{% url 'detail' post.id %}" class="btn btn-primary">자세히 보기</a>
            </div>
        </div>
    {% endfor %}
{% endblock content %}

 

index.html에 html 태그나 nav bar에 대한 소스코드가 없어도 템플릿 확장을 통해 적용된 것을 확인할 수 있다.

'Web Programming > django' 카테고리의 다른 글

[Django] Model기반 form 형식 지정  (0) 2020.06.22
[Django] 페이지네이션  (0) 2020.06.22
[Django] 부트스트랩  (0) 2020.06.22
[Django] URL 관리  (0) 2020.06.22
[Django] 이미지 업로드  (13) 2020.06.21

댓글