Paramètres URL et logique dans les vues basées sur les classes Django (TemplateView)

Je ne vois pas comment il est préférable d’accéder aux parameters URL dans les vues basées sur les classes dans Django 1.5.

Considérer ce qui suit:

Vue:

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\d+)/$', view=Yearly.as_view(), name='yearly-view' ), ) 

Je veux accéder au paramètre de l’ year à mon avis, donc je peux faire de la logique comme:

 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}) 

Comment accéder au paramètre url dans les CBV comme ci-dessus qui est sous-classé de TemplateView et où placer idéalement la logique comme ceci, par exemple. dans une méthode?

Pour accéder aux parameters d’url dans les vues basées sur des classes, utilisez self.args ou self.kwargs afin d’y accéder en faisant self.kwargs['year']

Si vous transmettez un paramètre d’URL comme celui-ci:

 http:///?order_by=created 

Vous pouvez y accéder en vue basée sur les classes en utilisant self.request.GET (ce n’est pas présenté dans self.args ni dans 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) 

J’ai trouvé cette solution élégante, et pour django 1.5 ou supérieur, comme indiqué ici :

Les vues de classe génériques de Django incluent désormais automatiquement une variable de vue dans le contexte. Cette variable pointe vers votre object vue.

Dans vos vues.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 solution d’expédition trouvée dans cette question .
Comme la vue est déjà passée dans le contexte du modèle, vous n’avez pas vraiment besoin de vous en préoccuper. Dans votre fichier de modèle annuel.html, il est possible d’accéder à ces atsortingbuts de vue simplement en:

 {{ view.year }} {{ view.current_year }} {{ view.current_month }} 

Vous pouvez garder votre urlconf tel quel.

Il est bon de mentionner que le fait d’obtenir des informations dans le contexte de votre modèle écrase le get_context_data (), ce qui brise en quelque sorte le stream de bean de l’action du django.

Jusqu’à présent, je n’ai pu accéder à ces parameters d’url qu’à partir de la méthode get_queryset, même si je ne l’ai essayée qu’avec un ListView et non un TemplateView. Je vais utiliser le paramètre url pour créer un atsortingbut sur l’instance d’object, puis utiliser cet atsortingbut dans get_context_data pour remplir le contexte:

 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 

Que diriez-vous d’utiliser les décorateurs Python pour rendre cela intelligible:

 class Yearly(TemplateView): @property def year(self): return self.kwargs['year']