【问题标题】:What is the CBV equivalent of passing params via kwargs and query strings in a FBV?通过 kwargs 和 FBV 中的查询字符串传递参数的 CBV 等效项是什么?
【发布时间】:2020-01-04 09:03:31
【问题描述】:

如果我想通过 URL 路径将多个变量传递给视图,以便我可以使用它来查找 多个 对象,我有几种不同的方法可以做到这一点:

1.在 URL 路径中作为关键字参数传递

我可以在 FBV 和 CBV 中通过 url 路径将参数作为 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。在 URL 路径中作为查询字符串传递

或者,我可以通过查询字符串传递参数,该字符串被解析,参数存储为request.GET 中的QueryDict,例如mysite.com/task/detail/?pk=1&amp;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

【问题讨论】:

    标签: django django-views


    【解决方案1】:

    在基于类的视图中,您可以从 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.

    创建/显示/更新/删除单个对象的基于类的通用视图期望 slug/主键位于 URL 路径中,而不是查询字符串中。您可以使用查询字符串来获取对象,但在这种情况下,您需要编写更多代码,例如覆盖get_object

    【讨论】:

    • 谢谢,一个非常全面的答案。所以没有性能或安全差异,只是使用这两种方法的风格/约定?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 2014-02-13
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 2023-04-05
    相关资源
    最近更新 更多