Quel est l'avantage de vues à base de classe?
-
09-10-2019 - |
Question
Je lis aujourd'hui que Django 1.3 alpha est l'expédition, et la nouvelle fonctionnalité la plus vantée est l'introduction de vues basées sur les classes .
J'ai lu documentation pertinente , mais je trouve difficile de voir le grand avantage ™ que je pourrais obtenir en les utilisant, donc je suis ici pour demander une aide à les comprendre.
Prenons par exemple avancé de la 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
Et maintenant, nous allons le comparer à une solution « plain-vieux-vues », fait par moi-même en 5 minutes pour cette question (je présente mes excuses pour toute erreur que vous pouvez y trouver).
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))
La deuxième version me semble:
- équivalent dans la fonctionnalité
- Beaucoup plus facile à lire (
self.args[0]
? Terrible!) - Shorter
- Pas moins conforme DRY
Y at-il quelque chose de grand qui me manque? Pourquoi devrais-je les utiliser? Sont ceux de la documentation? Si oui, alors ce serait le cas d'utilisation idéale? Sont mixins qui utile?
Merci d'avance à tous ceux qui contribuent!
P.S pour ceux qui se poseraient la question, je ne captivé par les vues génériques aussi bien. Dès que je avais besoin de fonctionnalités avancées, ils sont devenus de vues réguliers ne court
.La solution
Vous pouvez sous-classe d'une classe et des méthodes épurera comme get_context_data pour les cas spécifiques, et laisser le reste en l'état. Vous ne pouvez pas le faire avec des fonctions.
Par exemple, vous pourriez avoir besoin de créer une nouvelle vue qui fait tout un précédent fait, mais vous devez inclure variable supplémentaire dans le contexte. Sous-classe l'affichage d'origine et remplacer la méthode get_context_data.
En outre, en séparant les étapes nécessaires pour rendre le modèle dans des méthodes distinctes favorise le code plus lisible - moins fait dans une méthode, plus il est facile à comprendre. Avec des fonctions d'affichage régulières, il est tout jeté dans une unité de traitement.
Autres conseils
Si self.args[0]
vous tracasse, l'alternative est:
urlpatterns = patterns('books.views',
url(r'^books/(?P<slug>\w+)/$', 'publisher_books_list', name="publisher_books_list"),
)
Ensuite, vous pouvez utiliser à la place self.kwargs['slug']
, ce qui rend un peu plus lisible.
Votre exemple la fonction et la classe ne sont pas égaux dans les caractéristiques.
La version à base de classe fournissent gratuitement et pagination interdire l'utilisation d'autres verbes HTTP que GET.
Si vous voulez ajouter à votre fonction, il va être beaucoup plus longue.
Mais il est, en effet, plus compliqué.
Ceci est le premier que j'entends cela - et je l'aime.
L'avantage que je vois ici, honnêtement, est qu'il rend des vues plus cohérente avec Django globale. Les modèles sont des classes et je me suis toujours senti que les vues devraient être aussi. Je sais que tout n'est pas mais les vues et les modèles sont les deux types fortement utilisés .
En ce qui concerne l'avantage technique? Eh bien, dans tout ce que Python est une classe ( ou objet ?) - donc est-il vraiment une différence? Est-il pas de sucre 99% en premier lieu?
Une façon de penser à des vues sur la base de la classe, est qu'ils sont comme un admin Django avec des roues de formation au large et donc beaucoup plus flexible (mais plus difficile à comprendre).
Par exemple, la liste d'affichage dans l'admin est clairement basé sur le ListView générique. La vue de la liste la plus simple que vous ne ferait que définir un modèle ou queryset.
class MyExampleView(ListView);
model = ExampleModel
Vous devez fournir votre propre modèle, mais il sera essentiellement le même que le plus ModelAdmin de base. L'attribut list_display dans l'admin de modèle lui dire ce que les champs à afficher, alors que dans le ListView vous faire dans le modèle.
class SpeciesAdmin(admin.ModelAdmin):
list_display = ['name']
admin.site.register(ExampleModel , ExampleModelAdmin)
Avec l'administrateur que vous avez un paramètre
list_per_page = 100
qui définit le nombre d'objets par page. Voir la liste a
paginate_by = 100
qui permet d'obtenir la même chose. De même, si vous regardez dans la personnalisation de l'administrateur fortement, vous verrez beaucoup de chevauchement.
Ce site ici devrait vous donner une meilleure idée de ce qu'ils font bien.