Skip to content

Commit

Permalink
Added type hints for relation managers (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nik authored and grigi committed Nov 7, 2019
1 parent 996d46d commit 394e0c5
Show file tree
Hide file tree
Showing 23 changed files with 284 additions and 111 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

Changelog
=========
0.14.1
-------
- `ManyToManyField` is now a function instead of a class.
- Added section on adding better autocomplete for relations in editors.

0.14.0
------
.. caution::
Expand Down
6 changes: 4 additions & 2 deletions docs/fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,11 @@ Relational Fields
.. autoclass:: tortoise.fields.ForeignKeyField
:exclude-members: to_db_value, to_python_value

.. autoclass:: tortoise.fields.ManyToManyField
:exclude-members: to_db_value, to_python_value
.. autofunction:: tortoise.fields.ManyToManyField

.. autodata:: tortoise.fields.ForeignKeyRelation

.. autodata:: tortoise.fields.ForeignKeyNullableRelation

Extending A Field
=================
Expand Down
52 changes: 52 additions & 0 deletions docs/models.rst
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,58 @@ Sync usage requires that you call `fetch_related` before the time, and then you
The reverse lookup of ``team.event_team`` works exactly the same way.

``Improving relational type hinting``
-------------------------------------

Since Tortoise ORM is still a young project, it does not have such widespread support by
various editors who help you writing code using good autocomplete for models and
different relations between them.
However, you can get such autocomplete by doing a little work yourself.
All you need to do is add a few annotations to your models for fields that are responsible
for the relations.

Here is an updated example from :ref:`getting_started`, that will add autocomplete for
all models including fields for the relations between models.

.. code-block:: python3
from tortoise.models import Model
from tortoise import fields
class Tournament(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
events: fields.ReverseRelation["Event"]
def __str__(self):
return self.name
class Event(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events"
)
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team", related_name="events", through="event_team"
)
def __str__(self):
return self.name
class Team(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=255)
events: fields.ManyToManyRelation[Event]
def __str__(self):
return self.name
Reference
=========
Expand Down
4 changes: 2 additions & 2 deletions docs/query.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Foreign Key

Tortoise ORM provides an API for working with FK relations

.. autoclass:: tortoise.fields.RelationQueryContainer
.. autoclass:: tortoise.fields.ReverseRelation
:members:


Expand All @@ -161,7 +161,7 @@ Many to Many

Tortoise ORM provides an API for working with M2M relations

.. autoclass:: tortoise.fields.ManyToManyRelationManager
.. autoclass:: tortoise.fields.ManyToManyRelation
:members:
:inherited-members:

Expand Down
10 changes: 8 additions & 2 deletions examples/complex_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ class Tournament(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ReverseRelation["Event"]

def __str__(self):
return self.name


class Event(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
tournament = fields.ForeignKeyField("models.Tournament", related_name="events")
participants = fields.ManyToManyField(
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events"
)
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team", related_name="events", through="event_team"
)

Expand All @@ -32,6 +36,8 @@ class Team(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ManyToManyRelation[Event]

def __str__(self):
return self.name

Expand Down
10 changes: 8 additions & 2 deletions examples/complex_prefetching.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ class Tournament(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ReverseRelation["Event"]

def __str__(self):
return self.name


class Event(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
tournament = fields.ForeignKeyField("models.Tournament", related_name="events")
participants = fields.ManyToManyField(
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events"
)
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team", related_name="events", through="event_team"
)

Expand All @@ -27,6 +31,8 @@ class Team(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ManyToManyRelation[Event]

def __str__(self):
return self.name

Expand Down
10 changes: 8 additions & 2 deletions examples/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,19 @@ class Tournament(Model):
name = fields.TextField()
desc = fields.TextField(null=True)

events: fields.ReverseRelation["Event"]

def __str__(self):
return self.name


class Event(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
tournament = fields.ForeignKeyField("models.Tournament", related_name="events")
participants = fields.ManyToManyField(
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events"
)
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team", related_name="events", through="event_team"
)

Expand All @@ -28,6 +32,8 @@ class Team(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ManyToManyRelation[Event]

def __str__(self):
return self.name

Expand Down
10 changes: 8 additions & 2 deletions examples/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@ class Tournament(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ReverseRelation["Event"]

def __str__(self):
return self.name


class Event(Model):
id = fields.IntField(pk=True)
name = fields.TextField()
tournament = fields.ForeignKeyField("models.Tournament", related_name="events")
participants = fields.ManyToManyField(
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events"
)
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team", related_name="events", through="event_team"
)

Expand All @@ -34,6 +38,8 @@ class Team(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

events: fields.ManyToManyRelation[Event]

def __str__(self):
return self.name

Expand Down
12 changes: 10 additions & 2 deletions examples/relations_recursive.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,16 @@

class Employee(Model):
name = fields.CharField(max_length=50)
manager = fields.ForeignKeyField("models.Employee", related_name="team_members", null=True)
talks_to = fields.ManyToManyField("models.Employee", related_name="gets_talked_to")

manager: fields.ForeignKeyNullableRelation["Employee"] = fields.ForeignKeyField(
"models.Employee", related_name="team_members", null=True
)
team_members: fields.ReverseRelation["Employee"]

talks_to: fields.ManyToManyRelation["Employee"] = fields.ManyToManyField(
"models.Employee", related_name="gets_talked_to"
)
gets_talked_to: fields.ManyToManyRelation["Employee"]

def __str__(self):
return self.name
Expand Down
8 changes: 6 additions & 2 deletions examples/schema_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ class Tournament(Model):
name = fields.CharField(max_length=255, description="Tournament name", index=True)
created = fields.DatetimeField(auto_now_add=True, description="Created datetime")

events: fields.ReverseRelation["Event"]

class Meta:
table_description = "What Tournaments we have"


class Event(Model):
id = fields.IntField(pk=True, description="Event ID")
name = fields.CharField(max_length=255, unique=True)
tournament = fields.ForeignKeyField(
tournament: fields.ForeignKeyRelation[Tournament] = fields.ForeignKeyField(
"models.Tournament", related_name="events", description="FK to tournament"
)
participants = fields.ManyToManyField(
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"models.Team",
related_name="events",
through="event_team",
Expand All @@ -38,6 +40,8 @@ class Meta:
class Team(Model):
name = fields.CharField(max_length=50, pk=True, description="The TEAM name (and PK)")

events: fields.ManyToManyRelation[Event]

class Meta:
table_description = "The TEAMS!"

Expand Down
4 changes: 3 additions & 1 deletion examples/two_databases.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Event(Model):
name = fields.TextField()
tournament_id = fields.IntField()
# Here we make link to events.Team, not models.Team
participants = fields.ManyToManyField(
participants: fields.ManyToManyRelation["Team"] = fields.ManyToManyField(
"events.Team", related_name="events", through="event_team"
)

Expand All @@ -44,6 +44,8 @@ class Team(Model):
id = fields.IntField(pk=True)
name = fields.TextField()

event_team: fields.ManyToManyRelation[Event]

def __str__(self):
return self.name

Expand Down
1 change: 1 addition & 0 deletions tests/models_dup1.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
This is the testing Models — Duplicate 1
"""

from tortoise import fields
from tortoise.models import Model

Expand Down
1 change: 1 addition & 0 deletions tests/models_dup2.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
This is the testing Models — Duplicate 1
"""

from tortoise import fields
from tortoise.models import Model

Expand Down
4 changes: 3 additions & 1 deletion tests/models_schema_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class Meta:

class Team(Model):
name = fields.CharField(max_length=50, pk=True, description="The TEAM name (and PK)")
manager = fields.ForeignKeyField("models.Team", related_name="team_members", null=True)
key = fields.IntField()
manager = fields.ForeignKeyField("models.Team", related_name="team_members", null=True)
talks_to = fields.ManyToManyField("models.Team", related_name="gets_talked_to")

class Meta:
Expand All @@ -50,9 +50,11 @@ class Meta:
class SourceFields(Model):
id = fields.IntField(pk=True, source_field="sometable_id")
chars = fields.CharField(max_length=255, source_field="some_chars_table", index=True)

fk = fields.ForeignKeyField(
"models.SourceFields", related_name="team_members", null=True, source_field="fk_sometable"
)

rel_to = fields.ManyToManyField(
"models.SourceFields",
related_name="rel_from",
Expand Down

0 comments on commit 394e0c5

Please sign in to comment.