Nie jest dla mnie jasne, jak najlepiej uzyskać dostęp do parametrów URL w widokach opartych na klasach w Django 1.5.
Rozważ następujące:
Widok:
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'
),
)
Chcę uzyskać dostęp do year
parametru w moim widoku, więc mogę wykonać logikę, taką jak:
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
})
Jak najlepiej uzyskać dostęp do parametru url w CBV, takim jak powyższy, który jest podklasą TemplateView
i gdzie najlepiej umieścić taką logikę, np. w metodzie?
extra_context
dyktowaniadjango2
, patrz tutajOdpowiedzi:
Aby uzyskać dostęp do parametrów adresu URL w widokach opartych na klasach, użyj
self.args
lubself.kwargs
tak, aby uzyskać do niego dostęp, wykonującself.kwargs['year']
źródło
year = self.kwargs['year']
w widoku, który dostajęNameError: self not defined
.NameError
, gdzie próbujesz zrobićyear = self.kwargs['year']
? Powinieneś to robić metodą, nie możesz tego robić na poziomie klasy. Na przykład używasz a,TemplateView
co oznacza, że wykonasz logikę w swoimget_context_data
zastąpieniu.def __init__(self):
funkcji w klasie, jeśli chcesz uzyskać do niej dostęp poza innymi funkcjami.W przypadku przekazania parametru adresu URL w ten sposób:
Możesz uzyskać do niego dostęp w widoku opartym na klasach, używając
self.request.GET
(nie jest wyświetlany wself.args
ani wself.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)
źródło
qs=<Object>.objects.<method>
Znalazłem to eleganckie rozwiązanie i dla django 1.5 lub nowszego, jak wskazano tutaj :
W Twoim views.py:
from django.views.generic.base import TemplateView class Yearly(TemplateView): template_name = "calendars/yearly.html" # Not 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)
Rozwiązanie wysyłki znalezione w tym pytaniu .
Ponieważ widok jest już przekazany w kontekście szablonu, nie musisz się o to martwić. W pliku szablonu yearly.html można uzyskać dostęp do tych atrybutów widoku w prosty sposób:
Możesz zachować swój adres urlconf bez zmian .
Warto wspomnieć, że pobranie informacji do kontekstu szablonu nadpisuje metodę get_context_data (), więc w jakiś sposób przerywa przepływ fasoli akcji django .
źródło
Do tej pory mogłem uzyskać dostęp do tych parametrów adresu URL tylko z metody get_queryset, chociaż próbowałem tego tylko z ListView, a nie TemplateView. Użyję parametru url do utworzenia atrybutu w instancji obiektu, a następnie użyję tego atrybutu w get_context_data, aby wypełnić kontekst:
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
źródło
context['year'] = self.kwargs['year']
? Powinien być dostępny w każdym miejscu w klasie.Co powiesz na użycie dekoratorów Pythona, aby uczynić to zrozumiałym:
class Yearly(TemplateView): @property def year(self): return self.kwargs['year']
źródło