Ich habe heute gelesen, dass Django 1.3 alpha ausgeliefert wird, und die am meisten angepriesene neue Funktion ist die Einführung klassenbasierter Ansichten .
Ich habe die entsprechende Dokumentation gelesen , aber es fällt mir schwer, den großen Vorteil ™ zu erkennen , den ich durch ihre Verwendung erzielen könnte. Deshalb bitte ich hier um Hilfe beim Verständnis.
Nehmen wir ein erweitertes Beispiel aus der Dokumentation.
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
Und jetzt vergleichen wir es mit einer Lösung, die ich in 5 Minuten für diese Frage erstellt habe (ich entschuldige mich für etwaige Fehler).
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))
Die zweite Version sieht für mich so aus:
- Entspricht der Funktionalität
- Viel besser lesbar (
self.args[0]
? Schrecklich!) - Kürzer
- Nicht weniger DRY-konform
Fehlt mir etwas Großes? Warum sollte ich sie verwenden? Sind die in der Dokumentation? Wenn ja, was wäre dann der ideale Anwendungsfall? Sind Mixins so nützlich?
Vielen Dank im Voraus an alle, die dazu beitragen!
PS für diejenigen, die sich vielleicht fragen, ich war auch nie begeistert von allgemeinen Ansichten: Sobald ich einige erweiterte Funktionen benötigte, wurden sie nicht kürzer als normale Ansichten.
Antworten:
Sie können eine Klasse in Unterklassen unterteilen und Methoden wie get_context_data für bestimmte Fälle verfeinern und den Rest unverändert lassen. Mit Funktionen geht das nicht.
Beispielsweise müssen Sie möglicherweise eine neue Ansicht erstellen, die alles tut, was eine vorherige tut, aber Sie müssen zusätzliche Variablen in den Kontext aufnehmen. Unterklassifizieren Sie die ursprüngliche Ansicht und überschreiben Sie die Methode get_context_data.
Wenn Sie die zum Rendern der Vorlage erforderlichen Schritte in separate Methoden unterteilen, wird der Code klarer. Je weniger in einer Methode ausgeführt wird, desto einfacher ist das Verständnis. Mit regulären Ansichtsfunktionen wird alles in einer Verarbeitungseinheit gespeichert.
quelle
Wenn
self.args[0]
Sie gestört werden, ist die Alternative:Dann könnten Sie
self.kwargs['slug']
stattdessen verwenden, um es etwas lesbarer zu machen.quelle
Ihre Beispielfunktion und Klasse sind in Funktionen nicht gleich.
Die klassenbasierte Version bietet eine kostenlose 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.
quelle
Dies ist das erste Mal, dass ich davon höre - und ich mag es.
Der Vorteil, den ich hier ehrlich sehe, ist, dass dadurch die Ansichten insgesamt besser mit Django übereinstimmen. Models sind Klassen und ich hatte immer das Gefühl, dass Ansichten auch so sein sollten. Ich weiß, dass nicht alles so ist, aber Ansichten und Modelle sind die beiden am häufigsten verwendeten Typen .
Was den technischen Vorteil betrifft? Nun, in Python ist alles eine Klasse ( oder ein Objekt ?) - gibt es also wirklich einen Unterschied? Ist es nicht in erster Linie 99% syntaktischer Zucker?
quelle
Eine Möglichkeit, über klassenbasierte Ansichten nachzudenken, besteht darin, dass sie wie ein Django-Administrator mit ausgeschalteten Trainingsrädern sind und daher viel flexibler (aber schwieriger zu verstehen).
Zum Beispiel basiert die Listenanzeige im Administrator eindeutig auf der generischen ListView. In der einfachsten Listenansicht würden Sie nur ein Modell oder einen Abfragesatz definieren.
Sie müssen Ihre eigene Vorlage bereitstellen, diese entspricht jedoch im Wesentlichen der grundlegendsten ModelAdmin-Vorlage. Das Attribut list_display im Modelladministrator gibt an, welche Felder angezeigt werden sollen, während Sie dies in der ListView in der Vorlage tun würden.
Mit dem Admin haben Sie einen Parameter
Hiermit wird festgelegt, wie viele Objekte pro Seite vorhanden sind. Listenansicht hat
das erreicht das gleiche. Wenn Sie sich intensiv mit der Anpassung des Administrators befassen, werden Sie ebenfalls viele Überschneidungen feststellen.
Diese Seite hier soll Ihnen eine bessere Vorstellung davon geben, was sie auch tun.
http://ccbv.co.uk/
quelle