首页 文章

Django基于类的视图:如何将其他参数传递给as_view方法?

提问于
浏览
77

我有一个基于类的自定义视图

# myapp/views.py
from django.views.generic import *

class MyView(DetailView):
    template_name = 'detail.html'
    model = MyModel

    def get_object(self, queryset=None):
        return queryset.get(slug=self.slug)

我想像这样传入slug参数(或其他参数到视图)

MyView.as_view(slug='hello_world')

我是否需要覆盖任何方法才能执行此操作?

6 回答

  • 13

    传递给 as_view 方法的每个参数都是View类的实例变量 . 这意味着要添加 slug 作为参数,您必须将其创建为子类中的实例变量:

    # myapp/views.py
    from django.views.generic import DetailView
    
    class MyView(DetailView):
        template_name = 'detail.html'
        model = MyModel
        # additional parameters
        slug = None
    
        def get_object(self, queryset=None):
            return queryset.get(slug=self.slug)
    

    这应该使 MyView.as_view(slug='hello_world') 工作 .

    如果您通过关键字传递变量,请使用Erikkson先生的建议:https://stackoverflow.com/a/11494666/9903

  • 7

    如果你的urlconf看起来像这样:

    url(r'^(?P<slug>[a-zA-Z0-9-]+)/$', MyView.as_view(), name = 'my_named_view')
    

    然后slug将在你的视图函数(例如'get_queryset')中可用,如下所示:

    self.kwargs['slug']
    
  • 95

    它需要覆盖 get_object() 才能根据作为关键字arg传递的slug查找对象 - 您可以使用 SingleObjectMixin https://docs.djangoproject.com/en/1.5/ref/class-based-views/mixins-single-object/#singleobjectmixin的属性

    # views.py
    class MyView(DetailView):
        model = MyModel
        slug_field = 'slug_field_name'
        slug_url_kwarg = 'model_slug'
        context_object_name = 'my_model'
    
    # urls.py
    url(r'^(?P<model_slug>[\w-]+)/$', MyView.as_view(), name = 'my_named_view')
    
    # mymodel_detail.html
    {{ my_model.slug_field_name }}
    

    slug_fieldslug_url_kwarg 默认为 'slug'

  • 73

    如果要将对象添加到模板的上下文中,可以覆盖 get_context_data 并添加到其上下文 . 如果您需要request.user,请求也是self的一部分 .

    def get_context_data(self, **kwargs):
            context = super(MyTemplateView, self).get_context_data(**kwargs)
            if 'slug' in self.kwargs:
                context['object'] = get_object_or_404(MyObject, slug=self.kwargs['slug'])
                context['objects'] = get_objects_by_user(self.request.user)
    
            return context
    
  • 17

    您可以从urls.py传递参数https://docs.djangoproject.com/en/1.7/topics/http/urls/#passing-extra-options-to-view-functions

    这也适用于通用视图 . 例:

    url(r'^$', views.SectionView.as_view(), { 'pk': 'homepage', 'another_param':'?'}, name='main_page'),
    

    在这种情况下,传递给视图的参数不一定是View类的实例变量 . 使用此方法,您无需将默认页面名称硬编码到YourView模型中,但您可以将其作为urlconf中的参数传递 .

  • 9

    Yaroslav Nikitenko所述,如果您不想将新的实例变量硬编码到View类,您可以pass extra options to view functionsurls.py 这样:

    url(r'^$', YourView.as_view(), {'slug': 'hello_world'}, name='page_name')
    

    我只是想在视图中添加如何使用它 . 您可以实现以下方法之一:

    # If slug is optional
    def the_function(self, request, slug=None):
        # use slug here
    
    # if slug is an optional param among others
    def the_function(self, request, **kwargs):
        slug = kwargs.get("slug", None)
        other_param = kwargs.get("other_param", None)
    
    # If slug is required
    def the_function(self, request, slug):
        # use slug here
    

相关问题