如果我想通过URL路径将多个变量传递给视图,以便可以使用它查找多个对象,我可以通过两种不同的方法来执行此操作:
1。在网址路径中作为关键字参数传递
在FBV和CBV中,我都可以通过网址路径作为kwarg
传递参数:
// Function based view:
path('task/detail/<int:pk>/<int:abc>/', views.task_detail, name='task_detail')`
// Class based view:
path('task/detail/<int:pk>/<int:abc>/', views.TaskDetailView.as_view()
哪个在URL中以mysite.com/task/detail/1/2/
的形式传递。
在FBV中,我可以同时访问kwargs
和request
来获取单独的对象:
// Function based view:
def task_detail(request, pk, abc)
first_object = get_object_or_404(FirstObjectModel, id=pk)
second_object = get_object_or_404(SecondObjectModel, id=abc)
2。在网址路径中作为查询字符串传递
或者,我可以通过查询字符串传递参数,该字符串将被解析,并将参数作为QueryDict
存储在request.GET
中,例如mysite.com/task/detail/?pk=1&abc=2
。
然后我可以通过FBV和CBV来访问它们,如下所示:
// Function based view:
def task_detail(request):
first_object_id = request.GET.get('pk')
second_object_id = request.GET.get('abc')
first_object = get_object_or_404(FirstObjectModel, id=pk)
second_object = get_object_or_404(SecondObjectModel, id=abc)
这些方法中的每一种等效的分类基础视图是什么?为什么和何时在kwargs
上使用query strings
?
答案 0 :(得分:2)
在基于类的视图中,您可以从self.kwargs
的URL中获取关键字参数,并使用self.request.GET
从查询字符串中获取值。
class MyView(TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Use kwargs from URL
context['first_object'] = get_object_or_404(FirstObjectModel, id=self.kwargs['pk'])
context['second_object'] = get_object_or_404(SecondObjectModel, id=self.kwargs['abc'])
# Fetch from GET params
context['first_object'] = get_object_or_404(FirstObjectModel, id=self.request.GET.get('pk'))
context['second_object'] = get_object_or_404(SecondObjectModel, id=self.request.GET.get('abc'))
return context
通常,您将自定义基于特定类的视图,以减少必须编写的代码量。例如,您可以使用DetailView(用于显示对象),然后将第二个对象添加到上下文中。
class MyView(DetailView):
model = FirstObjectModel
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
context['second_object'] = get_object_or_404(SecondObjectModel, id=self.kwargs['abc'])
return context
在URL路径/查询字符串中包含关键字参数的决定与使用基于函数的视图还是基于类的视图是分开的。在Django中,通常会看到/tasks/55/
之类的URL,而不是tasks/?id=55
,因为它们“更干净”。查询字符串通常用于过滤,例如/tasks/?status=complete
。
创建/显示/更新/删除单个对象的基于类的通用视图希望,该子弹/主键位于URL路径中,而不是查询字符串中。您可以使用querystring来获取对象,但是在这种情况下,您需要编写更多代码,例如覆盖get_object
。