在基于 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
混淆你。
当我(作为一个
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
混淆你。