django.forms-FormとFieldのつながり
1655 ワード
class DeclarativeFieldsMetaclass(MediaDefiningClass):
"""
Metaclass that collects Fields declared on the base classes.
"""
def __new__(mcs, name, bases, attrs):
# Collect fields from current class.
current_fields = []
for key, value in list(attrs.items()):
if isinstance(value, Field):
current_fields.append((key, value))
attrs.pop(key)
current_fields.sort(key=lambda x: x[1].creation_counter)
attrs['declared_fields'] = OrderedDict(current_fields)
new_class = (super(DeclarativeFieldsMetaclass, mcs)
.__new__(mcs, name, bases, attrs))
# Walk through the MRO.
declared_fields = OrderedDict()
for base in reversed(new_class.__mro__):
# Collect fields from base class.
if hasattr(base, 'declared_fields'):
declared_fields.update(base.declared_fields)
# Field shadowing.
for attr, value in base.__dict__.items():
if value is None and attr in declared_fields:
declared_fields.pop(attr)
new_class.base_fields = declared_fields
new_class.declared_fields = declared_fields
return new_class
DeclarativeFieldsMetaclassはMediaDefiningClassを継承します.MediaDefiningClassはメディア情報を収集しています
django.forms-WidgetとMediaのつながりが紹介されています.
では、D e c l a r a r a tiveFieldsMetaclassがどのようにFieldを収集しているかを具体的に見てみましょう.
まずattrsを巡り、現在のクラス宣言のFieldを収集します.
次に、ベースクラスのdeclared_を巡回します.fields.ベースクラスのshadowing fieldを除去します(フィールドをNoneに設定します).