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 함수에 전달하기 위해서 ()로 쌉니다.


url(r'^time/plus/(\d{1,2})/$', hours_ahead),

정리하자면 아래와 같습니다.


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
Posted by C마노
,