하루에는

[Django]장고 템플릿 상속, url정리 네임스페이스 namespace 본문

Python, Django

[Django]장고 템플릿 상속, url정리 네임스페이스 namespace

에는 2019. 11. 29. 19:32

Overview

  • 템플릿 상속
  • url 관리
  • name space

템플릿 상속

지금까지 한 프로젝트에 두 개의 앱을 만들었습니다.

  • randomnum프로젝트
    1. picker앱
    2. post앱

두 개의 앱을 자유자재로 이동할 수 있는 네비게이션 바를 만들어보겠습니다.

<!-- 모든 html 파일 맨 윗줄에.. -->

<a href="{% url 'pick' %}">picker 앱으로 이동</a><br/>
<a href="{% url 'postlist' %}">post 앱으로 이동</a>
  • 모든 페이지마다 이렇게 코드를 써넣는 건 나중에 수정할 때도 힘들고 비효율적임
  • 하나의 html 파일을 만들어서 베이스로 삼고, 모든 페이지에 베이스 html 파일을 띄우는 것이 효율적

base.html 생성

settings.py가 있는 프로젝트 폴더에 templates를 만들고, base.html을 만들어주세요.

base.html에 아래와 같이 써주세요.

<h2>base.html에 작성된 네비게이션바</h2>
<a href="{% url 'pick' %}">picker 앱으로 이동</a><br/>
<a href="{% url 'postlist' %}">post 앱으로 이동</a>

{% block content %}
{% endblock %}
  • {% block content %}와 {% endblock %} 사이에 각 페이지들이 들어감

settings.py 수정

settings.py의 TEMPLTATES안의 DIR가 원래는 비어있습니다. base.html의 위치를 적어주세요.

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ['randomnumproject/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',
            ],
        },
    },
]

extends 표시

이제 base.html을 상속받을 페이지마다 아래 코드를 맨 위, 아래에 각각 넣어주면 됩니다.

<!-- 맨 위 -->
{% extends 'base.html' %}
{% block content %}

<!-- 맨 아래 -->
{% endblock %}
  • {% extends 'base.html' %} : base.html을 상속받겠다는 의미
  • {% block content %}부터 {% endblock %}까지의 내용이 base.html의 {% block content %}와 {% endblock %} 사이에 들어감

예시

url 정리

지금까지는 settings.py가 있는 프로젝트 폴더 내의 urls.py에 모든 path를 작성했습니다.

각 app별로 url을 관리할 수 있게 해보겠습니다.

앱 마다 urls.py 생성

post app

post 앱에 urls.py를 만들었습니다.

앱 안의 urls.py는 직접 만든 파일이기 때문에 아무 것도 작성돼있지 않습니다. 필요한 내용을 채워줍니다.

from django.urls import path
from . import views

urlpatterns = [
    path('list/', views.postlist, name='postlist'),
    path('show/<int:post_id>', views.show, name='show'),
]
  • 기존 urls.py에는 'post.views.함수이름' 으로 작성했지만, 앱 내의 urls.py에서는 'views.함수이름'만 작성한다.

settings.py가 있는 프로젝트 폴더의 urls.py를 정리해줍니다.

from django.contrib import admin
from django.urls import path, include # 추가
import picker.views
import post.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', picker.views.pick, name='pick'),
    path('post/', include('post.urls')), # 추가
]
  • include 임포트
  • post.urls에 적힌 path들을 include
  • post.urls의 path들은 '도메인주소/post/' 뒤에 붙여서 사용 가능

서버를 돌려서 도메인 뒤에 'post/list/'를 붙여보면 postlist.html 페이지가 잘 나타납니다.

picker app

picker 앱도 마찬가지로 urls.py를 만들고 내용을 채워줍니다.

from django.urls import path
from . import views

urlpatterns = [
    path('', views.pick, name='pick'),
]

기존의 'picker.views.pick'에서 picker를 빼는 것에 주의!

프로젝트 폴더의 urls.py도 수정해줍니다.

from django.contrib import admin
from django.urls import path, include
import picker.views
import post.views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('picker/', include('picker.urls')), # 추가
    path('post/', include('post.urls')),
]

도메인 뒤에 'picker/'를 붙이면 result.html이 잘 나타납니다.

 

name space

path의 name은 path 변수명이기 때문에 겹쳐서는 안된다.

Notice 게시판, FreeBoard 게시판의 상세 페이지 이름을 다 'show'라고 짓고 싶다면?

# picker/urls.py

from django.urls import path
from . import views

app_name = 'picker' # 앱의 이름을 명시

urlpatterns = [
    path('', views.pick, name='pick'),
]
  • app의 urls.py에 app_name을 명시해준다.
  • path name을 사용할 때 "appname:pathname" 형태로 사용한다.
  • name space를 사용해서 path name 중복 문제를 해결할 수 있다.

예시

<!-- base.html -->

<h2>base.html에 작성된 네비게이션바</h2>
<a href="{% url 'picker:pick' %}">picker 앱으로 이동</a><br/>
<a href="{% url 'postlist' %}">post 앱으로 이동</a>

{% block content %}
{% endblock %}
  • app_name을 지정했다면 반드시 "appname:pathname" 형태로 사용해야 한다.
  • appname을 생략하고 사용하면 NoReverseMatch 에러가 발생한다.
Comments