클래스 기반보기의 장점은 무엇입니까?


82

오늘 Django 1.3 알파가 출시되고 있으며 가장 선전 된 새로운 기능은 클래스 기반 뷰 의 도입입니다 . 관련 문서를
읽었 지만 이를 사용하여 얻을 수 있는 큰 이점 ™ 을보기가 어려웠 으므로 여기에서이를 이해하는 데 도움을 요청합니다. 문서에서 고급 예제 를 살펴 보겠습니다 .

urls.py

from books.views import PublisherBookListView

urlpatterns = patterns('',
    (r'^books/(\w+)/$', PublisherBookListView.as_view()),
)

views.py

from django.shortcuts import get_object_or_404
from django.views.generic import ListView
from books.models import Book, Publisher

class PublisherBookListView(ListView):

    context_object_name = "book_list"
    template_name = "books/books_by_publisher.html",

    def get_queryset(self):
        self.publisher = get_object_or_404(Publisher, name__iexact=self.args[0])
        return Book.objects.filter(publisher=self.publisher)

    def get_context_data(self, **kwargs):
        # Call the base implementation first to get a context
        context = super(PublisherBookListView, self).get_context_data(**kwargs)
        # Add in the publisher
        context['publisher'] = self.publisher
        return context

이제이 질문에 대해 5 분 만에 만든 "평범한보기"솔루션과 비교해 보겠습니다 (오류를 발견 할 수 있다는 점에 대해 사과드립니다).

urls.py

urlpatterns = patterns('books.views',
    url(r'^books/(\w+)/$', 'publisher_books_list', name="publisher_books_list"),
)

views.py

from django.shortcuts import get_object_or_404
from books.models import Book, Publisher

def publisher_books_list(request, publisher_name):
    publisher = get_object_or_404(Publisher, name__iexact=publisher_name)
    book_list = Book.objects.filter(publisher=publisher)

    return render_to_response('books/books_by_publisher.html', {
        "book_list": book_list,
        "publisher": publisher,
    }, context_instance=RequestContext(request))

나에게 두 번째 버전은 다음과 같습니다.

  • 기능면에서 동일
  • 훨씬 더 읽기 쉽습니다 ( self.args[0]? 끔찍합니다!)
  • 짧게
  • 덜 DRY 준수

내가 놓친 큰 것이 있습니까? 왜 사용해야합니까? 그것들이 문서에 있습니까? 그렇다면 이상적인 사용 사례는 무엇입니까? 인가 이나 mixin 유용한 그?

기여해 주신 모든 분들께 미리 감사드립니다!

추신 : 궁금해하는 사람들을 위해, 나는 일반보기에 매료 된 적이 없었습니다. 고급 기능이 필요하자마자 일반보기보다 짧아지지 않았습니다.


4
그래 나도 큰 이점을 보지 못하고있다. 이것에 대한 큰 대답을보고 싶습니다.
M. Ryan

1
완전히 동의합니다. 특히 self.args [0] 또는 self.kwargs [ 'slug']가 역겹습니다. 그것은 다음과 같이 URL 매개 변수에 대한 기본값을 제공하는 것도 지금 많이 힘들어 : 데프 publisher_books_list (요청, PUBLISHER_NAME = '허버트')
케빈 Renskers

답변:


48

클래스를 하위 클래스로 만들고 특정 경우에 대해 get_context_data와 같은 메서드를 구체화하고 나머지는 그대로 둘 수 있습니다. 함수로는 그렇게 할 수 없습니다.

예를 들어, 이전보기가 수행하는 모든 작업을 수행하는 새보기를 만들어야 할 수 있지만 컨텍스트에 추가 변수를 포함해야합니다. 원래 뷰를 하위 클래스로 만들고 get_context_data 메서드를 재정의합니다.

또한 템플릿을 별도의 메서드로 렌더링하는 데 필요한 단계를 분리하면 코드가 더 명확 해집니다. 메서드를 적게 수행할수록 이해하기가 더 쉽습니다. 일반보기 기능을 사용하면 모두 하나의 처리 장치에 덤프됩니다.


2
네, 볼 수 있습니다. RESTful로 이동해야하는지, 전체 사이트를 보유해야하는지 또는 모바일 사이트를 보유해야하는지 결정할 때 재정의가 쉽고 빈번한 혼합이 가능합니다. 이를 통해 해당 결정은 기능이 파생되는 동안 가능한 한 오래 연기 될 수 있습니다. Pylons의 Webware 모듈에는이 기능이 있었고 매우 유용했습니다. 즉, 클래스 기반 뷰는 __call __ () 메서드를 재정 의하여 Django에서 오랫동안 가능했습니다.
Elf Sternberg

9
매우 좋은 점을 제공하기 때문에 대답을 받아들이는 것은 ...하지만 해결해야 할 문제가 거의 없기 때문에 여전히 사용할 필요성을 느끼지 않습니다. 감사!
Agos

18

당신 self.args[0]을 괴롭히는 경우 대안은 다음과 같습니다.

urlpatterns = patterns('books.views',
    url(r'^books/(?P<slug>\w+)/$', 'publisher_books_list', name="publisher_books_list"),
)

그런 다음 self.kwargs['slug']대신 사용 하여 약간 더 읽기 쉽게 만들 수 있습니다.


10

예제 함수와 클래스는 기능이 동일하지 않습니다.

클래스 기반 버전은 무료로 페이지 매김을 제공하고 GET 이외의 다른 HTTP 동사의 사용을 금지합니다.

이것을 함수에 추가하려면 훨씬 더 길어질 것입니다.

그러나 실제로는 더 복잡합니다.


2
차이점을 지적하기 위해 +1하지만 개인적으로 require_GETdjango-pagination 은 사용하기 쉽고 간결하며 명시 적이라고 생각하며 항상 (거의 :)) cbvs보다 선호합니다.
Tomasz Zieliński

4

이것은 내가 처음 듣는 것입니다. 그리고 나는 그것을 좋아합니다.

솔직히 여기에서 내가 보는 장점은 뷰가 Django와 전체적으로 더 일관 적이라는 것입니다. 모델은 클래스이고 저는 항상 뷰도 그래야한다고 느꼈습니다. 나는 모든 것이 아니라는 것을 알고 있지만 뷰와 모델은 많이 사용되는 두 가지 유형 입니다.

기술적 인 이점은? 글쎄요, 파이썬에서는 모든 것이 클래스 ( 또는 객체 ?)입니다. 그래서 정말로 차이가 있습니까? 애초에 99 % 통사론 적 설탕 아닌가요?


일관성은 더 큰 코드 재사용을 허용한다고 말하고 싶습니다. 뷰가 특정 패턴을 따르는 경우 기본적으로 많은 상용구를 줄입니다. 예를 들어 모델을 기반으로 한 양식은 클래스 기반 뷰로 생성하는 것이 매우 빠릅니다. 두 개의 추가 필드가 필요하면 조금 까다로워지기 시작합니다. 3 개의 모델과 2 개의 추가 필드를 기반으로 한 양식이 필요한 경우에는 많은 노력을 아예 절약하지 못할 것입니다.
wobbily_col

1

클래스 기반 뷰에 대해 생각하는 한 가지 방법은 훈련 휠이없는 Django 관리자와 같으므로 훨씬 더 유연합니다 (그러나 이해하기 더 어렵습니다).

예를 들어 관리자의 목록 표시는 일반 ListView를 기반으로합니다. 가장 간단한 목록보기는 모델 또는 쿼리 세트 만 정의합니다.

class MyExampleView(ListView);
    model = ExampleModel 

자체 템플릿을 제공해야하지만 기본적으로 가장 기본적인 ModelAdmin과 동일합니다. 모델 관리자의 list_display 속성은 표시 할 필드를 알려주는 반면 ListView에서는 템플릿에서이 작업을 수행합니다.

class SpeciesAdmin(admin.ModelAdmin):
    list_display = ['name']
admin.site.register(ExampleModel , ExampleModelAdmin)

관리자에게는 매개 변수가 있습니다.

list_per_page = 100

페이지 당 개체 수를 정의합니다. 목록보기에는

paginate_by = 100

동일한 것을 달성합니다. 마찬가지로 관리자를 많이 사용자 지정하는 방법을 살펴보면 중복되는 부분이 많이 나타납니다.

이 사이트는 그들이하는 일에 대한 더 나은 아이디어를 제공 할 것입니다.

http://ccbv.co.uk/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.