В чем преимущество представлений на основе классов?

Сегодня я читал, что Django 1.3 alpha является отправкой, а самой популярной новой функцией является представление представлений на основе классов.
Я прочитал соответствующую документацию, но мне трудно увидеть большое преимущество ™, которое я мог бы получить, используя их, поэтому я прошу здесь о помощи в понимая их.
Возьмем расширенный пример из документации.

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]? awful!)
  • Более короткие
  • Не менее DRY-совместимый

Есть ли что-то большое, что мне не хватает? Почему я должен их использовать? Это документы? Если да, то каков будет идеальный вариант использования? Полезны ли миксины?

Заранее благодарим любого, кто вносит свой вклад!

P.S. для тех, кто мог бы задаться вопросом, я никогда не был увлечен общими представлениями: как только мне понадобилась какая-то расширенная функциональность, они стали не короче обычных представлений.

Ответ 1

Вы можете подклассифицировать класс и уточнить методы, такие как get_context_data для конкретных случаев, и оставить остальные как есть. Вы не можете делать это с помощью функций.

Например, вам может понадобиться создать новое представление, которое делает все, что делает предыдущий, но вам нужно включить дополнительную переменную в контекст. Подкласс исходного вида и переопределить метод get_context_data.

Кроме того, разделение шагов, необходимых для рендеринга шаблона в отдельные методы, способствует более четкому коду - чем меньше делается в методе, тем легче это понимать. С регулярными функциями просмотра все это сбрасывается в один процессор.

Ответ 2

Если self.args[0] беспокоит вас, альтернатива:

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

Тогда вы могли бы использовать self.kwargs['slug'] вместо этого, делая его несколько более читаемым.

Ответ 3

Ваша функция и класс не равны в функциях.

Версия на основе классов обеспечивает бесплатную разбивку на страницы и запрещает использование других HTTP-глаголов, чем GET.

Если вы хотите добавить это в свою функцию, это будет намного дольше.

Но это, действительно, сложнее.

Ответ 4

Это первое, что я слышал об этом, и мне это нравится.

Преимущество, которое я вижу здесь, честно, заключается в том, что он делает представления более согласованными с Django в целом. Модели - это классы, и я всегда считал, что взгляды тоже должны быть. Я знаю, что все не так, но взгляды и модели - это два сильно используемых типа.

Что касается технического преимущества? Ну, в Python все это класс (или объект?) - так есть ли разница? Разве это не 99% синтаксический сахар в первую очередь?

Ответ 5

Один из способов подумать о взглядах, основанных на классе, заключается в том, что они похожи на администратора 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/