问题:Django基于类的视图:如何将其他参数传递给as_view方法?
我有一个基于类的自定义视图
# 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')
我是否需要重写任何方法才能做到这一点?
回答 0
如果您的urlconf看起来像这样:
url(r'^(?P<slug>[a-zA-Z0-9-]+)/$', MyView.as_view(), name = 'my_named_view')
那么该子弹将在您的视图函数(例如“ get_queryset”)中可用,如下所示:
self.kwargs['slug']
回答 1
传递给该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
回答 2
值得注意的是,您不需要重写get_object()
即可基于作为关键字arg传递的段来查找对象-您可以使用SingleObjectMixin
https://docs.djangoproject.com/en/1.5/ref/基于类的视图/ mixins-单个对象/#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'
)
回答 3
如果要向模板的上下文中添加对象,则可以覆盖get_context_data
并添加到其上下文中。如果您需要request.user,那么请求也是自我的一部分。
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
回答 4
您可以从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中传递即可。
回答 5
如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
回答 6
对于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'),
]