Ưu điểm của chế độ xem Dựa trên Lớp là gì?


82

Hôm nay tôi đọc được rằng Django 1.3 alpha đang được vận chuyển và tính năng mới được chào hàng nhiều nhất là giới thiệu các chế độ xem dựa trên lớp .
Tôi đã đọc các tài liệu liên quan , nhưng tôi cảm thấy khó thấy được lợi thế lớn mà tôi có thể nhận được khi sử dụng chúng, vì vậy tôi đang yêu cầu ở đây để được trợ giúp trong việc hiểu chúng.
Hãy lấy một ví dụ nâng cao từ tài liệu.

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

Và bây giờ chúng ta hãy so sánh nó với một giải pháp "quan điểm đơn giản", do chính tôi thực hiện trong 5 phút cho câu hỏi này (tôi xin lỗi vì bất kỳ lỗi nào bạn có thể tìm thấy trong đó).

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))

Phiên bản thứ hai đối với tôi trông:

  • Tương đương về chức năng
  • Có thể đọc được nhiều hơn ( self.args[0]? Kinh khủng!)
  • Ngắn hơn
  • Không ít tuân thủ DRY

Có điều gì lớn mà tôi đang thiếu? Tại sao tôi nên sử dụng chúng? Những cái đó có trong tài liệu không? Nếu vậy thì trường hợp sử dụng lý tưởng sẽ là gì? Là mixins rằng hữu ích?

Cảm ơn trước cho bất kỳ ai đóng góp!

PS cho những ai có thể thắc mắc, tôi cũng không bao giờ bị say mê bởi các chế độ xem chung chung: ngay khi tôi cần một số chức năng nâng cao, chúng trở nên không ngắn hơn các chế độ xem thông thường.


4
Vâng, tôi cũng không nhìn thấy lợi thế lớn. Rất thích xem một câu trả lời lớn về điều này.
M. Ryan

1
Hoàn toàn đồng ý. Tôi đặc biệt chán ghét self.args [0] hoặc self.kwargs ['slug']. Đó là bây giờ cũng khó khăn hơn rất nhiều để cung cấp các giá trị mặc định cho tham số url, như thế này: publisher_books_list def (yêu cầu, PUBLISHER_NAME = 'Herbert')
Kevin Renskers

Câu trả lời:


48

Bạn có thể phân lớp con một lớp và tinh chỉnh các phương thức như get_context_data cho các trường hợp cụ thể và giữ nguyên phần còn lại. Bạn không thể làm điều đó với các hàm.

Ví dụ: bạn có thể cần tạo một dạng xem mới thực hiện mọi thứ mà chế độ xem trước đó làm, nhưng bạn cần bao gồm thêm biến trong ngữ cảnh. Phân lớp chế độ xem ban đầu và ghi đè phương thức get_context_data.

Ngoài ra, việc tách các bước cần thiết để hiển thị mẫu thành các phương thức riêng biệt sẽ thúc đẩy mã rõ ràng hơn - càng ít được thực hiện trong một phương pháp, thì càng dễ hiểu. Với các chức năng xem thông thường, tất cả được đưa vào một đơn vị xử lý.


2
Vâng, tôi có thể thấy điều này. Nó tạo ra sự kết hợp dễ dàng và thường xuyên, trong trường hợp cố gắng quyết định xem bạn nên RESTful, có một trang web đầy đủ hay một trang web di động. Với điều này, quyết định đó có thể được hoãn lại càng lâu càng tốt trong khi chức năng được bắt nguồn. Mô-đun Phần mềm web trong Pylons có điều này, và nó rất hữu ích. Điều đó nói rằng, các chế độ xem dựa trên lớp từ lâu đã có thể thực hiện được với Django bằng cách ghi đè phương thức __call __ ().
Elf Sternberg

9
Chấp nhận câu trả lời vì nó cung cấp một điểm rất tốt ... nhưng vẫn không cảm thấy cần thiết phải sử dụng chúng, vì tôi hiếm khi gặp những vấn đề như vậy để giải quyết. Cảm ơn!
Agos

18

Nếu self.args[0]làm phiền bạn, giải pháp thay thế là:

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

Sau đó, bạn có thể sử dụng self.kwargs['slug']thay thế, làm cho nó dễ đọc hơn một chút.


10

Hàm ví dụ và lớp của bạn không giống nhau về các tính năng.

Phiên bản dựa trên lớp cung cấp phân trang miễn phí và cấm sử dụng các động từ HTTP khác ngoài GET.

Nếu bạn muốn thêm điều này vào chức năng của mình, nó sẽ mất nhiều thời gian hơn.

Nhưng nó, thực sự, phức tạp hơn.


2
+1 để chỉ ra sự khác biệt, nhưng cá nhân tôi nghĩ rằng request_GETdjango-pagination là cách sử dụng tầm thường, ngắn gọn, rõ ràng, v.v. và tôi thích chúng hơn cbvs tại (hầu như :)) mọi lúc.
Tomasz Zieliński,

4

Đây là lần đầu tiên tôi nghe về điều này - và tôi thích nó.

Thành thật mà nói, lợi thế mà tôi thấy ở đây là nó làm cho các quan điểm nhất quán hơn với Django nói chung. Mô hình là các lớp học và tôi luôn cảm thấy rằng các khung nhìn cũng nên như vậy. Tôi biết không phải tất cả mọi thứ nhưng quan điểm và mô hình là hai loại được sử dụng nhiều .

Đối với lợi thế kỹ thuật? Chà, trong Python, mọi thứ đều là một lớp ( hay đối tượng ?) - vậy có thực sự khác biệt không? Ngay từ đầu nó không phải là đường cú pháp 99% sao?


Tôi muốn nói rằng tính nhất quán cho phép sử dụng lại mã nhiều hơn. Về cơ bản, họ cắt giảm rất nhiều bảng soạn sẵn, nếu quan điểm của bạn tuân theo các mẫu nhất định. ví dụ: một biểu mẫu dựa trên mô hình aa được tạo cực kỳ nhanh chóng với các khung nhìn dựa trên lớp. Nếu nó cần một vài trường bổ sung, nó bắt đầu phức tạp hơn một chút. Nếu bạn cần một biểu mẫu dựa trên ba mô hình cộng với hai trường bổ sung, chúng có thể sẽ không giúp bạn tiết kiệm nhiều công sức.
wobbily_col

1

Một cách để nghĩ về các chế độ xem dựa trên lớp, đó là chúng giống như một quản trị viên Django đã tắt bánh xe đào tạo và do đó linh hoạt hơn rất nhiều (nhưng khó hiểu hơn).

Ví dụ: hiển thị danh sách trong quản trị rõ ràng là dựa trên ListView chung. Dạng xem danh sách đơn giản nhất mà bạn sẽ chỉ xác định một mô hình hoặc bộ truy vấn.

class MyExampleView(ListView);
    model = ExampleModel 

Bạn sẽ cần phải cung cấp mẫu của riêng mình, nhưng về cơ bản nó sẽ giống với ModelAdmin cơ bản nhất. Thuộc tính list_display trong quản trị viên mô hình sẽ cho nó biết những trường nào sẽ hiển thị, trong khi trong ListView, bạn sẽ thực hiện điều này trong mẫu.

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

Với quản trị viên, bạn có một tham số

list_per_page = 100

xác định số lượng đối tượng trên mỗi trang. Chế độ xem danh sách có

paginate_by = 100

mà đạt được điều tương tự. Tương tự như vậy, nếu bạn xem xét tùy chỉnh quản trị nhiều, bạn sẽ thấy rất nhiều chồng chéo.

Trang web này ở đây sẽ cung cấp cho bạn một ý tưởng tốt hơn về những gì họ làm.

http://ccbv.co.uk/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.