web-dev-qa-db-fra.com

Quel est l'avantage des vues basées sur la classe?

J'ai lu aujourd'hui que Django 1.3 Alpha est l'expédition, et la nouvelle fonctionnalité la plus intégrée est l'introduction de Vues basées sur la classe .
[.____] J'ai lu la documentation pertinente , mais je trouve difficile à voir le Big Advantage ™ que je pourrais obtenir en les utilisant, alors je ' m demandant ici de l'aide pour les comprendre.
[.____] prenons un exemple avancé de la documentation.

urls.py

from books.views import PublisherBookListView

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

vues.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, comparons-la à une solution "vieillie plaine", faite par moi-même en 5 minutes pour cette question (je m'excuse pour toute erreur que vous pourriez y trouver).

urls.py

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

vues.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 à moi regarde:

  • Équivalent en fonctionnalité
  • Beaucoup plus lisible (self.args[0]? affreux!)
  • Plus court
  • Pas moins conforme à sec

Y a-t-il quelque chose de grand qui me manque? Pourquoi devrais-je les utiliser? Sont ceux sur la documentation? Si oui, quel serait le cas d'utilisation idéal? Sont mélanges cela utile?

Merci d'avance à quiconque qui contribue!

PS Pour ceux qui pourraient se demander, je n'ai jamais été passionné par des vues génériques aussi: dès que j'avais besoin de fonctionnalités avancées, ils ne deviennent pas plus courts que réguliers Vues.

81
Agos

Vous pouvez sous-classer une classe et affiner des méthodes telles que get_context_data pour des cas spécifiques et laisser le reste tel quel. Vous ne pouvez pas faire cela avec des fonctions.

Par exemple, vous devrez peut-être créer une nouvelle vue qui fait tout ce qui est précédent, mais vous devez inclure une variable supplémentaire dans le contexte. Sous-classe la vue d'origine et remplacer la méthode get_context_data.

De plus, séparer les étapes nécessaires pour rendre le gabarit dans des méthodes distinctes favorise le code plus claire - le moins fait dans une méthode, plus il est facile de comprendre. Avec des fonctions d'affichage régulières, tout est déversé dans l'unité de traitement.

48
Evan Porter

Si self.args[0] vous dérange, l'alternative est la suivante:

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

Ensuite, vous pourriez utiliser self.kwargs['slug'] Au lieu de cela, le rendue légèrement plus lisible.

17
Alex

Votre exemple de fonction et de classe ne sont pas égaux en fonctionnalités.

La version basée sur la classe fournit une pagination gratuitement et interdire l'utilisation d'autres verbes HTTP que d'obtenir.

Si vous souhaitez ajouter cela à votre fonction, cela va être beaucoup plus long.

Mais c'est bien plus compliqué.

10
e-satis

C'est le premier j'entends ça - et j'aime ça.

L'avantage que je vois ici, honnêtement, c'est que cela rend la vue plus cohérente avec Django Globalement. Les modèles sont des cours et j'ai toujours senti que des vues devraient être aussi. Je sais que tout n'est que des vues et les modèles sont les deux largement utilisés types.

Quant à l'avantage technique? Eh bien, in Python Tout est une classe (-ou objet?) - Il y a donc vraiment une différence? N'est-ce pas 99% de sucre syntaxiste en premier lieu ?

4
Frank V

Une façon de penser à des vues basées sur la classe, c'est qu'ils sont comme un Django admin avec des roues d'entraînement et donc beaucoup plus flexibles (mais plus difficiles à comprendre).

Par exemple, l'affichage de liste dans l'administrateur est clairement basé sur la liste générique. La liste la plus simple que vous ne définiriez qu'un modèle ou un requérant.

class MyExampleView(ListView);
    model = ExampleModel 

Vous devrez fournir votre propre modèle, mais il sera fondamentalement identique à la modeladmin le plus élémentaire. L'attribut list_display dans l'administrateur du modèle lui indiquera les champs à afficher, alors que dans la listeVoir, vous le feriez dans le modèle.

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

Avec l'administrateur, vous avez un paramètre

list_per_page = 100

qui définit le nombre d'objets par page. La liste de la liste a

paginate_by = 100

qui atteint la même chose. De même, si vous regardez fortement sur la personnalisation de l'administrateur, vous verrez beaucoup de chevauchement.

Ce site ici devrait vous donner une meilleure idée de ce qu'ils font aussi.

http://ccbv.co.uk/

1
wobbily_col