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

时间:2016-04-07 18:25:04

标签: django django-views django-class-based-views

当我(作为一个人)时,我的危险已接近疯狂 Django初学者)没能 通过主键pk访问模型对象(来自URL) 在我的FormView子类中,并试图了解如何 这样做正确。 这令人困惑。

那么关键字参数如何在通用CBV中传递 应如何处理和使用?

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

1 个答案:

答案 0 :(得分:4)

不要将kwargs与其他kwargs ...

混淆
  • 请记住,视图最终总是一个功能。 您可能还记得"How Django processes a request", 来自urlconf regexp的未命名组将作为*args传递给视图 并将命名组命名为**kwargs
  • 但是对于CBV来说,实际上该视图功能并不那么明显 是或者它做了什么,因为它隐藏在Django内部。 您可能还记得"Using class-based views", 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()。 (我编写调用parens来指示方法而不是数据属性; 空的parens并不意味着没有争论。)
  • dispatch()查看请求和调用 get()post()head()等,具体取决于请求类型, 再次传递论据。
  • 更多冗余即将来临: initkwargs冗余地存储在vvv.view_initkwargs中。 (尽量忘记这一点,你很少需要它。)
  • 一旦调用了如此创建的视图,就会出现“真实”kwargs 传递给各种各样的请求处理方法 通用视图子类和视图mixin类。 然而,那些班级的结构可能会让你发疯。 如果您对保持心理健康感兴趣, 我强烈建议使用vanilla-views
    作为Django内置通用CBV的替代品。 该软件包以更简单的形式提供相同的功能。
  • 总结一下:(1) initkwargs来自 as_view()视图工厂方法的各个关键字参数 并将最终成为 CBV类实例的各个属性 和(2) kwargs源于此 urlconf实例中的命名组 最终作为(2a)关键字参数调用您的 get()post()方法以及令人困惑的方法 (2b) CBV类实例中的属性kwargs
  • 那么你应该使用哪个kwargs参数或属性? This post 认为使用该属性对于CBV更为自然 它还会使你的代码更多 统一,因为这个论点并非在所有地方都可用 在CBV框架内。
  • 这是混淆的最后根源: kwargs 尽管如此自己有一个kwargs参数......

道德:尽可能优先于self.kwargs kwargs论点,不要让initkwargs迷惑你。