working m2m and fk self relations with forwardref

This commit is contained in:
collerek
2021-01-12 14:38:22 +01:00
parent 8b67c83d0c
commit 4209d37364
10 changed files with 62 additions and 25 deletions

View File

@ -110,6 +110,7 @@ def register_reverse_model_fields(model_field: Type["ForeignKeyField"]) -> None:
related_name=model_field.name,
owner=model_field.to,
self_reference=model_field.self_reference,
self_reference_primary=model_field.self_reference_primary,
)
# register foreign keys on through model
adjust_through_many_to_many_model(model_field=model_field)

View File

@ -586,7 +586,7 @@ class ModelMetaclass(pydantic.main.ModelMetaclass):
new_model = populate_meta_tablename_columns_and_pk(name, new_model)
populate_meta_sqlalchemy_table_if_required(new_model.Meta)
expand_reverse_relationships(new_model)
for field_name, field in new_model.Meta.model_fields.items():
for field in new_model.Meta.model_fields.values():
register_relation_in_alias_manager(field=field)
if new_model.Meta.pkname not in attrs["__annotations__"]:

View File

@ -125,7 +125,13 @@ class Model(NewBaseModel):
)
):
through_field = previous_model.Meta.model_fields[related_name]
rel_name2 = through_field.default_target_field_name() # type: ignore
if (
through_field.self_reference
and related_name == through_field.self_reference_primary
):
rel_name2 = through_field.default_source_field_name() # type: ignore
else:
rel_name2 = through_field.default_target_field_name() # type: ignore
previous_model = through_field.through # type: ignore
if previous_model and rel_name2:

View File

@ -436,6 +436,8 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
Populates Meta table of the Model which is left empty before.
Sets self_reference flag on models that links to themselves.
Calls the pydantic method to evaluate pydantic fields.
:param localns: local namespace
@ -446,7 +448,7 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
globalns = sys.modules[cls.__module__].__dict__.copy()
globalns.setdefault(cls.__name__, cls)
fields_to_check = cls.Meta.model_fields.copy()
for field_name, field in fields_to_check.items():
for field in fields_to_check.values():
if field.has_unresolved_forward_refs():
field = cast(Type[ForeignKeyField], field)
field.evaluate_forward_ref(globalns=globalns, localns=localns)