오늘 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 유용한 그?
기여해 주신 모든 분들께 미리 감사드립니다!
추신 : 궁금해하는 사람들을 위해, 나는 일반보기에 매료 된 적이 없었습니다. 고급 기능이 필요하자마자 일반보기보다 짧아지지 않았습니다.
답변
클래스를 하위 클래스로 만들고 특정 경우에 대해 get_context_data와 같은 메서드를 구체화하고 나머지는 그대로 둘 수 있습니다. 함수로는 그렇게 할 수 없습니다.
예를 들어, 이전보기가 수행하는 모든 작업을 수행하는 새보기를 만들어야 할 수 있지만 컨텍스트에 추가 변수를 포함해야합니다. 원래 뷰를 하위 클래스로 만들고 get_context_data 메서드를 재정의합니다.
또한 템플릿을 별도의 메서드로 렌더링하는 데 필요한 단계를 분리하면 코드가 더 명확 해집니다. 메서드를 적게 수행할수록 이해하기가 더 쉽습니다. 일반보기 기능을 사용하면 모두 하나의 처리 장치에 덤프됩니다.
답변
당신 self.args[0]
을 괴롭히는 경우 대안은 다음과 같습니다.
urlpatterns = patterns('books.views',
url(r'^books/(?P<slug>\w+)/$', 'publisher_books_list', name="publisher_books_list"),
)
그런 다음 self.kwargs['slug']
대신 사용 하여 약간 더 읽기 쉽게 만들 수 있습니다.
답변
예제 함수와 클래스는 기능이 동일하지 않습니다.
클래스 기반 버전은 무료로 페이지 매김을 제공하고 GET 이외의 다른 HTTP 동사의 사용을 금지합니다.
이것을 함수에 추가하려면 훨씬 더 길어질 것입니다.
그러나 실제로는 더 복잡합니다.
답변
이것은 내가 처음 듣는 것입니다. 그리고 나는 그것을 좋아합니다.
솔직히 여기에서 내가 보는 장점은 뷰가 Django와 전체적으로 더 일관 적이라는 것입니다. 모델은 클래스이고 저는 항상 뷰도 그래야한다고 느꼈습니다. 나는 모든 것이 아니라는 것을 알고 있지만 뷰와 모델은 많이 사용되는 두 가지 유형 입니다.
기술적 인 이점은? 글쎄요, 파이썬에서는 모든 것이 클래스 ( 또는 객체 ?)입니다. 그래서 정말로 차이가 있습니까? 애초에 99 % 통사론 적 설탕 아닌가요?
답변
클래스 기반 뷰에 대해 생각하는 한 가지 방법은 훈련 휠이없는 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
동일한 것을 달성합니다. 마찬가지로 관리자를 많이 사용자 지정하는 방법을 살펴보면 중복되는 부분이 많이 나타납니다.
이 사이트는 그들이하는 일에 대한 더 나은 아이디어를 제공 할 것입니다.