URL Reverse를 통해서 유연하게 URL 생성하기
2022. 1. 11. 19:18ㆍ강의 정리/Django Views
반응형
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!
URL Dispatcher
- urls.py 변경만으로 "각 뷰에 대한 URL"이 변경되는 유연한 URL 시스템
HTTP 요청이 들어올 때, 즉 예를 들어서 검색을 하거나, 주소창에 직접 주소를 입력하거나, 어떠한 이벤트가 발생하여 백엔드(Django)에게 HTTP request가 들어올 때, 적합한 로직(View 함수)을 가진 URL로 매칭을 해주는 것이 URL Dispatcher이다.
https://devdongbaek.tistory.com/67
URL Reverse
- python 코드 안에서 URL 템플릿 태그와 비슷하게 동작하는 기능이다.
- urls.py에서 설정한 URL의 name이나, viewname을 통해서 다시 URL로 되돌릴 수 있다.
URL Reverse의 혜택
- 개발자가 일일이 URL을 계산하지 않아도 되며, URL이 변경되더라도 누락 되지않고 URL Reverse가 변경된 URL을 추적
- 즉 무슨 말이냐면
- https://wayhome25.github.io/django/2017/05/05/django-url-reverse/
"blog/" 주소로 서비스하다가 urlpatterns = [ path('blog/', views.post_list, name='post_list'), ] 아래와 같이 변경하면 자동으로 "weblog/" 주소로 서비스하게 됨 urlpatterns = [ path('weblog/', views.post_list, name='post_list'), ]
만약 직접 URL을 계산한다면??
- blog앱 Post 목록을 보려면, post_list 뷰를 호출해야 하니
- urls.py를 뒤적거리며, URL을 일일이 계산해야한다.
- 계산이 마치면 그 때 /blog/ 주소를 사용할 수 있다.
- 그런데 만약 url을 변경하고 싶다면??? 일일이 다 바꿔야 하는 불상사가 일어난다.
그러나 Django를 이용하면?
- blog앱 Post 목록을 보려면, post_list 뷰를 호출해야 함 # 끝!!!!
urls.py를 뒤적거리며, URL을 일일이 계산해야한다.계산이 마치면 그 때 /blog/ 주소를 사용할 수 있다.
URL Reverse를 수행하는 4가지 함수
- url 템플릿 태그
-
{% url="blog:post_detail" 100 %} # 문자열 URL {% url="blog:post_detail" pk=100 %} # 문자열 URL
- 내부적으로 reverse 함수를 사용
-
- reverse 함수
-
reverse('blog:post_detail', args=[100]) # 문자열 URL reverse('blog:post_detail', kwargs={'pk': 100}) # 문자열 URL
- 매칭 URL이 없으면 NoReverseMatch 예외 발생
-
- resolve_url 함수 #reverse 함수를 조금 더 사용하기 쉽게
-
resolve_url('blog:post_detail', 100) # 문자열 URL resolve_url('blog:post_detail', pk= 100) # 문자열 URL resolve_url('/blog/100/') # 문자열 URL
- 매핑 URL이 없으면 "인자 문자열"을 그대로 리턴
- 내부적으로 reverse 함수를 사용
-
- redirect 함수 #resolve_url 함수 기능을 보충
-
redirect('blog:post_detail', 100) # HttpResponse 응답 (301 or 302) redirect('blog:post_detail', pk= 100) # HttpResponse 응답 (301 or 302) redirect('/blog/100/') # HttpResponse 응답 (301 or 302)
- 매칭 URL이 없으면 "인자 문자열"을 그대로 URL로 사용
- 내부적으로 resolve_url 함수를 사용
- view 함수 내에서 특정 url로 이동 하고자 할 때 사용 (Http Response)
-
URL Reverse 직접 사용해보기
urls.py의 urlpatterns에 name 속성이 지정되어있어야 한다.
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:pk>/', views.post_detail, name='post_detail'),
]
Shell에서
>>> from django.urls import reverse
>>> from django.shortcuts import resolve_url
>>> reverse('instagram:post_list')
'/instagram/'
>>> reverse('instagram:post_detail', args=[123])
'/instagram/123/'
>>> resolve_url('instagram:post_detail', 100)
'/instagram/100/'
>>> resolve_url('instagram:post_detail', pk=100)
'/instagram/100/'
모델 객체에 대한 detail 주소 계산
#모든 모델에 대해서 detail 페이지는 거의 존재한다 ex) 쇼핑몰의 item과 Item_detail, SNS의 Post와 Post_detail등 그러므로 detail 페이지의 URL을 알기 위해서는 위에서 알게 된 방법 말고도 더 간단한 방법도 존재한다.
resolve_url('instagram:post_detail', pk=post.pk)
redirect('instagram:post_detail', pk=post.pk)
{% url 'blog:post_detail' post.pk %}
위의 코드와 아래 코드는 같은 의미의 detail 주소 계산이다.
resolve_url(post)
redirect(post)
{{ post.get_absolute_url }}
# 아래 코드를 사용하기 위해서는 모델 클래스에 get_absolute_url()을 구현해야한다.
모델 클래스에 get_absolute_url()
- 모델 클래스에 get_absolute_url()을 구현했다면, resolve_url과 redirect에서는 get_absolute_url()을 사용할 준비가 되어있기에, 바로 사용이 가능하다.
- 템플릿에서는 모델에 구현한 get_absoulte_url()을 직접 호출하여 사용한다.
- resolve_url 함수는 가장 먼저 get_absolute_url() 함수의 존재 여부를 체크하고, 존재할 경우 reverse를 수행하지 않고 그 리턴값을 즉시 리턴
특정 모델에 대한 Detail뷰를 작성할 경우, 코드가 보다 간결해지기 때문에 Detail뷰에 대한 URLConf설정을
필히 get_absolute_url설정을 해야한다.
- 모델을 구현하였다면, get_absolute_url() 함수부터 구현하는 것이 좋다.
get_absolute_url() 작성
instagram/models.py
class Post(models.Model):
--- 중략 ---
def get_absolute_url(self):
return reverse('instagram:post_detail', args=[self.pk])
get_absolute_url() 활용
1. 템플릿의 tag로 활용
instagram/templates/instagram/post_list.html
<body>
--- 중략 ---
<td>
<a href= "{{ post.get_absolute_url }}" >
{{ post.message }}
--- 중략 ---
</table>
2. resolve_url, redirect를 통한 활용
from django.shortcuts import resolve_url
from django.shortcuts import redirect
resolve_url('blog:post_detail', post.id) # '/blog/105/'
resolve_url(post) # '/blog/105/' 인자의 인스턴스 메소드로 get_absolute_url 있는지 체크해서 리턴
print(redirect('blog:post_detail', post.id))
print(redirect(post))
# <HttpResponseRedirect status_code=302, "text/html; charset=utf-8", url="/blog/105/">
출처 : https://wayhome25.github.io/django/2017/05/05/django-url-reverse/
그 외 활용
CreateView / UpdateView
- success_url(성공했을 때 이동할 주소)을 제공하지 않을 경우, 해당 model instance의 get_absolute_url 주소(즉 detail view)로 이동이 가능한지 체크하고, 이동이 가능할 경우 이동
- 생성 / 수정하고나서 Detail 화면으로 이동하는 것이 자연스러운 시나리오 # 즉 네이버 블로그에서 글을 생성 / 수정하면 목록이 아닌 해당 글 화면으로 이동하는 것이 자연스러움
반응형
'강의 정리 > Django Views' 카테고리의 다른 글
Django 휴대폰 망을 통해 접속하는 방법 (0) | 2022.01.14 |
---|---|
적절한 HTTP 상태코드로 응답하기 (0) | 2022.01.11 |
Django 기본 CBV API (Generic date views) (0) | 2022.01.11 |
Django 뷰 장식자(Decorators) (0) | 2022.01.10 |
Django 기본 CBV API (Generic display views) (0) | 2022.01.10 |