fix for #226
This commit is contained in:
@ -1,3 +1,13 @@
|
||||
# 0.10.11
|
||||
|
||||
## ✨ Features
|
||||
|
||||
*
|
||||
|
||||
## 🐛 Fixes
|
||||
|
||||
* Fix creation of auto through model for m2m relation with ForwardRef [#226](https://github.com/collerek/ormar/issues/226)
|
||||
|
||||
# 0.10.10
|
||||
|
||||
## ✨ Features
|
||||
|
||||
@ -2,6 +2,7 @@ import logging
|
||||
from typing import Dict, List, Optional, TYPE_CHECKING, Tuple, Type, Union
|
||||
|
||||
import sqlalchemy
|
||||
from pydantic.typing import ForwardRef
|
||||
|
||||
import ormar # noqa: I100, I202
|
||||
from ormar.models.descriptors import RelationDescriptor
|
||||
@ -203,7 +204,7 @@ def _is_through_model_not_set(field: "BaseField") -> bool:
|
||||
:return: result of the check
|
||||
:rtype: bool
|
||||
"""
|
||||
return field.is_multi and not field.through
|
||||
return field.is_multi and not field.through and not field.to.__class__ == ForwardRef
|
||||
|
||||
|
||||
def _is_db_field(field: "BaseField") -> bool:
|
||||
|
||||
@ -447,6 +447,9 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
|
||||
field = cast(ForeignKeyField, field)
|
||||
field.evaluate_forward_ref(globalns=globalns, localns=localns)
|
||||
field.set_self_reference_flag()
|
||||
if field.is_multi and not field.through:
|
||||
field = cast(ormar.ManyToManyField, field)
|
||||
field.create_default_through_model()
|
||||
expand_reverse_relationship(model_field=field)
|
||||
register_relation_in_alias_manager(field=field)
|
||||
update_column_definition(model=cls, field=field)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
# type: ignore
|
||||
from typing import List, Optional
|
||||
|
||||
import databases
|
||||
import pytest
|
||||
@ -17,10 +18,14 @@ engine = create_engine(DATABASE_URL)
|
||||
TeacherRef = ForwardRef("Teacher")
|
||||
|
||||
|
||||
class BaseMeta(ormar.ModelMeta):
|
||||
metadata = metadata
|
||||
database = db
|
||||
|
||||
|
||||
class Student(ormar.Model):
|
||||
class Meta(ModelMeta):
|
||||
metadata = metadata
|
||||
database = db
|
||||
class Meta(BaseMeta):
|
||||
pass
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100)
|
||||
@ -30,10 +35,8 @@ class Student(ormar.Model):
|
||||
|
||||
|
||||
class StudentTeacher(ormar.Model):
|
||||
class Meta(ModelMeta):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "students_x_teachers"
|
||||
metadata = metadata
|
||||
database = db
|
||||
|
||||
|
||||
class Teacher(ormar.Model):
|
||||
@ -50,6 +53,35 @@ class Teacher(ormar.Model):
|
||||
|
||||
Student.update_forward_refs()
|
||||
|
||||
CityRef = ForwardRef("City")
|
||||
CountryRef = ForwardRef("Country")
|
||||
|
||||
|
||||
class Country(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "countries"
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=128)
|
||||
capital: Optional[CityRef] = ormar.ForeignKey(
|
||||
CityRef, related_name="capital_city", nullable=True
|
||||
)
|
||||
borders: Optional[List[CountryRef]] = ormar.ManyToMany(CountryRef)
|
||||
|
||||
|
||||
class City(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "cities"
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=128)
|
||||
country: Country = ormar.ForeignKey(
|
||||
Country, related_name="cities", skip_reverse=True
|
||||
)
|
||||
|
||||
|
||||
Country.update_forward_refs()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
@ -114,3 +146,23 @@ async def test_double_relations():
|
||||
assert len(quibble.own_students) == 2
|
||||
assert quibble.own_students[1].name == "John"
|
||||
assert quibble.own_students[0].name == "Anna"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_auto_through_model():
|
||||
async with db:
|
||||
async with db.transaction(force_rollback=True):
|
||||
england = await Country(name="England").save()
|
||||
france = await Country(name="France").save()
|
||||
london = await City(name="London", country=england).save()
|
||||
england.capital = london
|
||||
await england.update()
|
||||
await england.borders.add(france)
|
||||
|
||||
check = await Country.objects.select_related(["capital", "borders"]).get(
|
||||
name="England"
|
||||
)
|
||||
assert check.name == "England"
|
||||
assert check.capital.name == "London"
|
||||
assert check.capital.country.pk == check.pk
|
||||
assert check.borders[0] == france
|
||||
|
||||
Reference in New Issue
Block a user