[Django] 장고의 기본 요소 익히기 - URL 별칭

싱숭생숭어·2023년 4월 30일
0

Django

목록 보기
9/19
post-thumbnail

위 글은 점프 투 장고를 참고해 작성하였습니다.

URL 하드코딩

먼저 지난 포스팅에서 만든 question_list.html 템플릿에 사용된 아래 링크

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

위는 질문 상세를 위한 URL 링크이다. 하지만 이러한 URL 링크는 프로젝트 과정에서 URL 리팩토링을 통해 빈번하게 발생할 수 있다.

URL 링크의 구조가 자주 변경된다면 템플릿에서 사용한 모든 URL들을 일일이 찾아가 수정해야하는 리스크가 있음. 이런 문제점을 해결하기 위해 해당 URL에 대한 실제 링크 주소가 1:1 매핑되어 있는 별칭을 사용해야 함 !


URL 별칭

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

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/ URL은 index라는 별칭을 부여

  • http://localhost:8000/pybo/2와 같은 URL에는 detail 이라는 별칭을 부여


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

위에 pybo/urls.py 별칭을 추가하면 템플릿(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 네임스페이스

현재 pybo 앱 하나만 사용중이지만 pybo 앱 이외의 다른 앱이 프로젝트에 추가될 수도 있을 것이다. 이런 경우 서로 다른 앱에서 동일한 URL 별칭을 사용하면 중복이 발생할 것이다.

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

from django.urls import path

from . import views

app_name = 'pybo' #app_name 추가

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
]
  • URL 별칭의 중복을 막기 위해 app_name 부분을 추가(app_name = 'pybo')

위처럼 pybo/urls.py에 app_name 부분을 추가하면 아래와 같은 페이지 오류 발생

  • 이 오류는 네임스페이스를 추가했기 때문에 발생한 오류, 이 오류를 해결하기 위해 템플릿에서 사용한 URL 별칭의 네임스페이스를 지정해줘야 함({% url 'detail' question.id %} -> {% url 'pybo:detail' question.id %} 이런식으로 !)

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 %}

그럼 이제 다시 pybo 페이지가 제대로 실행되는 것을 볼 수 있다 !

redict 함수와 URL 별칭

  • URL 별칭은 템플릿 외에 redict 함수에서도 사용됨. redict는 특정 페이지로 이동시키는 함수로, 아래와 같이 사용 가능
    • redirect('pybo:detail', question_id=question.id)
profile
공부합시당

0개의 댓글