мне удалось сделать это с помощью подклассов метакласса по умолчанию:
class MySchemaMeta(SchemaMeta):
@classmethod
def get_declared_fields(mcs, klass, cls_fields, inherited_fields, dict_cls):
fields = super().get_declared_fields(klass, cls_fields, inherited_fields, dict_cls)
FIELDS = ('field_1', 'field_2',..., 'field_42')
for field in FIELDS:
fields.update({fluid: Float()})
return fields
class MySchema(Schema, metaclass=MySchemaMeta):
class Meta:
strict = True
я сделал это более общий характер:
class DynamicSchemaOpts(SchemaOpts):
def __init__(self, meta):
super().__init__(meta)
self.auto_fields = getattr(meta, 'auto_fields', [])
class DynamicSchemaMeta(SchemaMeta):
@classmethod
def get_declared_fields(mcs, klass, cls_fields, inherited_fields, dict_cls):
fields = super().get_declared_fields(klass, cls_fields, inherited_fields, dict_cls)
for auto_field_list in klass.opts.auto_fields:
field_names, field = auto_field_list
field_cls = field['cls']
field_args = field.get('args', [])
field_kwargs = field.get('kwargs', {})
for field_name in field_names:
fields.update({field_name: field_cls(*field_args, **field_kwargs)})
return fields
class MySchema(Schema, metaclass=DynamicSchemaMeta):
OPTIONS_CLASS = DynamicSchemaOpts
class Meta:
strict = True
auto_fields = [
(FIELDS,
{'cls': Float}),
]
Я не писал
class Meta:
strict = True
auto_fields = [
(FIELDS, Float()),
]
, потому что тогда все эти поля будут Sh те же Field
экземпляр.
Field
и его арг/kwargs должны быть указаны отдельно:
class Meta:
strict = True
auto_fields = [
(FIELDS,
{'cls': Nested,
'args': (MyEmbeddedSchema),
'kwargs': {'required': True}
}),
]
У меня нет ни одного примера, случай использования неисправного из-за нескольких полей, разделяющих один и тот же экземпляр, но это не звучит безопасно. Если эта мера предосторожности бесполезно, то код может быть упрощен и более удобным для чтения:
class Meta:
strict = True
auto_fields = [
(FIELDS, Nested(MyEmbeddedSchema, required=True)),
]
Очевидно, что этот ответ является специфическим для Зефир и не относится к другим библиотекам ODM/ОРМ.
Это здорово. Он использует только Python, а не специфические механизмы Marshmallow. –