이 포스트는 코드잇 Django 웹 개발 시작하기 3장 강의을 바탕으로 작성하였습니다 :)
https://www.codeit.kr/topics/getting-started-with-django
Django 웹 개발 시작하기 - Django 강의 | 코드잇
Django는 파이썬을 기반으로 하는 웹 개발 프레임워크입니다. Django에는 회원가입, 로그인, 검색 같이 웹 서비스에서 주로 사용되는 여러 기능들이 이미 만들어져 있어서 원하는 걸 그냥 갖다 쓰면
www.codeit.kr
** 정적 (static) 파일 관리하기
- 정적 파일 (static files)
웹 페이지를 렌더링(Rendering)하는 과정에서 필요한 추가적인 파일
ex) css, js, png, font
- 정적 파일 디렉토리 구조 설정


- 정적 파일 사용하기
* 템플릿 태그
위에서 만든 static에 있는 정적 파일을 현재 이 템플릿 파일에서 사용한다고 알려주는 태그이다.
{% load static %}
foods > templates > foods > index.html 에 위치한 파일에서 위 템플릿 태그를 명시하기 전에는

이런 식으로 화면이 구현된다.
정적 파일을 사용하기 위해 {% load static %}와 css href를 아래와 같은 템플릿 태그로 수정하면
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>코스토랑</title>
<meta charset="utf-8">
<link rel="stylesheet" href={% static 'foods/css/styles.css' %}>
</head>

css 정적 파일이 적용되는 것을 확인할 수 있다
이미지 파일을 적용하기 위해서
<img> 태그의 src를 아래와 같이 수정하면
<div class="food-container">
<div class="food">
<img src={% static 'foods/images/chicken.jpg' %} width="300px" height="200px"/>
<div class="info">
<h3>코딩에 빠진 닭</h3>
<P>주머니가 가벼운 당신의 마음까지 생각한 가격!</p>
<a href="#">메뉴 보기</a>
</div>
</div>

이미지 파일이 적용되는 것을 확인할 수 있다.
** Template과 static의 폴더 구조
프로젝트 앱의 settings.py 파일 부분을 보면
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
다음과 같이 APP_DIRS 부분을 확인할 수 있다.
APP_DIRS 항목이 True로 표시되어 있는데
이는 각각의 앱에 templates 디렉토리가 있기 때문에, templates을 찾을 때 그 디렉토리에서 찾아라는 것을 의미한다.
index.html 템플릿을 찾기 위해서는 foods 앱에 있는 templates 디렉토리에 가야한다는 말이다.
foods>templates>foods>index.html
이때 장고는 템플릿을 찾기 위해
프로젝트 앱의 settings.py 파일에 있는 아래의 코드 내용과 같이
등록된 앱의 순서대로 각각의 템플릿을 찾으려고 한다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'foods',
'menus',
]
만일 foods>templates>foods>index.html 와 같이
"샌드위치 구조"를 적용하지 않고 각각의 앱에 동일한 템플릿이 있다면,
항상 위에 등록되어 있는 앱의 템플릿이 적용된다.
foods앱과 menus앱에 샌드위치 구조 없이 모두 동일한 index.html 템플릿을 가지고 있다면,
각각의 index.html 파일의 내용이 다르더라도 항상 foods 앱에 해당하는 index.html 파일이 적용된다는 의미이다.
템플릿 이름이 겹치는 문제를 해결하기 위해서는
템플릿 디렉토리 안에 바로 index.html 파일을 두는 것이 아니라
디렉토리와 템플릿 사이에 앱 이름과 동일한 디렉토리를 생성하여
foods>templates>foods>index.html 와 같이 표현해야한다.
** Template Language
ㅇ 템플릿 언어
템플릿 언어는 크게 4가지로 구분할 수 있다.
템플릿 변수는 우리가 지정한 데이터로 변환하는 기능을 한다.
템블릿 태그는 템플릿 작성에 로직을 사용하는 것이며,
템플릿 필터는 템플릿 변수를 특정 형식으로 변환하는 것이고,
마지막 템플릿 주석은 템플릿 언어의 주석처리를 담당하는 것이다.
ㅇ 템플릿 변수
템플릿이 렌더될 때 해당 변수가 의미하는 값으로 변환된다.
view에서 넘겨 받은 데이터를 템플릿 변수를 사용하여 넘겨받은 데이터에 접근할 수 있다.
** 기본형
{{ 변수명. 속성 }}

ㅇ 템플릿 필터
템플릿 변수를 특정 형식으로 변환
** 기본형
{{변수명 | 필터}}
ex) {{ codeit | upper }} -> codeit : "good" 이 upper 필터로 인해 GOOD 으로 출력
추가적인 템플릿 필터에 대한 정보는 아래 사이트를 참고하길 바란다.
https://docs.djangoproject.com/en/2.2/ref/templates/builtins/#ref-templates-builtins-filters
ㅇ 템플릿 태그
{% 태그 %} {% end태그 %}
ex) {% for %}, {% endfor %} -> 반복
{% if %}, {% else %}, {% endif %} -> 조건
{% block %}, {% endblock %} -> 상속
ㅇ 템플릿 주석
{# 주석 #}
** 코스토랑 메인 페이지 만들기 실습

다음과 같은 index.html 템플릿 파일에 css, jpg와 같은 정적 파일을 적용시키기 위해
아래와 같이 코드를 수정해보았다.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>코스토랑</title>
<meta charset="utf-8">
<link rel="stylesheet" href={% static 'menus/css/styles.css' %} <!-- [B] 정적 경로로 변경해 주어야 합니다.-->
<link rel="stylesheet" type="text/css"
href="https://cdn.rawgit.com/moonspam/NanumSquare/master/nanumsquare.css">
</head>
<body>
<div id="header">
<div class="container">
<div class="nav">
<a href="index.html"><img src={% static 'menus/images/logo-color.svg' %}></a> <!-- [C] 정적 경로로 변경해 주어야 합니다.-->
</div>
<div class="header_txt">
<p>오늘도<b>신선한재료</b>로만든요리</p>
<h1><img src={% static 'menus/images/header-txt.svg' %} style="width:330px; height:89px;"></h1> <!-- [D] 정적 경로로 변경해 주어야 합니다.-->
</div>
</div>
</div>
<div id="content">
<div class="container">
<div class="content_txt">
<h2>오늘의 메뉴</h2>
<p class="date-text"> July 16, 2020 </p>
</div>
<div class="food_container">
<div class="food">
<img src={% static 'menus/images/chicken.jpg' %}/> <!-- [E] 정적 경로로 변경해 주어야 합니다.-->
<div class="info">
<h3>코딩에 빠진 닭</h3>
<p>지금까지 이런 맛은 없었다. 이것은 갈비인가 통닭인가 </p>
<a href="#">메뉴 보기</a>
</div>
</div>
</div>
</div>
<div id="footer">
<div class="container">
<div class="footer">
<img src={% static 'menus/images/logo-gray.svg' %}> <!-- [F] 정적 경로로 변경해 주어야 합니다.-->
</div>
</div>
</div>
</body>
</html>

완성 !
** 중복되는 템플릿 코드 없애기
디장고는 "템플릿 상속"을 통해 코드의 중복을 막는다.
템플릿 상속은,
여러 자식 파일의 공통적인 부분을 부모 파일로 모아서 사용하고
자식 파일은 부모 파일로부터 공통 부분을 상속받고, 달라지는 부분만 코드로 작성하는 것을 의미한다.
상속은 주로
템플릿 태그 {% block %}과 {% extends %}를 사용하여 구현한다.

templates>foods 디렉토리에 base.html을 만들어 이를 부모 템플릿으로 사용한다.
기존에 만들었던 index.html 파일 코드를 복사하여 base.html에 붙여 기본 틀을 만들어 준다.
부모 템플릿은
공통적으로 변경되는 부분은 블록으로 만들고, 변경되지 않은 부분은 남겨두면 된다.
base.html 파일의 food-container class에 있는 내용을 전부 지우고
<div class="food-container">
{% block food-container %}
{% endblock food-container %}
</div>
위 코드처럼 공통된 부분은 템플릿 태그를 사용해 자식 파일에 상속할 수 있게끔 만든다.
기존에 만들어 두었던 index.html 파일은 자식 템플릿으로 사용한다.

어떤 템플릿을 부모 템플릿으로 사용하는지 명시해주기 위해 다음과 같은 코드를 사용한다.
{ % extends '부모 템플릿' %} 은 가장 첫 줄에 기입하는 것이 중요하다 !!
{% extends '부모 템플릿' %} # 기본형
{% extends './base.html' %}
자식 템플릿에서도 정적 파일에 접근하기 때문에 이 코드를 사용한다.
{% load static %}
부모 템플릿에서 자식 템플릿에 구현할 부분을 블록으로 처리했었는데,
자식 템플릿은 그 블록에 있는 내용을 다음과 같이 블록 안쪽에 함께 채우면 된다.
{% block date-block %}
<div>26 Jan, 2024</div>
{% endblock date-block %}

'Framework > Django' 카테고리의 다른 글
| [ Django 웹 개발 시작하기 ] 2장. Django 구조 이해하기 (2) | 2024.01.05 |
|---|