python - urls - vistas basadas en clases django
Parámetros y lógica de URL en las vistas basadas en clases de Django(TemplateView) (5)
No me queda claro cómo es mejor acceder a los parámetros de URL en las vistas basadas en clase en Django 1.5.
Considera lo siguiente:
Ver:
from django.views.generic.base import TemplateView
class Yearly(TemplateView):
template_name = "calendars/yearly.html"
current_year = datetime.datetime.now().year
current_month = datetime.datetime.now().month
def get_context_data(self, **kwargs):
context = super(Yearly, self).get_context_data(**kwargs)
context[''current_year''] = self.current_year
context[''current_month''] = self.current_month
return context
URLCONF:
from .views import Yearly
urlpatterns = patterns('''',
url(
regex=r''^(?P<year>/d+)/$'',
view=Yearly.as_view(),
name=''yearly-view''
),
)
Quiero acceder al parámetro del year
en mi vista, por lo que puedo hacer lógica como:
month_names = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"]
for month, month_name in enumerate(month_names, start=1):
is_current = False
if year == current_year and month == current_month:
is_current = True
months.append({
''month'': month,
''name'': month_name,
''is_current'': is_current})
¿Cómo podría uno acceder mejor al parámetro url en los CBV como el anterior que está subclasificado de TemplateView
y dónde debería ubicarse idealmente la lógica de esta manera, por ejemplo? en un metodo?
¿Qué tal si solo usas decoradores de Python para hacer esto inteligible?
class Yearly(TemplateView):
@property
def year(self):
return self.kwargs[''year'']
En caso de que pase un parámetro de URL como este:
http://<my_url>/?order_by=created
Puede acceder a él en la vista basada en clase utilizando self.request.GET
(no se presenta en self.args
ni en self.kwargs
):
class MyClassBasedView(ObjectList):
...
def get_queryset(self):
order_by = self.request.GET.get(''order_by'') or ''-created''
qs = super(MyClassBasedView, self).get_queryset()
return qs.order_by(order_by)
Encontré esta solución elegante, y para django 1.5 o superior, como se indica here :
Las vistas basadas en la clase genérica de Django ahora incluyen automáticamente una variable de vista en el contexto. Esta variable apunta a su objeto de vista.
En tus views.py:
from django.views.generic.base import TemplateView
class Yearly(TemplateView):
template_name = "calendars/yearly.html"
# No here
current_year = datetime.datetime.now().year
current_month = datetime.datetime.now().month
# dispatch is called when the class instance loads
def dispatch(self, request, *args, **kwargs):
self.year = kwargs.get(''year'', "any_default")
# other code
# needed to have an HttpResponse
return super(Yearly, self).dispatch(request, *args, **kwargs)
La solución de despacho encontrada en esta question .
Como la view ya se ha pasado dentro del contexto de la Plantilla, realmente no es necesario preocuparse por ella. En su archivo de plantilla anual.html, es posible acceder a esos atributos de vista simplemente mediante:
{{ view.year }}
{{ view.current_year }}
{{ view.current_month }}
Puedes mantener tu urlconf como es.
Es bueno mencionar que obtener información en el contexto de su plantilla sobrescribe el get_context_data (), por lo que de alguna manera está rompiendo el flujo de bean de acción del django.
Hasta ahora solo he podido acceder a estos parámetros de URL desde el método get_queryset, aunque solo lo he probado con un ListView no con TemplateView. Usaré el parámetro url para crear un atributo en la instancia del objeto, luego usaré ese atributo en get_context_data para rellenar el contexto:
class Yearly(TemplateView):
template_name = "calendars/yearly.html"
current_year = datetime.datetime.now().year
current_month = datetime.datetime.now().month
def get_queryset(self):
self.year = self.kwargs[''year'']
queryset = super(Yearly, self).get_queryset()
return queryset
def get_context_data(self, **kwargs):
context = super(Yearly, self).get_context_data(**kwargs)
context[''current_year''] = self.current_year
context[''current_month''] = self.current_month
context[''year''] = self.year
return context
Para acceder a los parámetros de url en vistas basadas en clases, use self.args
o self.kwargs
para que pueda acceder a él haciendo self.kwargs[''year'']