Skip to content

Commit

Permalink
fix join query with source_field param (#349)
Browse files Browse the repository at this point in the history
We found join query with source_field param has bug (See #345). So fix it !

* Fix bug in join with source_field param
* Add more testcase with source_field
* Add Changelog
  • Loading branch information
hqsz authored Apr 10, 2020
1 parent 10669b5 commit 1ee6d73
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Changelog
* Moved ``Tortoise.describe_model(<MODEL>, ...)`` to ``<MODEL>.describe(...)``
* Deprecated ``Tortoise.describe_model()``
* Fix for ``generate_schemas`` param being ignored in ``tortoise.contrib.quart.register_tortoise``
* Fix join query with `source_field` param

0.16.4
------
Expand Down
7 changes: 7 additions & 0 deletions tests/test_source_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,13 @@ async def test_get_m2m_reverse_prefetch_related(self):
obj1a = await self.model.get(eyedee=obj1.eyedee).prefetch_related("rel_to")
self.assertEqual(list(obj1a.rel_to), [obj2])

async def test_values_reverse_relation(self):
obj1 = await self.model.create(chars="aaa")
await self.model.create(chars="bbb", fk=obj1)

obj1a = await self.model.filter(chars="aaa").values("fkrev__chars")
self.assertEqual(obj1a[0]["fkrev__chars"], "bbb")

async def test_f_expression(self):
obj1 = await self.model.create(chars="aaa")
await self.model.filter(eyedee=obj1.eyedee).update(chars=F("blip"))
Expand Down
12 changes: 10 additions & 2 deletions tortoise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,11 @@ def split_reference(reference: str) -> Tuple[str, str]:
f" model {related_model_name}"
)
fk_relation = BackwardFKRelation(
model, f"{field}_id", fk_object.null, fk_object.description,
model,
f"{field}_id",
key_fk_object.source_field,
fk_object.null,
fk_object.description,
)
fk_relation.to_field_instance = fk_object.to_field_instance
related_model._meta.add_field(backward_relation_name, fk_relation)
Expand Down Expand Up @@ -269,7 +273,11 @@ def split_reference(reference: str) -> Tuple[str, str]:
f" model {related_model_name}"
)
o2o_relation = BackwardOneToOneRelation(
model, f"{field}_id", null=True, description=o2o_object.description,
model,
f"{field}_id",
key_o2o_object.source_field,
null=True,
description=o2o_object.description,
)
o2o_relation.to_field_instance = o2o_object.to_field_instance
related_model._meta.add_field(backward_relation_name, o2o_relation)
Expand Down
2 changes: 2 additions & 0 deletions tortoise/fields/relational.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,12 +332,14 @@ def __init__(
self,
field_type: "Type[Model]",
relation_field: str,
relation_source_field: str,
null: bool,
description: Optional[str],
**kwargs: Any,
) -> None:
super().__init__(field_type, null=null, **kwargs)
self.relation_field: str = relation_field
self.relation_source_field: str = relation_source_field
self.description: Optional[str] = description


Expand Down
7 changes: 5 additions & 2 deletions tortoise/query_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,16 @@ def _get_joins_for_related_field(
)
)
elif isinstance(related_field, BackwardFKRelation):
to_field_source_field = related_field.to_field_instance.source_field
if not to_field_source_field:
to_field_source_field = related_field.to_field_instance.model_field_name

if table == related_table:
related_table = related_table.as_(f"{table.get_table_name()}__{related_field_name}")
required_joins.append(
(
related_table,
table[related_field.to_field_instance.model_field_name]
== related_table[related_field.relation_field],
table[to_field_source_field] == related_table[related_field.relation_source_field],
)
)
else:
Expand Down

0 comments on commit 1ee6d73

Please sign in to comment.