Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
815 views
in Technique[技术] by (71.8m points)

django - What is the advantage of Class-Based views?

I read today that Django 1.3 alpha is shipping, and the most touted new feature is the introduction of class-based views.
I've read the relevant documentation, but I find difficult to see the big advantage? that I could get by using them, so I'm asking here for some help in understanding them.
Let's take an advanced example from the documentation.

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

And now let's compare it to a “plain-old-views” solution, made by myself in 5 minutes for this question (I apologize for any error you may find in it).

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

The second version to me looks:

  • Equivalent in functionality
  • A lot more readable (self.args[0]? awful!)
  • Shorter
  • Not less DRY-compliant

Is there something big I'm missing? Why should I use them? Are those on the documentation? If so then what would be the ideal use case? Are mixins that useful?

Thanks in advance to anybody who contributes!

P.S. for those who might wonder, I was never enthralled by generic views as well: as soon as I needed some advanced functionality, they became no shorter than regular views.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can subclass a class and refine methods like get_context_data for specific cases, and leave the rest as-is. You can't do that with functions.

For instance, you might need to create a new view that does everything a previous one does, but you need to include extra variable in the context. Subclass the original view and override the get_context_data method.

Also, separating the steps needed to render the template into separate methods promotes clearer code - the less done in a method, the easier it is to understand. With regular view functions, it's all dumped into the one processing unit.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...