Skip to content

Commit 379cd71

Browse files
sinasogrigi
authored andcommitted
OneToOneField (tortoise#239)
* Added OneToOneField + schema generation * describe_model() now reports OneToOne relations * Prefetch concurrently * Enable foreign keys by default on sqlite
1 parent 335f320 commit 379cd71

26 files changed

Lines changed: 701 additions & 15 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ celerybeat-schedule
8686

8787
# dotenv
8888
.env
89+
.env3
8990

9091
# virtualenv
9192
.venv

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Changelog
77
- The ``auto_now_add`` argument of ``DatetimeField`` is handled correctly in the SQLite backend.
88
- ``unique_together`` now creates named constrains, to prevent the DB from auto-assigning a potentially non-unique constraint name.
99
- Filtering by an ``auto_now`` field doesn't replace the filter value with ``now()`` anymore.
10+
- Implemented ``OneToOneField``, one to one relation between two models.
11+
- Prefetching is done asynchronously now, sending all prefetch request at the same time instead of in sequence.
1012

1113
0.15.1
1214
------

CONTRIBUTORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Contributors
2121
* Adam Wallner ``@wallneradam``
2222
* Zoltán Szeredi ``@zoliszeredi``
2323
* Rebecca Klauser ``@svms1``
24+
* Sina Sohangir ``@sinaso``
2425

2526
Special Thanks
2627
==============

docs/fields.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ Relational Fields
7777
.. autoclass:: tortoise.fields.ForeignKeyField
7878
:exclude-members: to_db_value, to_python_value
7979

80+
.. autoclass:: tortoise.fields.OneToOneField
81+
8082
.. autofunction:: tortoise.fields.ManyToManyField
8183

8284
.. autodata:: tortoise.fields.ForeignKeyRelation

examples/relations.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ def __str__(self):
3434
return self.name
3535

3636

37+
class Address(Model):
38+
city = fields.CharField(max_length=64)
39+
street = fields.CharField(max_length=128)
40+
41+
event: fields.OneToOneRelation[Event] = fields.OneToOneField(
42+
"models.Event", on_delete=fields.CASCADE, related_name="address", pk=True
43+
)
44+
45+
def __str__(self):
46+
return f"Address({self.city}, {self.street})"
47+
48+
3749
class Team(Model):
3850
id = fields.IntField(pk=True)
3951
name = fields.TextField()
@@ -53,6 +65,9 @@ async def run():
5365
await Event(name="Without participants", tournament_id=tournament.id).save()
5466
event = Event(name="Test", tournament_id=tournament.id)
5567
await event.save()
68+
69+
await Address.create(city="Santa Monica", street="Ocean", event=event)
70+
5671
participants = []
5772
for i in range(2):
5873
team = Team(name=f"Team {(i + 1)}")
@@ -96,6 +111,14 @@ async def run():
96111

97112
print(await Event.filter(id=event.id).values_list("id", "participants__name"))
98113

114+
print(await Address.filter(event=event).first())
115+
116+
event_reload1 = await Event.filter(id=event.id).first()
117+
print(await event_reload1.address)
118+
119+
event_reload2 = await Event.filter(id=event.id).prefetch_related("address").first()
120+
print(event_reload2.address)
121+
99122

100123
if __name__ == "__main__":
101124
run_async(run())

tests/model_bad_rel5.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
"""
2+
Testing Models for a bad/wrong relation reference
3+
Wrong reference. App missing.
4+
"""
5+
from tortoise import fields
6+
from tortoise.models import Model
7+
8+
9+
class Tournament(Model):
10+
id = fields.IntField(pk=True)
11+
12+
13+
class Event(Model):
14+
tournament = fields.OneToOneField("Tournament")

tests/models_dup3.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""
2+
This is the testing Models — Duplicate 3
3+
"""
4+
5+
from tortoise import fields
6+
from tortoise.models import Model
7+
8+
9+
class Tournament(Model):
10+
id = fields.IntField(pk=True)
11+
event = fields.CharField(max_length=32)
12+
13+
14+
class Event(Model):
15+
tournament = fields.OneToOneField("models.Tournament", related_name="event")

tests/models_o2o_2.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""
2+
This is the testing Models — Bad on_delete parameter
3+
"""
4+
from tortoise import fields
5+
from tortoise.models import Model
6+
7+
8+
class One(Model):
9+
tournament = fields.OneToOneField("models.Two", on_delete="WABOOM")

tests/models_o2o_3.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""
2+
This is the testing Models — on_delete SET_NULL without null=True
3+
"""
4+
from tortoise import fields
5+
from tortoise.models import Model
6+
7+
8+
class One(Model):
9+
tournament = fields.OneToOneField("models.Two", on_delete=fields.SET_NULL)

tests/models_schema_create.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,22 @@ class Meta:
4747
indexes = [("manager", "key"), ["manager_id", "name"]]
4848

4949

50+
class TeamAddress(Model):
51+
city = fields.CharField(max_length=50, description="City")
52+
country = fields.CharField(max_length=50, description="Country")
53+
street = fields.CharField(max_length=128, description="Street Address")
54+
team = fields.OneToOneField(
55+
"models.Team", related_name="address", on_delete=fields.CASCADE, pk=True
56+
)
57+
58+
59+
class VenueInformation(Model):
60+
name = fields.CharField(max_length=128)
61+
capacity = fields.IntField()
62+
rent = fields.FloatField()
63+
team = fields.OneToOneField("models.Team", on_delete=fields.SET_NULL, null=True)
64+
65+
5066
class SourceFields(Model):
5167
id = fields.IntField(pk=True, source_field="sometable_id")
5268
chars = fields.CharField(max_length=255, source_field="some_chars_table", index=True)

0 commit comments

Comments
 (0)