在基于 Django 类的视图 (CBV) 中处理 kwargs 关键字参数

Lut*_*elt 2 django django-views django-class-based-views

当我(作为一个 Django 初学者)无法通过pk我的FormView子类中的主键(来自 URL)访问模型对象并试图了解如何正确地做到这一点时,我只是危险地接近疯狂。这很混乱。

那么关键字参数是如何在通用 CBV 中传递的,它们应该如何处理和使用?

(我将自己回答,因为我发现并写了它以便正确理解它。)

Lut*_*elt 5

不要kwargs与其他人混淆kwargs...

  • 请记住,视图最终总是一个函数。您可能还记得“Django 如何处理请求”中的内容,来自 urlconf regexp 的未命名组将被传递到视图 as*args 和命名组 as **kwargs
  • 但是对于 CBV 来说,视图函数实际上是什么或它做什么就不那么明显了,因为它隐藏在 Django 的深处。您可能还记得“使用基于类的视图”,CBV 的as_view()函数将创建并返回实际的视图函数。
  • 因此,关于kwargs处理,首先要记住:在 中urls.py,当您编写类似 的内容时 MyView.as_view(myarg=myvalue),每个此类关键字参数将覆盖 CBV 实例中 CBV 类的同名类属性。这些参数统称为initkwargs
  • 将视图功能实际上执行(我们称之为vvv)是定义一个通用的一个django.views.generic.base。它实例化您的CBV,传递initkwargs给构造函数,存储request*args以及**kwargs在CBV实例同名的属性,最后调用dispatch()的实例。
  • 这里谈到的那些令人困惑的细节之一:这些相同的参数 request*args**kwargs 也将冗余传递到dispatch()直接。(我写调用括号来表示方法而不是数据属性;空括号并不意味着没有参数。)
  • dispatch()查看请求和呼吁 get()post()head()等,这取决于请求类型,再次通过论证。
  • 更多的冗余即将到来:initkwargs冗余存储在vvv.view_initkwargs. (尝试快速忘记这一点,您将很少需要它。)
  • 一旦如此创建的视图被调用,“真实”就会kwargs 被传递给各种通用视图子类和视图混合类中的各种请求处理方法。然而,这些类的结构可能会让你发疯。
    如果您对保持心理健康感兴趣,我强烈建议您将 其用作 Django 内置通用 CBV 的替代品。该软件包以更简单的形式提供了相同的功能。vanilla-views

把它们加起来


(1) initkwargs源自as_view()视图工厂方法的单个关键字参数,并将作为 CBV 类实例的单个属性结束,以及
(2) kwargs源自您的 urlconf 实例中的命名组并最终作为
(2a)关键字参数调用您的 get()post()方法以及令人困惑的是
(2b)kwargs CBV 类实例中的属性。

那么你应该使用哪个kwargs参数或属性? 这篇文章 认为,对于 CBV 而言,使用该属性更自然,并且它还将使您的代码更加统一,因为该参数并非在 CBV 框架内的所有地方都可用。

这是混乱的最终来源:到了这些方法kwargs不会被传递往往不过有一个kwargs参数,自己...

道德

身高self.kwargskwargs参数尽可能不要让initkwargs迷惑你。