Django
Vistas genéricas
Buscar..
Introducción
Las vistas genéricas son vistas que realizan una determinada acción predefinida, como crear, editar o eliminar objetos, o simplemente mostrar una plantilla.
Las vistas genéricas deben distinguirse de las vistas funcionales, que siempre se escriben a mano para realizar las tareas requeridas. En pocas palabras, se puede decir que las vistas genéricas deben configurarse, mientras que las vistas funcionales deben programarse.
Las vistas genéricas pueden ahorrar mucho tiempo, especialmente cuando tiene que realizar muchas tareas estandarizadas.
Observaciones
Estos ejemplos muestran que las vistas genéricas generalmente hacen que las tareas estandarizadas sean mucho más simples. En lugar de programar todo desde cero, configura lo que otras personas ya han programado para usted. Esto tiene sentido en muchas situaciones, ya que le permite concentrarse más en el diseño de sus proyectos que en los procesos en segundo plano.
Entonces, ¿ siempre deberías usarlos? No. Solo tienen sentido siempre que sus tareas sean bastante estandarizadas (cargar, editar, eliminar objetos) y cuanto más repetitivas sean sus tareas. Usar una vista genérica específica solo una vez y luego anular todos sus métodos para realizar tareas muy específicas puede que no tenga sentido. Puede que estés mejor con una vista funcional aquí.
Sin embargo, si tiene muchas vistas que requieren esta funcionalidad o si sus tareas coinciden exactamente con las tareas definidas de una vista genérica específica, entonces las vistas genéricas son exactamente lo que necesita para simplificar su vida.
Ejemplo Mínimo: Funcional vs. Vistas Genéricas
Ejemplo para una vista funcional para crear un objeto. Excluyendo comentarios y líneas en blanco, necesitamos 15 líneas de código:
# imports
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from .models import SampleObject
from .forms import SampleObjectForm
# view functioon
def create_object(request):
# when request method is 'GET', show the template
if request.method == GET:
# perform actions, such as loading a model form
form = SampleObjectForm()
return render_to_response('template.html', locals())
# if request method is 'POST', create the object and redirect
if request.method == POST:
form = SampleObjectForm(request.POST)
# save object and redirect to success page if form is valid
if form.is_valid:
form.save()
return HttpResponseRedirect('url_to_redirect_to')
# load template with form and show errors
else:
return render_to_response('template.html', locals())
Ejemplo para una 'Vista genérica basada en clase' para realizar la misma tarea. Solo necesitamos 7 líneas de código para lograr la misma tarea:
from django.views.generic import CreateView
from .models import SampleObject
from .forms import SampleObjectForm
class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
Personalizar vistas genéricas
El ejemplo anterior solo funciona si sus tareas son tareas completamente estándar. No agrega contexto adicional aquí, por ejemplo.
Hagamos un ejemplo más realista. Supongamos que queremos agregar un título de página a la plantilla. En la vista funcional, esto funcionaría así: con solo una línea adicional:
def create_object(request):
page_title = 'My Page Title'
# ...
return render_to_response('template.html', locals())
Esto es más difícil (o contra-intuitivo) de lograr con vistas genéricas. Como están basados en la clase, debe anular uno o varios de los métodos de la clase para lograr el resultado deseado. En nuestro ejemplo, necesitamos anular el método get_context_data de la clase de la siguiente manera:
class CreateObject(CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
def get_context_data(self, **kwargs):
# Call class's get_context_data method to retrieve context
context = super().get_context_data(**kwargs)
context['page_title'] = 'My page title'
return context
Aquí, necesitamos cuatro líneas adicionales para codificar en lugar de solo una, al menos para la primera variable de contexto adicional que deseamos agregar.
Vistas genéricas con mixins
El verdadero poder de las vistas genéricas se despliega cuando las combinas con Mixins. Un mixin es simplemente otra clase definida por usted cuyos métodos pueden ser heredados por su clase de vista.
Supongamos que desea que cada vista muestre la variable adicional 'page_title' en la plantilla. En lugar de anular el método get_context_data cada vez que defina la vista, cree un mixin con este método y deje que sus vistas se hereden de este mixin. Suena más complicado de lo que realmente es:
# Your Mixin
class CustomMixin(object):
def get_context_data(self, **kwargs):
# Call class's get_context_data method to retrieve context
context = super().get_context_data(**kwargs)
context['page_title'] = 'My page title'
return context
# Your view function now inherits from the Mixin
class CreateObject(CustomMixin, CreateView):
model = SampleObject
form_class = SampleObjectForm
success_url = 'url_to_redirect_to'
# As all other view functions which need these methods
class EditObject(CustomMixin, EditView):
model = SampleObject
# ...
La belleza de esto es que su código se vuelve mucho más estructurado de lo que es en su mayoría con vistas funcionales. Toda su lógica detrás de tareas específicas se encuentra en un solo lugar y en un solo lugar. Además, ahorrará enormes cantidades de tiempo, especialmente cuando tiene muchas vistas que siempre realizan las mismas tareas, excepto con diferentes objetos.