Frage Was ist der Vorteil von klassenbasierten Sichten?


Ich habe heute gelesen, dass Django 1.3 Alpha ausgeliefert wird, und das bekannteste neue Feature ist die Einführung von Klassenbasierte Ansichten.
Ich habe das gelesen relevante Dokumentation, aber ich finde es schwierig, das zu sehen großer Vorteil dass ich sie benutzen könnte, also bitte ich um Hilfe beim Verständnis.
Nehmen wir ein fortgeschrittenes Beispiel aus der Dokumentation.

urls.py

from books.views import PublisherBookListView

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

ansichten.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

Und jetzt vergleichen wir es mit einer "plain-old-views" -Lösung, die ich selbst in 5 Minuten für diese Frage gemacht habe (ich entschuldige mich für irgendeinen Fehler, den Sie darin finden könnten).

urls.py

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

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

Die zweite Version zu mir sieht aus:

  • Entspricht der Funktionalität
  • Viel besser lesbar (self.args[0]? furchtbar!)
  • Kürzer
  • Nicht weniger DRY-konform

Gibt es etwas Großes, das mir fehlt? Warum sollte ich sie benutzen? Sind das auf der Dokumentation? Wenn ja, was wäre der ideale Anwendungsfall? Sind Mixins das nützlich?

Vielen Dank im Voraus an jeden, der dazu beiträgt!

P.S. für diejenigen, die sich wundern könnten, war ich noch nie von generischen Ansichten begeistert: Sobald ich etwas fortgeschrittene Funktionalität brauchte, wurden sie nicht kürzer als normale Ansichten.


76
2017-12-06 20:29


Ursprung


Antworten:


Sie können eine Klasse ableiten und Methoden wie get_context_data für bestimmte Fälle verfeinern und den Rest unverändert belassen. Mit Funktionen ist das nicht möglich.

Beispielsweise müssen Sie möglicherweise eine neue Ansicht erstellen, die alle vorherigen Aktionen ausführt. Sie müssen jedoch zusätzliche Variablen in den Kontext einfügen. Unterklassieren Sie die ursprüngliche Ansicht und überschreiben Sie die Methode get_context_data.

Auch die Trennung der Schritte, die zum Rendern der Vorlage in separate Methoden erforderlich sind, fördert klareren Code - je weniger in einer Methode, desto einfacher ist sie zu verstehen. Mit regulären Ansichtsfunktionen wird alles in die eine Verarbeitungseinheit geworfen.


46
2017-12-07 04:19



Ob self.args[0] stört dich, die Alternative ist:

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

Dann könnten Sie verwenden self.kwargs['slug'] anstatt es etwas lesbarer zu machen.


16
2018-01-21 15:45



Ihre Beispielfunktion und -klasse sind in Features nicht gleich.

Die klassenbasierte Version bietet freie Paginierung und verbietet die Verwendung anderer HTTP-Verben als GET.

Wenn Sie dies zu Ihrer Funktion hinzufügen möchten, wird es viel länger dauern.

Aber es ist in der Tat komplizierter.


10
2018-03-25 13:41



Das ist das erste, was ich davon höre - und ich mag es.

Der Vorteil, den ich hier sehe, ist, dass die Ansichten insgesamt besser mit Django übereinstimmen. Models sind Klassen und ich habe immer gefühlt, dass Ansichten auch sein sollten. Ich weiß nicht alles ist aber Ansichten und Modelle sind die beiden stark genutzt Arten.

Wie für den technischen Vorteil? Nun, in Python ist alles eine Klasse (oder Objekt?) - Gibt es wirklich einen Unterschied? Ist es nicht zu 99% syntaktischer Zucker an erster Stelle?


4
2017-12-06 20:36



Eine Möglichkeit, über klassenbasierte Ansichten nachzudenken, ist, dass sie wie ein Django-Administrator sind, der das Training deaktiviert und daher viel flexibler (aber schwieriger zu verstehen) ist.

Zum Beispiel basiert die Listenanzeige im Admin eindeutig auf dem generischen ListView. In der einfachsten Listenansicht würden Sie nur ein Modell oder ein Queryset definieren.

class MyExampleView(ListView);
    model = ExampleModel 

Sie müssen Ihre eigene Vorlage angeben, aber sie ist im Grunde die gleiche wie die einfachste ModelAdmin. Das list_display-Attribut im Modell-Admin teilt ihm mit, welche Felder angezeigt werden sollen, während Sie dies in der ListView in der Vorlage tun würden.

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

Mit dem Admin hast du einen Parameter

list_per_page = 100

was definiert wie viele Objekte pro Seite. Listenansicht hat

paginate_by = 100

was dasselbe bewirkt. Ebenso, wenn Sie den Administrator stark anpassen, werden Sie eine Menge Überschneidungen sehen.

Diese Seite hier sollte Ihnen eine bessere Vorstellung davon geben, was sie auch tun.

http://ccbv.co.uk/


1
2018-03-19 14:16