diff --git a/ormar/models/metaclass.py b/ormar/models/metaclass.py index 452fa47..a67f4f8 100644 --- a/ormar/models/metaclass.py +++ b/ormar/models/metaclass.py @@ -240,7 +240,8 @@ def verify_constraint_names( ) -> None: """ Verifies if redefined fields that are overwritten in subclasses did not remove - any name of the column that is used in constraint as it will fail. + any name of the column that is used in constraint as it will fail in sqlalchemy + Table creation. :param base_class: one of the parent classes :type base_class: Model or model parent class diff --git a/ormar/models/modelproxy.py b/ormar/models/modelproxy.py index b5d7ffe..5ecea9a 100644 --- a/ormar/models/modelproxy.py +++ b/ormar/models/modelproxy.py @@ -55,9 +55,11 @@ class ModelTableProxy: @classmethod def get_related_field_name(cls, target_field: Type["BaseField"]) -> str: if issubclass(target_field, ormar.fields.ManyToManyField): - return cls.resolve_relation_name(target_field.through, cls) + return cls.resolve_relation_name( + target_field.through, cls, explicit_multi=True + ) if target_field.virtual: - return cls.resolve_relation_name(target_field.to, cls) + return target_field.related_name or cls.get_name() + "s" return target_field.to.Meta.pkname @staticmethod @@ -113,7 +115,7 @@ class ModelTableProxy: target_field, ormar.fields.ManyToManyField ): return self.pk - related_name = self.resolve_relation_name(self, target_field.to) + related_name = target_field.name related_model = getattr(self, related_name) return None if not related_model else related_model.pk diff --git a/ormar/relations/querysetproxy.py b/ormar/relations/querysetproxy.py index b5cad21..1bbfdf2 100644 --- a/ormar/relations/querysetproxy.py +++ b/ormar/relations/querysetproxy.py @@ -33,9 +33,11 @@ class QuerysetProxy(ormar.QuerySetProtocol): self._queryset: Optional["QuerySet"] = qryset self.type_: "RelationType" = type_ self._owner: "Model" = self.relation.manager.owner - self.related_field = self._owner.resolve_relation_field( - self.relation.to, self._owner + self.related_field_name = ( + self._owner.Meta.model_fields[self.relation.field_name].related_name + or self._owner.get_name() + "s" ) + self.related_field = self.relation.to.Meta.model_fields[self.related_field_name] self.owner_pk_value = self._owner.pk @property diff --git a/ormar/relations/relation.py b/ormar/relations/relation.py index 68b8334..5e196a2 100644 --- a/ormar/relations/relation.py +++ b/ormar/relations/relation.py @@ -54,7 +54,7 @@ class Relation: field_name=self.field_name, data_=cleaned_data, ) - relation_name = self._owner.resolve_relation_name(self._owner, self.to) + relation_name = self.field_name self._owner.__dict__[relation_name] = cleaned_data self._to_remove = set() diff --git a/tests/test_inheritance_concrete.py b/tests/test_inheritance_concrete.py index f8f9ce4..a8031c7 100644 --- a/tests/test_inheritance_concrete.py +++ b/tests/test_inheritance_concrete.py @@ -118,6 +118,7 @@ class Bus(Car): metadata = metadata database = db + owner: Person = ormar.ForeignKey(Person, related_name="buses") max_persons: int = ormar.Integer() @@ -271,14 +272,30 @@ async def test_inheritance_with_relation(): await Truck( name="Shelby wanna be", max_capacity=1400, owner=sam, co_owner=joe ).save() + await Bus(name="Unicorn", max_persons=50, owner=sam, co_owner=joe).save() shelby = await Truck.objects.select_related(["owner", "co_owner"]).get() assert shelby.name == "Shelby wanna be" assert shelby.owner.name == "Sam" assert shelby.co_owner.name == "Joe" + assert shelby.max_capacity == 1400 - joe_check = await Person.objects.select_related("coowned_trucks").get( - name="Joe" - ) + unicorn = await Bus.objects.select_related(["owner", "co_owner"]).get() + assert unicorn.name == "Unicorn" + assert unicorn.owner.name == "Sam" + assert unicorn.co_owner.name == "Joe" + assert unicorn.max_persons == 50 + + joe_check = await Person.objects.select_related( + ["coowned_trucks", "coowned_buses"] + ).get(name="Joe") assert joe_check.pk == joe.pk assert joe_check.coowned_trucks[0] == shelby + assert joe_check.coowned_buses[0] == unicorn + + joe_check = await Person.objects.prefetch_related( + ["coowned_trucks", "coowned_buses"] + ).get(name="Joe") + assert joe_check.pk == joe.pk + assert joe_check.coowned_trucks[0] == shelby + assert joe_check.coowned_buses[0] == unicorn