嗨,Stackoverflow社区
我一直在试图理解Django(和Wagtail的流场)是如何在引擎盖下工作的。这样做,我学会了元类,并相信有一个处理的原则。但是有一段代码让我困惑(见下文)。你知道吗
当我们遵循StreamField定义时,这段代码似乎将元组列表传递给一个类构造函数,而这个类构造函数似乎不适合这种类型的列表。这怎么行?你知道吗
如有任何建议,我们将不胜感激。代码如下:
型号.py
这就是我们定义流场的地方。它采用格式为('title',blockType)的元组列表。我们的目标是遵循StreamField呼吁:
class BlogPage(Page):
blogElement = StreamField([
('heading', blocks.CharBlock(classname="full title")),
('paragraph', blocks.TextBlock()),
('picture', ImageChooserBlock()),
], default=[])
字段。py>;流域
当我们跟随对StreamField的调用时,我们到达下面的类构造函数。在这里调用StreamBlock(block类型)会让人困惑:
class StreamField(models.Field):
def __init__(self, block_types, **kwargs):
if isinstance(block_types, Block):
self.stream_block = block_types
elif isinstance(block_types, type):
self.stream_block = block_types()
else:
self.stream_block = StreamBlock(block_types)
super(StreamField, self).__init__(**kwargs)
流块
而对类构造函数的调用将块类型作为参数(包含中定义的三个元组的列表)型号.py)接收类构造函数调用六.带元类作为参数(代码包括在下面):
class StreamBlock(six.with_metaclass(DeclarativeSubBlocksMetaclass, BaseStreamBlock)):
pass
我的问题
这怎么可能?六.带元类它本身是对一个方法的调用,该方法使用两个参数<;gt;和<;gt;,这两个参数本身都是类构造函数(下面包含代码)。你知道吗
StreamBlock不应该容纳接收符合块类型的参数,而这些类型又包含中定义的三个元组的列表吗型号.py?我肯定我在这里遗漏了什么,但就是看不见。如有任何建议,我们将不胜感激。你知道吗
Z轴
上下文 我在下面的上下文中包含了其他代码片段的代码。我知道六.带元类在这个岗位上工作:[哇哦六.带元类()工作? ][1] 但我正在努力解决上述问题。你知道吗
六.带元类
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
# This requires a bit of explanation: the basic idea is to make a dummy
# metaclass for one level of class instantiation that replaces itself with
# the actual metaclass.
class metaclass(meta):
def __new__(cls, name, this_bases, d):
print("In with_metaclass: %s " %d )
return meta(name, bases, d)
return type.__new__(metaclass, 'temporary_class', (), {})
声明性SubBlocksMetaClass
class DeclarativeSubBlocksMetaclass(BaseBlock):
"""
Metaclass that collects sub-blocks declared on the base classes.
(cheerfully stolen from https://github.com/django/django/blob/master/django/forms/forms.py)
"""
def __new__(mcs, name, bases, attrs):
# Collect sub-blocks declared on the current class.
# These are available on the class as `declared_blocks`
current_blocks = []
for key, value in list(attrs.items()):
if isinstance(value, Block):
current_blocks.append((key, value))
value.set_name(key)
attrs.pop(key)
current_blocks.sort(key=lambda x: x[1].creation_counter)
attrs['declared_blocks'] = collections.OrderedDict(current_blocks)
new_class = (super(DeclarativeSubBlocksMetaclass, mcs).__new__(mcs, name, bases, attrs))
# Walk through the MRO, collecting all inherited sub-blocks, to make
# the combined `base_blocks`.
base_blocks = collections.OrderedDict()
for base in reversed(new_class.__mro__):
# Collect sub-blocks from base class.
if hasattr(base, 'declared_blocks'):
base_blocks.update(base.declared_blocks)
# Field shadowing.
for attr, value in base.__dict__.items():
if value is None and attr in base_blocks:
base_blocks.pop(attr)
new_class.base_blocks = base_blocks
return new_class
基本流块
class BaseStreamBlock(Block):
def __init__(self, local_blocks=None, **kwargs):
self._constructor_kwargs = kwargs
super(BaseStreamBlock, self).__init__(**kwargs)
# create a local (shallow) copy of base_blocks so that it can be supplemented by local_blocks
self.child_blocks = self.base_blocks.copy()
if local_blocks:
for name, block in local_blocks:
block.set_name(name)
self.child_blocks[name] = block
self.dependencies = self.child_blocks.values()
目前没有回答
相关问题 更多 >
编程相关推荐