(2024.07.01. 수정됨.)
주요 파일 경로
blog
|- entry
| |- urls.py
| |- models.py
|- templates
|- index.html
프로젝트에서 관리하는 app이 늘어날수록, app에서 사용하는 model이 많을수록 개별 url을 선언하고 관리하는 것은 매우 귀찮고, 번거로운 작업입니다.
이번에는 각 model에서 자신의 url을 스스로 밝힐 수 있도록 해줄 겁니다.
app_name 선언하기
다음과 같이 urls.py에 app_name을 선언하고, 글 목록과 개별 글 페이지 url에 name arg를 추가해줍니다.
글 목록은 index, 개별 글은 detail이라는 이름을 사용하겠습니다.
# entry/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index)
path('post/', views.post),
path('post/save/', views.save),
path('<int:pk>/', views.detail),
path('<int:pk>/edit/', views.edit, name='edit'),
path('<int:pk>/save/', views.save, name='save'),
path('<int:pk>/delete/', views.delete),
]
위 코드를 아래와 같이 수정합니다.
# entry/urls.py
from django.urls import path
from . import views
app_name = 'entry' # 추가
urlpatterns = [
path('', views.index, name='index'), # 변경
path('post/', views.post, name='post',), # 변경
path('post/save/', views.save, name='save'), # 변경
path('<int:pk>/', views.detail, name='detail'), # 변경
path('<int:pk>/edit/', views.edit), # 변경
path('<int:pk>/save/', views.save), # 변경
path('<int:pk>/delete/', views.delete, name='delete'), # 변경
]
url namespace
장고는 url namespace라는 기능을 제공합니다.
url의 이름을 통해 url 경로를 찾기 위해 사용하는데, "{url name}" 또는 "{app name}:{url name}" 조합으로 사용되는 것이 일반적입니다.
앞서 추가한 url name들을 활용하자면 글 목록은 "entry:index", 개별 글은 "entry:detail"이라는 이름을 가집니다.
"{url name}"만 선언하는 경우에는 config/urls.py에서만 해당하는 url을 찾습니다.
get_absolute_url 선언하기
models.py를 열고 이전에 작성한 Post class에 get_abolute_url method를 추가합니다.
사실 method의 이름은 아무렇게나 해도 상관없는데, 장고 공식 문서에서 get_absolute_url이라는 이름으로 소개하고 있어서 그 명칭을 그대로 사용합니다.
# entry/models.py
from django.db import models
from django.shortcuts import resolve_url # 추가
class Post(models.Model):
title = models.CharField(max_length=30,)
content = models.TextField(max_length=999, default='',)
date_post = models.DateTimeField(auto_now_add=True,)
date_edit = models.DateTimeField(auto_now=True,)
# 추가
def get_absolute_url(self):
return resolve_url('entry:detail', self.pk)
resolve_url
resolve_url은 urls.py를 탐색해 전달받은 args에 해당하는 url을 찾아주는 코드입니다.
템플릿 수정하기
이전에 작성한 index.html을 열어 "<a href="/entry/{{ object.pk }}">"라고 작성했던 부분을 "<a href="{{ object.get_absolute_url }}">"으로 변경해줍니다.
# index.html
<head></head>
<body>
{% if request.user.is_anonymous %}
<div>
<a href="/admin/login/?next={{ request.get_full_path }}">로그인하기</a>
</div>
{% else %}
<p>"{{ request.user.username }}"님</p>
<form action="/admin/logout/?next={{ request.get_full_path }}" method="post">
{% csrf_token %}
<input type="submit" value="로그아웃">
</form>
{% endif %}
<br>
<h1>{{ title }}</h1>
<a href="{% url 'entry:post' %}">글 작성하기</a>
<article>
{% for object in objects %}
<p><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></p>
<p>get_absolute_url : {{ object.get_absolute_url }}</p>
<p>url filter : {% url 'entry:detail' object.pk %}</p>
{% empty %}
<p>작성된 글이 없습니다.</p>
{% endfor %}
</article>
</body>
url filter
index.html을 다시 보면 "{{ object.get_absolute_url }}" 외에도 "{% url 'entry:post' %}"와 "{% url 'entry:detail' object.pk %}"라는 html 코드를 추가해놨습니다.
{% url ~ %}은 장고 템플릿에서 사용하는 템플릿 필터로, resolve_url과 같은 역할을 수행합니다.
{% url 'entry:post' %}은 다른 arg를 필요로 하지 않는 url이고,
{% url 'entry:detail' object.pk %}는 pk라는 arg를 필요로 하는 url이기 때문에 {% url {url name} {arg} %} 형식으로 작성되었습니다.
확인해보기
이제 url을 하나하나 찾을 필요없이, urls.py에서 대응하는 url을 장고 프로젝트가 알아서 찾아올 수 있게 되었습니다.

이 글의 댓글 기능은 일부러 막아놓았습니다. 궁금한 내용이 있다면 게시판을 이용해주세요!