장고에서 reverse 함수는 urls.py 에 선언해둔 name에 따라 URL을 받아와서 사용할 수 있게 해주는 기능을 가지고 있다. 다만 사용하기 위해서는 몇개의 밑작업이 필요하다.
우선 urls.py 에 수정이 필요한데,
apps/urls.py
#apitest/urls.py
from django.urls import path
from . import views
app_name = 'apitest'
urlpatterns = [
path('',views.IndexView.as_view(),name='index'),
path('<int:formid>/',views.testView,name='testview'),
path('formtest/',views.FormView.as_view(),name='formtest'),
path('contact/',views.ContactView.as_view(),name='contact')
]
위와 같이 app_name 항목을 추가해서 해당 앱의 이름을 적어줘야 한다.
위 예제는 calss형 뷰를 사용하는 generic view 예제.
그 다음, views.py를 보자.
apps/views.py
class ContactView(generic.FormView):
template_name = 'apitest/contact.html'
form_class = ContactForm
return_str = reverse_lazy("apitest:formtest")
success_url = '' #moving url when FORM request success.
def form_valid(self,form):
form.send_email()
return super().form_valid(form)
class FormView(generic.DetailView):
template_name = 'apitest/form.html'
def testView(request,formid):
test = reverse("apitest:formtest")
return HttpResponse("reverse return is %s"%test)
보면 하나는 def형 뷰에서는 reverse()를 그대로 사용하고, class형 뷰에서는 reverse_lazy()라는 함수를 사용한다.
왜 그러냐면, Class-level 속성을 가지는 객체들은 import 될 때 배치되는데 URL-seolving 규칙은 import 시간에 세팅되어있지 않아 class 내에서 reverse()를 사용하면 URLconf의 규칙을 인식하지 못한다.
따라서 class내에서 사용되는 reverse()함수는 URL 규칙을 적용하지 못하여 Included URLconf “does not appear to have any patterns in it”
에러을 뿜어내며 서버가 죽어버린다.
그러나 def 속성 객체는 import 이후에 배치되므로 URLconf의 규칙을 적용할 수 있다.
그러므로 class 형 뷰를 사용할때는 from django.urls import reverse_lazy
로 reverse_lazy() 함수를 import 해서 사용해주자.
- 마크다운 테스트