12. class based views 이해 - chohankyun/python-django-study GitHub Wiki
##class based views
모든 뷰는 요청을 받고, 응답을 리턴한다, 라는 것으로 볼때,
단순하게 함수로만으로 제공하는것 보다는 큰 틀을 만들어서
그 틀을 재사용하고, 그 틀에 맞게 코드를 작성하므로써 좀 더
구조적인 코드가 되도록 한다.(django documentation 나름대로 해석)
all views class ->(상속) View class
View class 기능
- url 링크 처리
- http method 에 따른 함수 호출
- etc..
##class based views 호출 방법
app/urls.py => as_view() : 클래스 함수 호출(entry point)
from django.conf.urls import url
from django.views.generic import TemplateView
urlpatterns = [
# urls 에서 제너릭 클래스 직접 호출(첫번째 방법)
url(r'^about/$', TemplateView.as_view(template_name="about.html")),
url(r'^books/$', BookListView.as_view()),
]
app/views.py
from django.views.generic import ListView
from books.models import Book
# 클래스 상속(두번째 방법, 속성 또는 함수 오버라이드)
class BookListView(ListView):
model = Book
##class based views 특징
- 조건(ex: if 문, ect..)에 의한 분기 보다 HTTP method(ex: get, post, ect..) 에 따른 분기로 함수 호출
- 객체 지향 프로그래밍, mixins(다중 상속)의 사용으로 코드 재활용
##generic views(미리 만들어진 뷰, 개발 편의성)
- function-based generic views
- Class-based generic views
##class based views 기본 함수
- as_view() : entry point 모든 Class-based generic views 는 as_view() 부터 시작(클래스 메쏘드)
- dispatch() : http method(get, post, etc.) 를 이용해서 함수 호출
##class based views, function based views 비교
HTTP GET 일 경우
function based views
app/urls.py
from django.conf.urls import url
from myapp import views
urlpatterns = [
url(r'^about/$', views.my_view),
]
app/views.py
from django.http import HttpResponse
def my_view(request):
if request.method == 'GET': # request 에서 method 값으로 분기
# <view logic>
return HttpResponse('result')
class based views
app/urls.py
from django.conf.urls import url
from myapp.views import MyView
urlpatterns = [
url(r'^about/$', MyView.as_view()),
]
app/views.py
from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request): # as_view() -> dispatch() 함수에서 get() 함수 호출
# <view logic>
return HttpResponse('result')
##decorating class based views
class based views 확장 방법
- mixins
- decorators
##mixins
- generic calss based views 사용(django 제공 class)
- custom class based views 사용(사용자 개발 class)
##decorators
decorator urls.py 적용
method decorator : @method_decorator
as_view() 를 decorating
decorator : login_required, permission_required
request 가 있을때 마다 만들어지는 instance 별 적용
같은 함수를 사용하는 두개의 요청(두개의 url)이 있고
하나의 요청에만 decorator 를 사용하면, decorator 를
사용한 요청의 instance 만 적용
from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView
from .views import VoteView
urlpatterns = [
url(r'^about/$', login_required(TemplateView.as_view(template_name="secret.html"))),
url(r'^vote/$', permission_required('polls.can_vote')(VoteView.as_view())),
]
decorator 클래스 적용
함수에 직접 적용
decorator : login_required
decorator 가 적용된 함수가 호출 될때 마다 적용
첫번째 방법: 클래스 안에 있는 함수에 적용
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
class ProtectedView(TemplateView):
template_name = 'secret.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(ProtectedView, self).dispatch(*args, **kwargs)
두번째 방법: 클래스 상단에서 name 속성(name=함수)을 이용한 적용
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
새번째 방법: 여러개의 decorator 적용은 decorator list 사용
순서: 왼쪽부터 오른쪽으로 적용
decorators = [never_cache, login_required]
@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'