Templates

  • Template ์–ธ์–ด๋Š” ๊ฐ framework ๋งˆ๋‹ค ๋‹ค๋ฅด๋‹ค

  • Django์˜ template ์–ธ์–ด๋Š” DTL !

DTL (Django Template Language)

Ground Rule

: ์—ฐ์‚ฐ์€ DTL์ด ์•„๋‹Œ views.py ์˜ context๋กœ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ DTL์€ ๋‹จ์ˆœํžˆ ์ถœ๋ ฅํ•˜๋Š” ์—ญํ• ๋งŒ ํ•˜๊ฒŒ ํ•˜๊ธฐ

๊ธฐ๋ณธ ๋ฌธ๋ฒ•

1. ์ถœ๋ ฅ {{ }}

{{ menu }}
{{ menu.0 }}

2. ๋ฌธ๋ฒ• `{% %}

`


<div data-gb-custom-block data-tag="for">

</div>

3. ์ฃผ์„

{# This is comment #}

๋ฐ˜๋ณต๋ฌธ

Loops over each item in an array


<div data-gb-custom-block data-tag="for">

	<p> {{reply}} </p>

</div>
{{ forloop.counter }}
{{ forloop.counter0 }}

<div data-gb-custom-block data-tag="empty"></div>
  • ๋ฐฐ์—ด์ด ๋น„์–ด์žˆ์œผ๋ฉด ์ถœ๋ ฅํ•  ๋‚ด์šฉ ์จ์ค„ ๋•Œ ์‚ฌ์šฉ

Loop over each item in a dictionary


<div data-gb-custom-block data-tag="for">

    {{ key }}: {{ value }}

</div>

Variable
Description

forloop.counter

The current iteration of the loop (1-indexed)

forloop.counter0

The current iteration of the loop (0-indexed)

forloop.revcounter

The number of iterations from the end of the loop (1-indexed)

forloop.revcounter0

The number of iterations from the end of the loop (0-indexed)

forloop.first

True if this is the first time through the loop

forloop.last

True if this is the last time through the loop

forloop.parentloop

For nested loops, this is the loop surrounding the current one

์กฐ๊ฑด๋ฌธ


<div data-gb-custom-block data-tag="if" data-0='admin' data-1='admin'>

    <p> Accessible</p>

<div data-gb-custom-block data-tag="else"></div>

    <p> Inaccessible</p>

</div>

built-in tag, filter (|)

๊ณต์‹๋ฌธ์„œ ์ฐธ๊ณ ํ•˜์ž : https://docs.djangoproject.com/en/3.0/ref/templates/builtins/

length

{{content | length}}
  • ๊ธธ์ด ํ™•์ธํ•˜๊ธฐ

truncatechars:num

{{content|truncatechars:10}}
  • 10์ž๋งŒ ์ž˜๋ผ์„œ ๋ณด์ด๊ธฐ

dictsort

{{ value|dictsort:"name" }}
  • dictionary ์ž๋ฃŒํ˜•์ผ๋•Œ, ๋ช…์‹œํ•œ key๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ

Template ํ™•์žฅ

pages/templates/base.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Django Basics - Pages</title>
    

<div data-gb-custom-block data-tag="block">

    

</div>

</head>
<body>
    <h1> Django Basic Syntax</h1>
    

<div data-gb-custom-block data-tag="block">

    

</div>

</body>
</html>

posts.html


<div data-gb-custom-block data-tag="extends" data-0='base.html'></div>

<div data-gb-custom-block data-tag="block">

<style>

    h1 {
        color: blue;
    }
</style>

</div>

<div data-gb-custom-block data-tag="block">

    <!-- {# Template language ์—์„œ์˜ ์ฃผ์„ #} -->
    <h1> Post No. {{id}}</h1>
    <p> {{content}}</p>
    <p> {{content | length}}</p>
    <p> {{content|truncatechars:10}}</p>
    <hr>
    

<div data-gb-custom-block data-tag="for">

        <p> {{forloop.counter}} {{reply}}</p>
    

</div>

    <hr>

    

<div data-gb-custom-block data-tag="for">

        <p> {{forloop.counter}} {{reply}}</p>
        

<div data-gb-custom-block data-tag="empty"></div>

        <p> There's no reply ใ… _ใ… </p>
    

</div>

    <hr>
    

<div data-gb-custom-block data-tag="if" data-0='admin' data-1='admin'>

        <p> Accessible</p>
    

<div data-gb-custom-block data-tag="else"></div>

        <p> Inaccessible</p>
    

</div>

</div>

Template ์„ค์ • - DIR

TEMPLATES = [
    {	
        # DTL ์—”์ง„์„ ํ™œ์šฉ. jinja2 ๋“ฑ์œผ๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•จ
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # APP ๋‚ด์— ์žˆ๋Š” ํด๋”๊ฐ€ ์•„๋‹Œ ์ถ”๊ฐ€์ ์œผ๋กœ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ํ™œ์šฉํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ๋กœ.
        'DIRS': [os.path.join(BASE_DIR, 'intro', 'templates')],
        # APP_DIRS: True ์ธ๊ฒฝ์šฐ, ๋“ฑ๋ก๋œ app(INSTALLED_APPS)์˜ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” 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',
            ],
        },
    },
]

BASE_DIR

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  • Linux, Windows ๋“ฑ OS์— ์ƒ๊ด€์—†์ด ์„ค์ •ํ•˜๋ ค๊ณ  os.path.dirname()์œผ๋กœ ํ•จ

DIRS ๋ฆฌ์ŠคํŠธ์— ๊ฒฝ๋กœ ์ •์˜ ํด๋” ๊ตฌ์กฐ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•˜๊ธฐ

00_django_intro/ <- BASE_DIR
	django_intro/
		templates/

Multiple Apps

<br

์•ž์œผ๋กœ๋Š” ํ•ญ์ƒ app์„ ์ƒ์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํด๋” ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

app1/
	templates/
		app1/
			index.html
			a.thml
    urls.py
    views.py
    ...

app2/
	templates/
		app2/
			index.html
			b.thml
    urls.py
    views.py
    ...

1. url ์„ค์ • ๋ถ„๋ฆฌ

๊ฐ๊ฐ์˜ app ๋ณ„๋กœ url์„ ๊ด€๋ฆฌํ•œ๋‹ค.

  • ํ”„๋กœ์ ํŠธ ํด๋” urls.py ์ •์˜

    # django_intro/urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('pages/', include('pages.urls')),
        path('boards/', include('boards.urls')),
    ]

  • ๊ฐ ํ”„๋กœ์ ํŠธ๋ณ„ urls.py ์ •์˜

    from django.urls import path
    from . import views
    
    urlpatterns = [
        # /boards/
        path('', views.index),
        # /boards/new/
        path('new/', views.new),
        # /boards/complete/
        path('complete/', views.complete),
    ]

2. templates ํด๋” ๊ตฌ์กฐ

  • template ํŒŒ์ผ์„ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ django๋Š” ์•„๋ž˜์˜ ํด๋”๋“ค์„ ํƒ์ƒ‰ํ•œ๋‹ค.

    • DIRS ์— ์ •์˜๋œ ๊ฒฝ๋กœ์˜ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ

    • NSTALLED_APPS ๋””๋ ‰ํ† ๋ฆฌ์˜ templates ํด๋”์˜ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ ํƒ์ƒ‰

  • ์ด ๊ณผ์ •์—์„œ ์ค‘๋ณต๋œ ํŒŒ์ผ์ด ์žˆ๋Š” ๊ฒฝ์šฐ, ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค.

  • ๋”ฐ๋ผ์„œ, ์•ž์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

app1/
	templates/
		app1/
app2/
	templates/
		app2/

Form ์„ ํ†ตํ•œ Request ์ฒ˜๋ฆฌ

  1. ์‚ฌ์šฉ์ž๋“ค๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ๋ฐ›์•„์„œ (boards/new/)

  2. ๋‹จ์ˆœ ์ถœ๋ ฅํ•˜๋Š” page ๊ตฌ์„ฑ (boards/complete/)

1. ์‚ฌ์šฉ์ž์—๊ฒŒ form ์–‘์‹ ์ œ๊ณต

1-1 url ์ง€์ •

# boards/urls.py
path('new/', views.new),

1-2 view ํ•จ์ˆ˜ ์ƒ์„ฑ

#boards/views.py
def new (request):
    return render(request, 'boards/new.html')

1-3 template

<form action="/boards/complete/">
    Title: <input type="text" name="title">
</form>
  • form tag์—๋Š” action ์†์„ฑ์„ ์ •์˜ํ•œ๋‹ค

    • ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ๋‚ด์š”์„ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๋Š” url

  • input tag์—๋Š” name ์†์„ฑ์„ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋‚ด์šฉ์„ ๋‹ด์„ ๋ณ€์ˆ˜ ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค

  • url ์˜ˆ์‹œ

    • /boards/complete/?title="์ œ๋ชฉ์ œ๋ชฉ"

2. ์‚ฌ์šฉ์ž ์š”์ฒญ ์ฒ˜๋ฆฌ

2-1. urls.py ์ •์˜

bords/url.py

path('/boards/complete', views.complete)

2-2. views.py

boards/views.py

def complete(request):
    title = request.GET.get('title')
    context = {
        'title': title
    }
    return render(request, 'boards/complete.html', context)
  • request์—๋Š” ์š”์ฒญ๊ณผ ๊ด€๋ จ๋œ ์ •๋ณด๋“ค์ด ๋‹ด๊ธด object๊ฐ€ ์ €์žฅ๋˜์–ด ์žˆ๋‹ค

2-3. template

<!-- boards/templates/boards/complete.html -->
{{ title }}

+

Tip) project ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ!

$ cd intro/
$ django-admin startproject intro .

Last updated

Was this helpful?