vistas urls template genericas clases based basadas python django django-class-based-views

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'']