현재 폴더 구조
장고/monthly_challenges/monthly_challenges/setting.py 수정
.
.
.
.
INSTALLED_APPS = [
'challenges', #여기 추가
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
.
.
.
.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR / "templates"
],
'APP_DIRS': True, #여기도 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 파일에서 주석으로 표시 된 부분 설정!!
challlenges/urls.py 에서 다음과 같은 코드를 실행
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
from django.urls import reverse
from django.template.loader import render_to_string
def monthly_challenge(request, month):
try:
challenge_text = monthly_challenges[month]
response_data = render_to_string("challenges/challenge.html")
return HttpResponse(response_data)
except:
return HttpResponseNotFound("<h1>This month is not supported</h1>")
1. render_to_string 의 인자로 "challenges/challenge.html" 전달
2. 위의 urls.py 는 challenges 폴더에 속해있음으로 challenges/templates 안에서 "challenges/challenge.html" 을 자동으로 검색함
3. 우리가 setting.py 의 INSTALLED_APPS 에 "challenges" 를 추가해주었기 때문에 가능한 일이다!
위의 코드를 아래로 축약 가능
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
from django.urls import reverse
def monthly_challenge(request, month):
try:
challenge_text = monthly_challenges[month]
return render(request, "challenges/challenge.html",{
"text": challenge_text,
"month_name": month.capitalize(),
})
except:
return HttpResponseNotFound("<h1>This month is not supported</h1>")
render 는 request 와 템플릿 path, 그리고 뷰에 전달할 인자를 받는다
challenges.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ month_name }} Challenge</title>
</head>
<body>
<h1>{{ month_name }} Challenge</h1>
<h2>{{text}}</h2>
</body>
</html>
urls.py 에서 전달한 text와 month_name 을 다이나믹 렌더링으로 서빙한다.
for 태그 사용법
challenges/views 를 다음과 같이 수정
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseNotFound, HttpResponseRedirect
from django.urls import reverse
def index(request):
months = list(monthly_challenges.keys())
return render(request, "challenges/index.html", {
"months": months,
})
render 의 세번쨰 인수로 "month" 배열을 넘겨줌
index.html 은 다음과 같이 수정
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>All challenges</title>
</head>
<body>
<ul>
{% for month in months %}
<li><a href="/challenges/{{month}}">{{ month|title}}</a></li>
{% endfor %}
</ul>
</body>
</html>
for 태그를 이용해 반복 렌더링
url 태그 사용법
우리는 이전에 challenges/urls.py 에서 "month-challenge" 라는 url 을 등록해두었다.
challenges/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('<int:month>', views.monthly_challenge_by_number),
path('<str:month>', views.monthly_challenge, name="month-challenge")
]
이 등록해둔 url 을 장고 html에서 꺼내서 쓸 수 있다.
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>All challenges</title>
</head>
<body>
<ul>
{% for month in months %}
<li><a href="{% url 'month-challenge' month %}">{{ month|title}}</a></li>
{% endfor %}
</ul>
</body>
</html>
'month-challenge' 로 등록해둔 url 을 가져오고 pathVarible 엔 month 를 삽입하여 href 를 동적으로 생성하고있다.
if 태그 사용하기
challenge.html 다음과 같이 수정
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ month_name }} Challenge</title>
</head>
<body>
<h1>{{ month_name }} Challenge</h1>
{% if text is not None %}
<h2>{{text}}</h2>
{% else %}
<p>There is no challenge for this month yet</p>
{% endif %}
</body>
</html>
넘겨받은 text 를 if 문 분기처리.
base 템플릿을 이용하기
1. settings.py 에 다음을 수정
.
.
.
.
.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
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',
],
},
},
]
'DIRS' 속성 BASE_DIR / "templates" 추가
base.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% block page_title%}My Challenges{% endblock %}</title>
</head>
<body>
<h1>All Challenges</h1>
{% block content %}{% endblock %}
</body>
</html>
block 태그를이용해서 삽입받을 블럭과 이름을 정의
path_title 블락의 경우 들어오지 않으면 My Challenges 가 디폴드 값으로 설정
challenges/templates/challenges/index.html
{% extends "base.html" %}
{% block page_title %}
All challenges
{% endblock %}
{% block content%}
<ul>
{% for month in months %}
<li><a href="{% url 'month-challenge' month %}">{{ month|title}}</a></li>
{% endfor %}
</ul>
{% endblock %}
1. settings.py 에서 DIRS 속성을 추가했기 때문에 base.html 을 BASE_DIR/templates 에서 찾음
2. 정의한 block 을 base.html 에 삽입렌더링 .
include 태그 사용법
challenges/templates/challenges/challenge.html
{% extends "base.html" %}
{% block page_title %}
{{ month_name }} Challenge
{% endblock %}
{% block content %}
{% include "challenges/include/header.html" with active_page="challenge"%}
<h1>{{ month_name }} Challenge</h1>
{% if text is not None %}
<h2>{{text}}</h2>
{% else %}
<p>There is no challenge for this month yet</p>
{% endif %}
{% endblock %}
include 뒤에 나오는 header.html 은 절대 주소를 써주었다 .
setting.py 의 INSTALLED_APPS 에 "challenges" 를 추가해주었기 때문에 가능한 일이다!
with 뒤엔 header.html 에만 적용되는 변수를 사용하고 싶을 때 적용한다.
challenges/templates/challenges/includes/header.html
<header>
<nav>
<a href="{% url 'index' %}">All challenges</a>
</nav>
{{ month_name }}
</header>
<p>
Active_page : {{ active_page }}
</p>
month_name 변수는 밑에 views.py 에서 넘겨준 변수이다 !
즉 include 는 상위 템플릿에서 넘어온 변수도 인식이 가능하다 !
views.py
def monthly_challenge(request, month):
try:
challenge_text = monthly_challenges[month]
return render(request, "challenges/challenge.html",{
"text": challenge_text,
"month_name": month.capitalize(),
})
except:
return HttpResponseNotFound("<h1>This month is not supported</h1>")
'Django' 카테고리의 다른 글
커스텀 404 페이지 (0) | 2024.05.06 |
---|---|
파이참 장고 HTML 자동 완성 설정하기 (0) | 2024.05.05 |
reverse (0) | 2024.05.02 |
router 생성 (0) | 2024.04.30 |
파이썬 가상환경 만들기 (0) | 2024.04.30 |