Il n’est pas clair pour moi comment il est préférable d’accéder aux paramètres d’URL dans les vues basées sur les classes dans Django 1.5.
Considérer ce qui suit:
Voir:
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
RLCONF:
from .views import Yearly
urlpatterns = patterns('',
url(
regex=r'^(?P<year>\d+)/$',
view=Yearly.as_view(),
name='yearly-view'
),
)
Je souhaite accéder au paramètre year
de mon point de vue afin de pouvoir utiliser une logique telle que:
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 mieux au paramètre url dans les CBV, comme ci-dessus, qui est sous-classé de TemplateView
, et où placer idéalement la logique comme celle-ci, par exemple. dans une méthode?
Pour accéder aux paramètres d'URL dans les vues basées sur les classes, utilisez self.args
ou self.kwargs
afin que vous y accédiez en faisant self.kwargs['year']
Si vous passez le paramètre d'URL comme ceci:
http://<my_url>/?order_by=created
Vous pouvez y accéder dans la vue basée sur les classes en utilisant self.request.GET
_ (il 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 plus, comme indiqué ici :
Les vues basées sur les classes génériques de Django incluent désormais automatiquement une variable de vue dans le contexte. Cette variable pointe sur votre objet de vue.
Dans votre view.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 vue est déjà passé dans le contexte Template, vous n'avez pas vraiment besoin de vous en soucier. Dans votre fichier de modèle annual.html, il est possible d'accéder à ces attributs de vue simplement par:
{{ view.year }}
{{ view.current_year }}
{{ view.current_month }}
Vous pouvez conserver votre urlconf tel quel.
Il est bon de mentionner que le fait d’obtenir des informations dans le contexte de votre modèle écrase la méthode get_context_data (); elle interrompt donc le flux de Django action bean.
Jusqu'à présent, je n'ai pu accéder à ces paramètres d'URL qu'à partir de la méthode get_queryset, bien que je ne l'ais essayé qu'avec un ListView et non un TemplateView. Je vais utiliser le paramètre url pour créer un attribut sur l'instance d'objet, puis utiliser cet attribut dans get_context_data pour renseigner 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
Pourquoi ne pas utiliser simplement Python décorateurs pour rendre cela intelligible:
class Yearly(TemplateView):
@property
def year(self):
return self.kwargs['year']