通过FBV中的kwarg和查询字符串传递参数的CBV等价方式是什么?

时间:2019-08-31 12:36:43

标签: django django-views

如果我想通过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中,我可以同时访问kwargsrequest来获取单独的对象:

// 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

1 个答案:

答案 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