registros - vistas basadas en clases django
¿Cuál es la ventaja de las vistas basadas en clase? (5)
Esta es la primera vez que escucho 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 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 realmente hay una diferencia? ¿No es un 99% de azúcar sintáctico en primer lugar?
Leí hoy que Django 1.3 alpha se está enviando, 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 les pido ayuda para entenderlos.
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 vamos a compararlo 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 en ella).
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í se ve:
- Equivalente en funcionalidad
- Mucho más legible (
self.args[0]
?self.args[0]
!) - Corta
- No menos compatible con DRY
¿Hay algo grande que me estoy perdiendo? ¿Por qué debería usarlos? ¿Están esos en la documentación? Si es así, ¿cuál sería el caso de uso ideal? ¿Son mixins tan útiles?
Gracias de antemano a cualquiera que contribuya!
PD: para aquellos que podrían preguntarse, nunca me dejaron cautivados los puntos de vista genéricos: tan pronto como necesité alguna funcionalidad avanzada, se volvieron más cortos que las vistas regulares.
Puede subclasificar una clase y refinar métodos como get_context_data para casos específicos, y dejar el resto tal como está. No puedes hacer eso con las funciones.
Por ejemplo, puede que necesite crear una vista nueva 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 procesar la plantilla en métodos separados promueve un código más claro: cuanto menos se hace en un método, más fácil es de entender. Con las funciones de visualización regulares, todo se vierte en la unidad de procesamiento.
Si 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ías usar self.kwargs[''slug'']
, lo que lo hace un poco más legible.
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 GET.
Si desea agregar esto a su función, va a ser mucho más largo.
Pero es, de hecho, más complicado.
Una forma de pensar en vistas basadas en clases, es que son como el administrador de Django con ruedas de entrenamiento desactivadas 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 consulta.
class MyExampleView(ListView);
model = ExampleModel
Deberá proporcionar su propia plantilla, pero básicamente será la misma que la de ModelAdmin más básica. El atributo list_display en el administrador del modelo le dirá qué campos mostrar, mientras que en el 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 al administrador, verá mucha superposición.
Este sitio aquí debería darle una mejor idea de lo que hacen también.