Leí hoy que Django 1.3 alpha está disponible, y la nueva característica más promocionada es la introducción de vistas basadas en clases .
He leído la documentación pertinente , pero me resulta difícil ver la gran ventaja ™ que podría obtener al usarlos, por lo que solicito ayuda para comprenderlos.
Tomemos un ejemplo avanzado de la documentación.
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
Y ahora comparémoslo con una solución de "vistas simples y antiguas", hecha por mí mismo en 5 minutos para esta pregunta (me disculpo por cualquier error que pueda encontrar).
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 segunda versión para mí parece:
- Equivalente en funcionalidad
- Mucho más legible (
self.args[0]
¡horrible!) - Corta
- No menos compatible con DRY
¿Hay algo grande que me esté perdiendo? ¿Por qué debería usarlos? ¿Están en la documentación? Si es así, ¿cuál sería el caso de uso ideal? ¿Son los mixins tan útiles?
¡Gracias de antemano a todos los que contribuyen!
PD: para aquellos que se lo pregunten, nunca me cautivaron las vistas genéricas: tan pronto como necesité alguna funcionalidad avanzada, no se volvieron más cortas que las vistas normales.
Respuestas:
Puede subclasificar una clase y refinar métodos como get_context_data para casos específicos y dejar el resto como está. No puedes hacer eso con funciones.
Por ejemplo, es posible que deba crear una nueva vista que haga todo lo que hace una anterior, pero debe incluir una variable adicional en el contexto. Subclase la vista original y anule el método get_context_data.
Además, separar los pasos necesarios para representar la plantilla en métodos separados promueve un código más claro: cuanto menos se haga en un método, más fácil de entender. Con las funciones de visualización regulares, todo se vierte en una sola unidad de procesamiento.
fuente
Si te
self.args[0]
está molestando, la alternativa es:urlpatterns = patterns('books.views', url(r'^books/(?P<slug>\w+)/$', 'publisher_books_list', name="publisher_books_list"), )
Entonces podría usar
self.kwargs['slug']
en su lugar, haciéndolo un poco más legible.fuente
Su función y clase de ejemplo no son iguales en características.
La versión basada en clases proporciona paginación de forma gratuita y prohíbe el uso de otros verbos HTTP que no sean GET.
Si desea agregar esto a su función, será mucho más largo.
Pero es, de hecho, más complicado.
fuente
Esta es la primera vez que escucho sobre esto, y me gusta.
La ventaja que veo aquí, honestamente, es que hace que las vistas sean más consistentes con Django en general. Los modelos son clases y siempre sentí que las vistas también deberían serlo. Sé que no todo lo es, pero las vistas y los modelos son los dos tipos más utilizados .
¿En cuanto a la ventaja técnica? Bueno, en Python todo es una clase (¿ u objeto ?). Entonces, ¿hay realmente una diferencia? ¿No es 99% azúcar sintáctico en primer lugar?
fuente
Una forma de pensar en las vistas basadas en clases es que son como un administrador de Django con las ruedas de entrenamiento apagadas y, por lo tanto, mucho más flexibles (pero más difíciles de entender).
Por ejemplo, la visualización de la lista en el administrador se basa claramente en el ListView genérico. La vista de lista más simple solo definiría un modelo o conjunto de consultas.
class MyExampleView(ListView); model = ExampleModel
Deberá proporcionar su propia plantilla, pero básicamente será la misma que la ModelAdmin más básica. El atributo list_display en el administrador del modelo le indicará qué campos mostrar, mientras que en ListView lo haría en la plantilla.
class SpeciesAdmin(admin.ModelAdmin): list_display = ['name'] admin.site.register(ExampleModel , ExampleModelAdmin)
Con el administrador tienes un parámetro
list_per_page = 100
que define cuántos objetos por página. La vista de lista tiene
paginate_by = 100
que logra lo mismo. Del mismo modo, si busca personalizar mucho el administrador, verá mucha superposición.
Este sitio aquí debería darle una mejor idea de lo que hacen también.
http://ccbv.co.uk/
fuente