Class-based views¶
뷰(view)는 요청(request)을 받아 응답(response)를 반환(return)하는 역할로 호출 가능합니다. 뷰(view)는 단순한 함수(function) 이상일 수 있는데, Django에서는 뷰(view)로 사용할 몇 가지 클래스(class)로 정의된 예제들을 제공합니다. 이를 통해 상속(inheritance)과, 믹스인(mixins)을 이용하여, 뷰(view)를 구조화하고 코드 재사용 또한 할 수 있습니다. 간단한 일을 처리 하기 위한 몇 가지 제너릭 뷰(generic views)가 있지만 usecase 에 맞는 재사용 가능한 뷰 구조를 직접 디자인 할 수 도 있습니다. 자세한 내용은 `클래스 기반의 뷰(class-based view) 레퍼런스 문서</ref/class-based-views/index>`를 참조하세요
기본 예제¶
Django는 다양한 어플리케이션에 알맞은 기본 뷰 클래스(base view classes)를 제공합니다. 모든 뷰들은 View
클래스를 상속받는데, 이것은 뷰와 URLs 을 연결짓고 HTTP 메소드를 디스패칭하거나, 다른 간단한 기능들을 처리합니다. :class:`~django.views.generic.base.RedirectView`는 간단한 HTTP 리다이렉트를 하고, :class:`~django.views.generic.base.TemplateView`는 기본 클래스(base class)를 확장하여 템플릿을 렌더(render) 합니다.
URLconf에서의 간단한 사용¶
제너릭 뷰(generic view)를 사용하는 가장 간단한 방법은 URLconf 에 직접 작성하는 것입니다. 클래스 기반 뷰의 몇가지 속성(attributes)들을 바꾸고, as_view()
메소드를 호출할때 바꾼 속성들을 전달 할 수 있습니다.
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('about/', TemplateView.as_view(template_name="about.html")),
]
as_view()
에 전달한 인자는 클래스의 속성(attributes)을 오버라이드(override)합니다. 이 예제에서는 TemplateView``에 ``template_name
을 설정합니다. 마찬가지로 url
속성(attirubte) 오버랑이딩 패턴을 :class:`~django.views.generic.base.RedirectView`에도 사용 할 수 있습니다.
제너릭 뷰의 상속(subclassing)¶
둘째로, 보다 유용한 제너릭 뷰를 사용하는 방법은 기존에 있는 뷰를 상속받아, 서브클래스의 속성(template_name``같은 것) 또는 메소드(``get_context_data``같은 것)를 오버라이드 하여, 새로운 값이나 메소드를 제공하는 것입니다. 예를들어 하나의 템플릿 ``about.html
. 만 보여주는 경우를 생각해 보세요. Django는 이러한 일을 처리하는 -TemplateView
- 라는 제너릭 뷰를 가지고 있습니다. 이 클래스를 하위클래스로(subclass)두고 템플릿 이름(template name)을 재정의 하기만 하면 됩니다.
# some_app/views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
그 다음 새로 작성한 뷰를 URLconf에 추가하면 됩니다. TemplateView
는 함수가 아닌 클래스이므로 URL에 as_view()
클래스 메소드를 가르키게 하여 함수 형태처럼 클래스 기반 뷰에 접근 가능 하도록 합니다.
# urls.py
from django.urls import path
from some_app.views import AboutView
urlpatterns = [
path('about/', AboutView.as_view()),
]
내장 제너릭 뷰의 사용법에 대한 자세한 내용은, 다음 토픽 :doc:`generic class-based views</topics/class-based-views/generic-display>`를 참조하세요.
다른 HTTP 메소드 지원¶
누군가 뷰를 API로 사용하여 HTTP를 통해 도서 라이브러리에 접근을 시도할 경우를 생각해 봅시다. API 클라이언트는 매 순간 접속하여 지난 방문 이후 새롭게 발행된 서적에 대한 도서 데이터를 다운로드 할 것 입니다. 하지만 그 이후로 새로운 도서가 나타나지 않으면, 데이터베이스에서 서적을 가져와 응답을 전체를 렌더링하여 클라이언트에게 보내는 것은 CPU의 시간과 대역폭을 낭비하는 것입니다. 이 경우, API에게 최근의 업데이트 도서에 대해 묻는것이 보다 나은 방법입니다.
URLconf 에서 URL을 book list 뷰와 매핑합니다:
from django.urls import path
from books.views import BookListView
urlpatterns = [
path('books/', BookListView.as_view()),
]
그리고 뷰에서는:
from django.http import HttpResponse
from django.views.generic import ListView
from books.models import Book
class BookListView(ListView):
model = Book
def head(self, *args, **kwargs):
last_book = self.get_queryset().latest('publication_date')
response = HttpResponse('')
# RFC 1123 date format
response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')
return response
GET
요청(request)에서 뷰에 접근 할 경우 일반적인 오브젝트 리스트들이 응답(response)에 반환됩니다(book_list.html
템플릿을 통해). 그러나 클라이언트가 HEAD
요청을 발행하면 응답에 empty body 와 함께 Last-Modified
헤더에 가장 최근의 책이 언제 발행되었는지를 알려 줄 것입니다. 이 정보를 바탕으로 클라이언트는 전체 오브젝트 리스트를 다운로드 할 수도 있고 하지 않을 수도 있습니다.