django - 如果没有定义 self.kwargs 来自哪里的问题?特别是在 django 代码库中的 SingleObjectMixin 类中
问题描述
我正在关注一个 Django 教程,我正在创建一个继承自 (SelectRelatedMixin, DetailView) 的 CBV,当我到达具有名为 get_object 的函数的 SingleObjectMixin 时,我正在查看代码库。它设置
pk=self.kwargs.get(self.pk_url_kwarg)
kwargs 属性从何而来?因为 SingleObjectMixin 仅从一个类“ContextMixin”实例化,并且没有该属性
这是函数的一部分:
def get_object(self, queryset=None):
"""
Returns the object the view is displaying.
By default this requires `self.queryset` and a `pk` or `slug` argument
in the URLconf, but subclasses can override this to return any object.
"""
# Use a custom queryset if provided; this is required for subclasses
# like DateDetailView
if queryset is None:
queryset = self.get_queryset()
# Next, try looking up by primary key.
pk = self.kwargs.get(self.pk_url_kwarg)
slug = self.kwargs.get(self.slug_url_kwarg)
if pk is not None:
queryset = queryset.filter(pk=pk)
解决方案
从django-2.2开始,它源自类 [GitHub]setup(..)
中的方法View
:
def setup(self, request, *args, **kwargs): """Initialize attributes shared by all view methods.""" self.request = request self.args = args self.kwargs = kwargs
此方法由方法 [GitHub]中构造setup(..)
的包装方法调用:view
as_view
@classonlymethod def as_view(cls, **initkwargs): # ... def view(request, *args, **kwargs): self = cls(**initkwargs) # ... self.setup(request, *args, **kwargs) # ... return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # ... return view
如果您将基于类的视图添加到路径定义,您可以使用.as_view(..)
. 该函数将构造一个由 定义的函数def view(..)
。该视图将构造一个新的视图实例,并self.setup(request, *args, **kwargs)
在该视图上调用。接下来,它将调用将调用self.dispatch(request, *args, **kwargs)
分派给正确的方法(.get(..)
、.post(..)
等方法)。
AMixin
不需要有一个定义它的父类,因为 aMixin
是混合到方法解析 order中的,并且大多数基于类的视图都将View
[Django-doc]作为基本类,然后通过添加额外的逻辑混合混合,并覆盖某些方法。由于django-2.2,因此您可以覆盖该setup(..)
方法。例如“预处理” self.request
,self.args
和self.kwargs
.
在django-2.2之前,它是在view
构造的函数中设置的:
@classonlymethod def as_view(cls, **initkwargs): # ... def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # ... return view
推荐阅读
- python - 具有修复资源的多处理
- java - (已解决)使用 Files.copy API 复制的文件在库中不可见
- r - 在 R 中可视化几列的正确方法是什么?
- react-native - React Native Navigation 导航未从 useEffect 触发
- python - 根据前两个字母删除分类变量
- mysql - 使用多语言站点(polylang)搜索和替换查询
- linux - Flutter linux build error A required package was not found
- java - Quartz Scheduler + Spring:创建触发器时如何从JobStore获取初始cron表达式?
- javascript - 不能让测试失败?选择器可能是错误的
- c++ - Opencv.exe 中 0x00007FFFB9423B29 处未处理的异常:Microsoft C++ 异常:内存位置的 cv::Exception