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

Handling of kwargs keyword arguments in Django class-based views (CBVs)

当我(作为一个 Django初学者)失败 通过主键 pk 访问模型对象(来自 URL) 在我的 FormView 子类中并试图了解如何 这样做。 令人困惑。

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

(我要自己回答,因为我发现了它并写了下来 为了正确理解它。)

不要将 kwargs 与其他 kwargs...

混淆
  • 请记住,视图最终总是函数。 你可能还记得 "How Django processes a request", 来自 urlconf 正则表达式的未命名组将作为 *args 传递给视图 并将组命名为 **kwargs.
  • 但对于 CBV,该视图的实际功能不太明显 是或它做什么,因为它隐藏在 Django 的深处。 您可能还记得 "Using class-based views", CBV 的 as_view() 函数将创建和 return 实际查看功能。
  • 因此,关于 kwargs 处理,首先要记住的是: 在 urls.py 中,当你写类似 MyView.as_view(myarg=myvalue), 每个这样的 关键字参数 将覆盖同名的 class 属性 CBV 实例中的 CBV class。 这些参数统称为 initkwargs.
  • 实际执行的视图函数(让我们称之为vvv) 是通用的 在 django.views.generic.base 中定义。 它 实例化 你的 CBV,将 initkwargs 传递给构造函数, 将 request*args**kwargs 存储在同名的 CBV 实例中的属性, 最后在实例上调用 dispatch()
  • 这里出现了一个令人困惑的细节: 那些 相同的参数 request*args**kwargs 也将 冗余地 直接 传递给 dispatch()。 (我写 call parens 来指示方法而不是数据属性; 空括号并不意味着没有参数。)
  • dispatch() 查看请求并调用 get()post()head() 等,具体取决于请求类型, 再次传递参数。
  • 更多冗余即将到来: initkwargs 冗余存储在 vvv.view_initkwargs 中。 (试着尽快忘记它,你很少需要它。)
  • 调用如此创建的视图后,“真实的”kwargs 被传递给各种请求处理方法 通用视图 subclasses 和视图 mixin classes。 然而,那些 classes 的结构会让你抓狂。
    如果您有兴趣保持心理健康, 我强烈建议使用 vanilla-views
    作为 Django 内置通用 CBV 的替代品。 该软件包以非常简单的形式提供了相同的功能。

总结一下


(1) initkwargs 源于 as_view() 视图工厂方法的单个关键字参数 最终会成为 CBV class 实例的个别属性 和
(2) kwargs 源于 urlconf 实例中的命名组 并最终成为
(2a) 调用您的关键字参数 get()post() 方法以及令人困惑的
(2b) 您的 CBV class 实例中的属性 kwargs

那么您应该使用kwargs 参数还是属性? This post 认为使用该属性对于 CBV 来说更自然 并且 它也会让你的代码更 uniform,因为论证并非在所有地方都可用 在 CBV 框架内。

这是混乱的最终来源: kwargs 经常传递给的那些方法 然而 do 自己有一个 kwargs 参数...

道德

尽可能选择 self.kwargs 而不是 kwargs 论点,不要让 initkwargs 混淆你。