티스토리 뷰
Django URL Dispatcher
urls.py 변경만으로 "각 뷰에 대한 URL"이 변경되는, 유연한 URL 시스템
urlpatterns = [ url(r'^blog/$', blog_views.post_list, name='post_list'), url(r'^blog/(?P<id>\d+)/$', blog_views.post_detail, name='post_detail'), ] # "/blog/", "/blog/1/" 주소로 서비스하다가, 아래와 같이 변경하면 urlpatterns = [ url(r'^weblog/$', blog_views.post_list, name='post_list'), url(r'^weblog/(?P<id>\d+)/$', blog_views.post_detail, name='post_detail'), ## weblog변경으로 weblog로 url이 변경 된다. ] |
URL Reverse 의 혜택 # view함수로 부터 url을 역으로 계산을 해보자
• 개발자가 일일이 URL을 계산하지 않아도 된다.
• URL이 변경되더라도, URL Reverse가 변경된 URL을 추적
- 누락될 일이 없다.
url이 변경이되면, 탬플릿네 여러군대 url을 참조하는 소스 코드를 전부 수정해야 하는 번거로움이 있다.
<!-- blog/templates/blog/layout.html --> <a href="/blog/">블로그 글 목록</a> <!-- blog/templates/blog/post_form.html --> <a href="/blog/">블로그 글 목록</a> <!-- blog/templates/blog/comment_form.html --> <a href="/blog/">블로그 글 목록</a> url name이 변경 되었을 경우 ex(/weblog) 일일이 탬플릿 전체의 기존 url로 걸려있는 링크 전부 수정 |
뷰 URL계산은 장고에게 양보 해라..
URL이 변경될 때마다, 이 URL을 참조하고 있는 코드를 일일이 찾아서 변경하는 것은 너무 번거롭고, 수정건을 누락시킬 여지도 많다.
urlpatterns = [ url(r'^blog/$', blog_views.post_list, name="post_list"), url(r'^blog/(?P<id>\d+)/$', blog_views.post_detail, name="post_detail"), ] (중요) url이름을 지정한다. # 기존 탬플릿 <a href="/blog/detail/{{ post.id }}/"> # 변경 후 탬플릿 <a href="{% url "post_detail" post.id %}"> # 인자가 필요없는데 인자를 넘길경우 에러가 발생한다. |
URL Reverse를 수행하는 4가지 함수
• reverse 함수 : 매칭 URL이 없으면 NoReverseMatch 예외 발생 # return (STR)
• resolve_url 함수 : 매칭 URL이 없으면 "인자 문자열"을 그대로 리턴 # return (STR)
• 내부적으로 reverse 함수를 사용
• redirect 함수 : 매칭 URL이 없으면 "인자 문자열"을 URL로 판단 # return (HttpResponse)
• 내부적으로 resolve_url 함수를 사용
• url template tag : 내부적으로 reverse 함수가 사용 # return (STR)
reversed_url_str = reverse('blog:post_detail', args=[100]) # 프로젝트/urls.py url(r'^blog/', include('blog.urls', namespace='blog')) # 앱/url.py url(r'^(?P<id>\d+)/$', views.post_detail, name='post_detail'), 이 이름은 현재 프로젝트 안에서 유일 하여야 한다. (템플릿과 동일하게 우선순위가 높은거 부터) 이러한 것을 방지하기위해 namespace를 지정하여, 예외 처리한다 inlcude의 인자로 받는다. (중요) namespace를 지정한 순간 name만으로 url reverse를 지정할 수 없다. <a href="{% url "blog:post_detail" post.id %}"> |
reverse 함수
from django.core.urlresolvers import reverse reversed_url_str = reverse('blog:post_detail', args=[100]) > '/blog/100/' reversed_url_str = reverse('blog:post_detail', kwargs={'id': 100}) > '/blog/100/' reverse('/hello') # 없는 문자열늠 넘길 경우 NoreverseMatch가 발생 |
resolve_url 함수
from django.shortcuts import resolve_url reversed_url_str = resolve_url('blog:post_detail', 100) > '/blog/100/' reversed_url_str = resolve_url('blog:post_detail', id=100) > '/blog/100/' resolve_url('/hello') 없는 문자열을 넘길 경우, 문자열 그대로 return > '/hello' |
redirect 함수
from django.shortcuts import redirect response = redirect('blog:post_detail', 100) > <HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/blog/100/"> response = redirect('blog:post_detail', id=100) > <HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/blog/100/"> |
redirect 내부적으로 resolve_url함수를 사용하며 resolve_url함수는 내부적으로 reverse를 사용한다.
최상위 url요청 시 blog로 리다이렉트
# 프로젝트/urls.py from django.shortcuts import redirect def root(reuqest): return redirect('blog:post_list') urlpatterns = [ #url(r'^$', root, name='root'), url(r'^%', lamda r:redirect('blog:post_list'), name='root) |
"GET / HTTP/1.1" 302 0
"GET /blog/ HTTP/1.1" 200 100064
모델 클래스내 get_absolute_url 멤버함수 (중요) 무조건 사용하자.
- 특정 모델에 대한 Detail뷰를 작성할 경우, Detail뷰에 대한 URLConf설정을 하자마자, get_absolute_url설정 코드가 간결해짐
- 어떠한 모델에 대해서 detail 뷰를 만들게 되면 get_absolute_url() 멤버 함수를 무조건 선언
- resolve_url(모델 인스턴스), redirect(모델 인스턴스) 를 통해서 모델 인스턴스의 get_absolute_url() 함수를 자동으로 호출
- resolve_url() 함수는 가장 먼저 get_absolute_url 함수의 존재 여부를 체크하고, 존재하면 호출하며 그 리턴값으로 URL을 사용
사용 전
from blog.models import Post post = Post.objects.first() print (reverse('blog:post_detail', args=[post.id]) print (resolve_url('blog:post_detail', post.id)) |
사용 후
# blog/models.py def get_absolute_url(self): reutrn reverse('blog:post_detail', args=[self.id]) print(post.get_absoulute_url()) |
"""본 내용은 AskDjango VOD, "장고 차근차근 시작하기" 강의내용을 참고하여 작성했습니다.(https://nomade.kr/)"""
'Python > * Django' 카테고리의 다른 글
14. Django 템플릿 엔진 - 템플릿 필터 (0) | 2017.12.15 |
---|---|
13. Django 템플릿 엔진 - 템플릿 태그 (0) | 2017.12.15 |
11. Django Template Loader (0) | 2017.12.13 |
10. Django 템플릿 상속 (0) | 2017.12.13 |
9. Model Relationship Fields (2) | 2017.12.13 |