allow customization of through model relation names

This commit is contained in:
collerek
2021-04-16 16:27:07 +02:00
parent 1c24ade8c8
commit 15e12ef55b
7 changed files with 223 additions and 13 deletions

View File

@ -53,6 +53,12 @@ class BaseField(FieldInfo):
"is_relation", None
) # ForeignKeyField + subclasses
self.is_through: bool = kwargs.pop("is_through", False) # ThroughFields
self.through_relation_name = kwargs.pop("through_relation_name", None)
self.through_reverse_relation_name = kwargs.pop(
"through_reverse_relation_name", None
)
self.skip_reverse: bool = kwargs.pop("skip_reverse", False)
self.skip_field: bool = kwargs.pop("skip_field", False)

View File

@ -318,29 +318,23 @@ class ForeignKeyField(BaseField):
"""
return self.related_name or self.owner.get_name() + "s"
def default_target_field_name(self, reverse: bool = False) -> str:
def default_target_field_name(self) -> str:
"""
Returns default target model name on through model.
:param reverse: flag to grab name without accessing related field
:type reverse: bool
:return: name of the field
:rtype: str
"""
self_rel_prefix = "from_" if not reverse else "to_"
prefix = self_rel_prefix if self.self_reference else ""
return f"{prefix}{self.to.get_name()}"
prefix = "from_" if self.self_reference else ""
return self.through_reverse_relation_name or f"{prefix}{self.to.get_name()}"
def default_source_field_name(self, reverse: bool = False) -> str:
def default_source_field_name(self) -> str:
"""
Returns default target model name on through model.
:param reverse: flag to grab name without accessing related field
:type reverse: bool
:return: name of the field
:rtype: str
"""
self_rel_prefix = "to_" if not reverse else "from_"
prefix = self_rel_prefix if self.self_reference else ""
return f"{prefix}{self.owner.get_name()}"
prefix = "to_" if self.self_reference else ""
return self.through_relation_name or f"{prefix}{self.owner.get_name()}"
def evaluate_forward_ref(self, globalns: Any, localns: Any) -> None:
"""

View File

@ -122,6 +122,9 @@ def ManyToMany(
skip_reverse = kwargs.pop("skip_reverse", False)
skip_field = kwargs.pop("skip_field", False)
through_relation_name = kwargs.pop("through_relation_name", None)
through_reverse_relation_name = kwargs.pop("through_reverse_relation_name", None)
if through is not None and through.__class__ != ForwardRef:
forbid_through_relations(cast(Type["Model"], through))
@ -158,6 +161,8 @@ def ManyToMany(
related_orders_by=related_orders_by,
skip_reverse=skip_reverse,
skip_field=skip_field,
through_relation_name=through_relation_name,
through_reverse_relation_name=through_reverse_relation_name,
)
Field = type("ManyToMany", (ManyToManyField, BaseField), {})

View File

@ -112,6 +112,8 @@ def register_reverse_model_fields(model_field: "ForeignKeyField") -> None:
self_reference_primary=model_field.self_reference_primary,
orders_by=model_field.related_orders_by,
skip_field=model_field.skip_reverse,
through_relation_name=model_field.through_reverse_relation_name,
through_reverse_relation_name=model_field.through_relation_name,
)
# register foreign keys on through model
model_field = cast("ManyToManyField", model_field)