Programming

; develop a program

Framework/Django

[Django] 장고(Django) 기본요소 - URL 별칭

Clloud_ 2022. 11. 27. 15:45
반응형

이번 포스팅에서는 장고의 기본 요소 중 하나인 URL 별칭에 대하여 공부를 해보고자 한다.


URL 하드코딩

다음은 question_list.html 템플릿에 사용된 링크다.

<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li>

 

질문 상세를 위한 URL 링크지만 이러한 URL 링크는 수정될 가능성이 있다.

예를 들어 http://localhost:8000/pybo/question/2 또는 http://localhost:8000/pybo/2/question 처럼 바뀔 수 있다.

 

URL 링크의 구조가 자주 변경된다면 템플릿에서 사용한 모든 URL들을 일일이 찾아가며 수정해야 하는 리스크가 발생한다.

이러한 문제점을 해결하기 위해서는 해당 URL에 대한 실제 링크 대신 링크의 주소가 1:1 매핑되어 있는 별칭을 사용해야 한다.


URL 별칭

링크의 주소 대신 별칭을 사용하려면 URL 매핑에 name 속성을 부여하면 된다. 

pybo/urls.py 파일을 다음과 같이 수정한다.

 

[파일명: projects\mysite\pybo\urls.py]

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
]

http://localhost:8000/pybo/ URLindex, http://localhost:8000/pybo/2와 같은 URL에는 detail이라는 별칭을 부여한 것이다.

 


템플릿에서 URL 별칭 사용하기

pybo/urls.py 파일에 별칭을 추가하면 템플릿에서 다음처럼 사용할 수 있다.

 

[파일명: C:\projects\mysite\templates\pybo\question_list.html]

{% if question_list %}
    <ul>
    {% for question in question_list %}
        <li><a href="{% url 'detail' question.id %}">{{ question.subject }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}

 

하드 코딩되어 있던 /pybo/{{ question.id }} 링크를 {% url 'detail' question.id %}로 변경했다.

여기서 question.id는 URL 매핑에 정의된 <int:question_id>에 전달해야 하는 값을 의미한다.

 

파라미터명 전달
한 개의 파라미터를 전달할 경우에는 다음과 같이 사용했다.
{% url 'detail' question.id %}​


다음처럼 파라미터 명을 함께 사용할 수 있다.

{% url 'detail' question_id=question.id %}​

 

만약 2개 이상의 파라미터를 사용해야 한다면 다음과 같이 공백 문자 이후에 덧 붙여주면 된다.
{% url 'detail' question_id=question.id page=2 %}​

 


URL 네임스페이스

현재는 앱 하나만 사용 중이지만 앱 이외의 다른 앱이 프로젝트에 추가될 수도 있다.

이런 경우 서로 다른 앱에서 동일한 URL 별칭을 사용하면 중복이 발생한다.

 

이 문제를 해결하려면 pybo/urls.py 파일에 네임스페이스를 의미하는 app_name 변수를 지정해야 한다.

pybo/urls.py 파일app_name을 추가한다.

 

[파일명: projects\mysite\pybo\urls.py]

from django.urls import path

from . import views

app_name = 'pybo'

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
]

 

app_name을 pybo로 설정하고, http://localhost:8000/pybo/ 페이지를 요청하면 다음과 같은 오류가 발생한다.

 

이 오류는 네임스페이스를 추가했기 때문에 발생한 오류이다.

이 오류를 해결하려면 템플릿에서 사용한 URL 별칭에 네임스페이스를 다음과 같이 지정해야 한다.

 

[파일명: C:\projects\mysite\templates\pybo\question_list.html]

{% if question_list %}
    <ul>
    {% for question in question_list %}
        <li><a href="{% url 'pybo:detail' question.id %}">{{ question.subject }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>질문이 없습니다.</p>
{% endif %}

detail 앞에 pybo 라는 네임스페이스를 붙여준 것이다.

 


redirect 함수와 URL 별칭

URL별칭은 템플릿 외에 redirect 함수에서도 사용된다.

redirect는 특정 페이지로 이동시키는 함수이다.

redirect('pybo:detail', question_id=question.id)

 


반응형