티스토리 뷰

Python/* Django

12. URL Reverse

포꾼 2017. 12. 13. 17:37

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
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함