urlpatterns = [ url(r'^time/$', current_datetime), url(r'^time/plus/1/$', one_hour_ahead), url(r'^time/plus/2/$', two_hours_ahead), url(r'^time/plus/3/$', three_hours_ahead), ]
해당 URL 매핑이 있다고 가정하자, /time/plus/1 은 1시간 미래를 보여주고
/time/plus/2 는 2시간 미래,
/time/plus/3 는 3시간 미래를 보여주는 url 맵핑이다.
분명이 위의 URL 맵핑에는 문제가 있다.
위의 urlpattern들은 중복적인 기능을 제공 하고, 기능자체가 (1시간, 2시간, 3시간) 만 지원할 수 있으므로 효율성이 떨어집니다.
만약, 4시간의 기능이 필요할 경우 URL conf를 새로하나 추가해줘야한다는 번거로움이 생깁니다.
임의의 시간으로 오프셋을 처리하기 위해서 어플리케이션을 다시 설계해 봅시다.
urlpatterns = [ # ... url(r'^time/plus/\d+/$', hours_ahead), # ... ]
저렇게 만들면 가능할 것 같지만, /time/plus/100000000 도 가능한 값이 되어버리므로, 좀더 합당한 값을 가질 수 있도록 다시 수정해봅시다.
url(r'^time/plus/\d{1,2}/$', hours_ahead),
자 이제 이것을 View 함수에 전달하기 위해서 ()로 쌉니다.
정리하자면 아래와 같습니다.
from django.conf.urls import include, url from django.contrib import admin from mysite.views import hello, current_datetime, hours_ahead urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^hello/$', hello), url(r'^time/$', current_datetime), url(r'^time/plus/(\d{1,2})/$', hours_ahead), ]
여기서 보통은 이런식으로 처리하면 되지 않을까 생각할 수 있습니다. (일반적인 다른 웹프로그래밍 언어등을 따져보자면, )
/time/plus?hours=3
위와 같은 ? 로 처리하는 방식이 낫다고 생각 할 수 있지만 Django의 철학중 하나는 URL이 깨끗하고 심플하고 더 읽기쉽고 더 쉬워야 한다는 철학이 있습니다.
아름다운 URL은 퀄리티 높은 웹 응용 프로그램의 특징입니다.
결국 /time/plus/hours/3 을 사용하라는 말입니다.
자 이제 hours_ahead 뷰를 작성해 보겠습니다. 이전에 작선한 current_datetime 뷰와 매우 비슷합니다.
from django.http import Http404, HttpResponse import datetime def hours_ahead(request, offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html)
위의 URLconf에서 보면 숫자가 1~2글자일경우만 가능하지만, 만약의 경우를 대비해서 ValueError을 계속 확인하는 것은 좋은 습관입니다.
def hours_ahead(request, offset): # try: # offset = int(offset) # except ValueError: # raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html)
자 해당 try except 구문의 주석을 해보고
/time/plus/3/ 을 호출해 봅시다.
그럼 TypeError가 날겁니다.
왜냐하면 timedelta에 string 형 변수를 전달했기 때문입니다.
자 위의 사진을 보고 에러를 판단하는 방법에 대해서 알아봅시다.
페이지의 상단에서 우선 정보를 얻습니다.
unsupported type 그리고 Exception Location 에서 에러가 난 행 번호를 봅니다.
Django 에서는 파일 이름, 함수, 메소드 이름, 행 번호 및 해당 행의 소스코드를 표시해 줍니다.
소스라인을 선택하면 오류가 있는 라인의 여러라인이 표시됩니다.
자여기서 밑에 사진이 살짝 짤렸지만 Local vars를 클릭해보면 해당 프레임 즉 저 에러가 난 부분에서의 모든 Local 변수들을 볼 수 있습니다.
예외가 발생한 코드의 정확한 위치를 알 수 있고, 위의 디버깅 정보는 개발하는데 있어서 큰 도움이 될겁니다.
일시적으로 Assertion을 일부러 삽입해서 오류 페이지를 강제로 띄우게 할 수도 있습니다. 그런 다음 프로그램의 로컬 변수와 상태를 볼 수 있죠,
아래와 같이 코드하면 됩니다.
def hours_ahead(request, offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) assert False html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html)
'Python > Django' 카테고리의 다른 글
[Django] RestFrameWork 튜토리얼 - 1. 직렬화 (0) | 2017.03.10 |
---|---|
[Django] 템플릿 태그와 필터 (0) | 2017.03.08 |
[Django] 템플릿 (0) | 2017.03.08 |
[Django] VIew와 URL conf (0) | 2017.03.07 |
[Django] urls.py 특징. (0) | 2017.03.07 |