장고 마스터하기 - 2장
동적 URL
지금 현재시간에 파라미터로 들어온 값의 시간만큼 더하는 기능을 만들어 봤을 때 URL은 아래와 같이 될 수 있다.
url(r'^time/plus/(\d{1,2})/$', hours_ahead)
동적으로 파라미터를 넣고 싶을 때 정규식을 사용해 넣을 수 있다.
/time/plus?hours=3
과 같이 URL 쿼리 문자열에서 파라미터로 설정할 수 있다. 하지만 장고의 핵심 철학 중 하나는 URL을 보기 좋게 하는 것이다. URL/time/plus/3
은 훨씬 깔끔하고, 간단하며, 읽기쉽고, 보기에 좋다. 장고의 URLconf 시스템은 깔끔한 URL을 쉽게 사용하도록해 이런 URL을 권장한다.
뷰 코드
hours_ahead 뷰를 보자.
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
assert False
html = "<html><body>In %s hour(s), it will be %s.</body></html>" % (offset, dt)
return HttpResponse(html)
hours_ahead는 2개의 매개변수인 request와 offset를 가지고 있다.
- request: HttpRequest 객체. 각 뷰의 첫 번째 파라미터는 항상 HttpRequest를 사용한다.
- offset: URLpattern에서 괄호로 쌓여있는 문자열을 가져온다.
/time/plus/3
이면 offset은 문자열3
이 된다. 숫자로만 구성되어 있어도 항상 정수가 아닌 유니코드 객체로 넘어온다.
내용
- offset에 int() 호출해 문자열을 정수로 바꾼다.
- 정수로 바꿀 수 없는 문자열이 들어오면 404 error를 발생시킨다. 숫자밖에 들어올 수 없다 가정하면 이 과정은 필요없을 것이다. URLpattern은 숫자밖에 들어오지 못하게 잘 막을 것이다. 하지만 다른 방식으로 뷰를 호출하면 Error가 나온다. 뷰 매개변수에 대한 가정을 하지 않도록 뷰 기능을 구현하는 것이 좋다.(Loose Coupling)
- 날짜/시간을 계산하고 offset만큼 추가한다. datetime.timedelta 객체를 만들고 datetime.