URL-parameters and logic in Django class-based views (TemplateView)

我不清楚在 Django 1.5中如何最好地访问基于类的视图中的 URL 参数。

考虑以下几点:

观看内容:

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

返回文章页面

from .views import Yearly




urlpatterns = patterns('',
url(
regex=r'^(?P<year>\d+)/$',
view=Yearly.as_view(),
name='yearly-view'
),
)

我想访问我的视图中的 year参数,这样我就可以进行如下逻辑:

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

如何最好地访问像上面这样的 CBV 中的 url 参数,它是 TemplateView的子类,以及理想情况下应该将这样的逻辑放在哪里,例如放在一个方法中?

118951 次浏览

要访问基于类的视图中的 url 参数,请使用 self.argsself.kwargs,这样您就可以通过执行 self.kwargs['year']来访问它

到目前为止,我只能在 get _ queryset 方法中访问这些 url 参数,尽管我只在 ListView 而不是 TemplateView 中尝试过。我将使用 url 参数在对象实例上创建一个属性,然后在 get _ context _ data 中使用该属性来填充上下文:

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

如果你像这样传递 URL 参数:

http://<my_url>/?order_by=created

You can access it in class based view by using self.request.GET (its not presented in self.args nor in self.kwargs):

from django.views.generic.list import ListView


class MyClassBasedView(ListView):
...
def get_queryset(self):
order_by = self.request.GET.get('order_by') or '-created'
qs = super().get_queryset()
return qs.order_by(order_by)

我找到了这个优雅的解决方案,对于 django 1.5或更高版本,正如 给你所指出的:

Django 的基于类的通用视图现在自动包含一个视图 这个变量指向你的视图对象。

In your 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)

在此 有个问题中找到的分派解决方案。
As the 风景 is already passed within Template context, you don't really need to worry about it. In your template file yearly.html, it is possible to access those view attributes simply by:

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

你可以 保持冷静,因为它是。

值得一提的是,将信息放入模板的上下文中会覆盖 get _ context _ data () ,因此会以某种方式破坏 django 的 动作豆流。

不如直接使用 Python 修饰器来使这个问题变得更易理解:

class Yearly(TemplateView):


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