110

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

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

我是否需要重写任何方法才能做到这一点?

4

7 回答 7

124

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

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

那么 slug 将在您的视图函数(例如“get_queryset”)中可用,如下所示:

self.kwargs['slug']
于 2012-07-15T18:54:02.867 回答
101

传递给该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

于 2012-07-15T19:04:13.840 回答
19

值得注意的是,您无需重写get_object()即可根据作为关键字 arg 传递的 slug 查找对象 - 您可以使用SingleObjectMixin https://docs.djangoproject.com/en/1.5/ref/的属性基于类的视图/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_field默认slug_url_kwarg'slug'

于 2013-06-19T03:17:32.473 回答
15

如果要将对象添加到模板的上下文中,您可以覆盖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
于 2012-10-08T18:24:18.870 回答
14

您可以从 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'),

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

于 2015-03-26T21:12:51.887 回答
8

正如Yaroslav Nikitenko 所说,如果您不想将新的实例变量硬编码到 View 类,您可以传递额外的选项来查看函数urls.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
于 2015-05-12T19:53:23.690 回答
4

对于 django 3.0,这对我有用:

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

class MyView(DetailView):
    template_name = 'detail.html'
    slug = None

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

# myapp/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('slug/<slug:slug>/', views.MyView.as_view(), name='myview_by_tag'),
]
于 2020-05-27T15:46:34.300 回答