Python 基于 Django 类的视图 (TemplateView) 中的 URL 参数和逻辑

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15754122/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:55:09  来源:igfitidea点击:

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

pythondjangodjango-class-based-views

提问by

It is unclear to me how it is best to access URL-parameters in class-based-views in Django 1.5.

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

Consider the following:

考虑以下:

View:

看法:

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'
    ),
)

I want to access the yearparameter in my view, so I can do logic like:

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

How would one best access the url parameter in CBVs like the above that is subclassed of TemplateViewand where should one ideally place the logic like this, eg. in a method?

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

回答by Ngenator

To access the url parameters in class based views, use self.argsor self.kwargsso you would access it by doing self.kwargs['year']

要访问基于类的视图中的 url 参数,请使用self.argsor self.kwargsso 您可以通过执行以下操作来访问它self.kwargs['year']

回答by hellsgate

So far I've only been able to access these url parameters from within the get_queryset method, although I've only tried it with a ListView not a TemplateView. I'll use the url param to create an attribute on the object instance, then use that attribute in get_context_data to populate the context:

到目前为止,我只能从 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

回答by niekas

In case you pass URL parameter like this:

如果您像这样传递 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.argsnor in self.kwargs):

您可以在基于类的视图中访问它,使用self.request.GET(它不在 中self.args也不在 中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)

回答by Evhz

I found this elegant solution, and for django 1.5 or higher, as pointed out here:

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

Django's generic class based views now automatically include a view variable in the context. This variable points at your view object.

Django 的基于通用类的视图现在自动在上下文中包含一个视图变量。此变量指向您的视图对象。

In your views.py:

在您的 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)

The dispatch solution found in this question.
As the viewis 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:

在这个问题中找到的调度解决方案。
由于视图已在模板上下文中传递,因此您无需担心它。在你的模板文件 yearly.html 中,可以简单地通过以下方式访问这些视图属性:

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

You can keep your urlconfas it is.

您可以保持 urlconf原样。

It's worth mentioning that getting information into your template's context overwrites the get_context_data(), so it is somehow breaking the django's action beanflow.

值得一提的是,将信息放入模板的上下文会覆盖 get_context_data(),因此它以某种方式破坏了 django 的操作 bean流程。

回答by danizen

How about just use Python decorators to make this intelligible:

仅使用 Python 装饰器来使这变得易于理解如何:

class Yearly(TemplateView):

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