본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

Backend

Django Template과 Static 파일

작성 2026. 10. 13.추가
목차8개 항목

Django 템플릿은 표현(presentation)을 위한 도구다. 조건·반복 같은 구조를 쓸 수 있지만 Python 코드가 실행되는 것이 아니며, 로직은 view에 두고 템플릿은 보여 주는 일에만 집중하도록 설계되었다(표현과 로직의 분리, 중복 배제).

DTL(Django Template Language) 문법

문법형태설명
Variable{{ variable }}view의 context로 넘긴 값 출력. .으로 속성 접근({{ article.title }}). 밑줄로 시작하거나 공백·구두점 포함 불가
Filter{{ variable|filter }}출력 값 변형. 예: {{ name|lower }}, {{ content|truncatechars:20 }}
Tag{% tag %}반복·조건 등 제어 흐름. 일부는 {% endtag %}로 닫음
Comment{# 주석 #}한 줄 주석 (여러 줄은 {% comment %})
{% for article in articles %}
  <p>{{ forloop.counter }}. {{ article.title|upper }}</p>
{% empty %}
  <p>글이 없습니다.</p>
{% endfor %}
 
{% if user.is_authenticated %}안녕하세요, {{ user.username }}님{% endif %}

커스텀 템플릿 필터

내장 필터로 부족하면 앱 안에 templatetags/ 폴더(이름 고정, __init__.py 필요)를 만들어 직접 등록한다. 예를 들어 M:N 장르 목록을 액션, 드라마처럼 한 줄로 보여 주는 필터다.

# movies/templatetags/movie_filters.py
from django import template
 
register = template.Library()
 
@register.filter
def make_genre_list(genres):
    return ', '.join(genre.name for genre in genres)
{% load movie_filters %}
<p>Genre: {{ movie.genres.all|make_genre_list }}</p>
  • 모듈은 위치와 무관하게 파일 이름으로 {% load %}되므로 다른 앱의 모듈과 이름이 겹치지 않게 짓는다.
  • 처음 만든 뒤에는 개발 서버를 재시작해야 인식된다.

템플릿 상속

공통 레이아웃(헤더, 네비게이션, 푸터)을 base.html 하나에 두고, 자식 템플릿은 바뀌는 블록만 채운다.

<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
  <title>{% block title %}My Site{% endblock title %}</title>
  {% block css %}{% endblock css %}
</head>
<body>
  {% block content %}{% endblock content %}
</body>
</html>
<!-- articles/templates/articles/index.html -->
{% extends 'base.html' %}
 
{% block title %}행운로또{% endblock title %}
 
{% block content %}
  <h1>로또 번호입니다.</h1>
  <h2>{{ lotto }}</h2>
{% endblock content %}
  • {% extends %}는 템플릿의 첫 번째 태그여야 하며 한 번만 쓸 수 있다.
  • {% block %}은 자식이 덮어쓸(override) 수 있는 공간이다. 가독성을 위해 endblock에도 이름을 붙일 수 있다.
  • 앱 밖(프로젝트 루트)의 templates/를 쓰려면 경로를 추가한다.
# settings.py
TEMPLATES = [{
    ...,
    'DIRS': [BASE_DIR / 'templates'],
    'APP_DIRS': True,   # 각 앱의 templates/ 도 검색
}]

form으로 데이터 주고받기

<form>의 action(URL)·method·<input name>으로 데이터를 보내고, view는 request.GET/request.POST로 꺼낸다. 생성·수정은 POST + {% csrf_token %}으로 보내며, 입력 검증까지 포함한 흐름은 Django Form과 ModelForm에 있다.

Static files

이미지·CSS·JS처럼 요청에 따라 바뀌지 않고 그대로 제공되는 파일이다.

설정과 사용

  1. django.contrib.staticfiles가 INSTALLED_APPS에 있는지 확인
  2. settings.py에 STATIC_URL 정의
  3. 앱의 static/ 폴더에 파일 저장 (예: articles/static/articles/sample.png. 템플릿처럼 앱 이름 폴더를 한 번 더 둔다)
  4. 템플릿에서 {% load static %} 후 {% static '경로' %}로 URL 생성
{% extends 'base.html' %}
{% load static %}
 
{% block css %}
  <link rel="stylesheet" href="{% static 'style.css' %}">
{% endblock css %}
 
{% block content %}
  <img src="{% static 'articles/sample.png' %}" alt="sample">
{% endblock content %}

관련 설정

설정의미
STATIC_URL정적 파일을 참조할 때 쓰는 URL 접두사(예: 'static/'). 실제 폴더가 아니라 URL로만 존재
STATICFILES_DIRS앱의 static/ 외에 추가로 탐색할 폴더 목록. 예: [BASE_DIR / 'static']
STATIC_ROOT배포 시 python manage.py collectstatic이 모든 정적 파일을 모아 둘 절대 경로. 운영에서는 Nginx 같은 웹 서버가 이 폴더를 직접 서빙
  • 개발 중(DEBUG = True)에는 runserver가 앱의 static/과 STATICFILES_DIRS를 자동으로 서빙하며 STATIC_ROOT는 쓰이지 않는다.

핵심 정리

  • {{ }} 출력, | 필터(부족하면 templatetags로 직접 등록), {% %} 태그, {# #} 주석.
  • base.html + {% extends %} + {% block %}으로 중복 레이아웃을 제거한다.
  • 정적 파일은 {% load static %} + {% static %}, 배포 땐 collectstatic.

댓글

GitHub 계정으로 댓글을 남길 수 있어요.