Skip to content

Commit

Permalink
Add model subscription lookup, Model[<pkval>] that will return the ob…
Browse files Browse the repository at this point in the history
…ject or raise KeyError (#386)
  • Loading branch information
grigi committed May 11, 2020
1 parent 8b55499 commit 7f160c3
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 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
- fix: ``sqlite://:memory:`` in Windows thrown ``OSError: [WinError 123]``
- Support ``bulk_create()`` insertion of records with overridden primary key when the primary key is DB-generated
- Add ``queryset.exists()`` and ``Model.exists()``.
- Add model subscription lookup, ``Model[<pkval>]`` that will return the object or raise ``KeyError``

0.16.10
-------
Expand Down
12 changes: 12 additions & 0 deletions tests/test_model_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,18 @@ async def test_update_from_dict(self):
with self.assertRaises(ValueError):
evt2.update_from_dict({"alias": "foo"})

async def test_index_access(self):
obj = await self.cls[self.mdl.pk]
self.assertEqual(obj, self.mdl)

async def test_index_badval(self):
with self.assertRaises(KeyError):
await self.cls[100000]

async def test_index_badtype(self):
with self.assertRaises(KeyError):
await self.cls["asdf"]


class TestModelMethodsNoID(TestModelMethods):
async def setUp(self):
Expand Down
11 changes: 11 additions & 0 deletions tortoise/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from tortoise.backends.base.client import BaseDBAsyncClient
from tortoise.exceptions import (
ConfigurationError,
DoesNotExist,
IncompleteInstanceError,
IntegrityError,
OperationalError,
Expand Down Expand Up @@ -602,6 +603,9 @@ def __search_for_field_attributes(base: Type, attrs: dict) -> None:
meta.finalise_fields()
return new_class

def __getitem__(cls: Type[MODEL], key: Any) -> QuerySetSingle[MODEL]: # type: ignore
return cls._getbypk(key) # type: ignore


class Model(metaclass=ModelMeta):
"""
Expand Down Expand Up @@ -728,6 +732,13 @@ def _set_pk_val(self, value: Any) -> None:
Can be used as a field name when doing filtering e.g. ``.filter(pk=...)`` etc...
"""

@classmethod
async def _getbypk(cls: Type[MODEL], key: Any) -> MODEL:
try:
return await cls.get(pk=key)
except (DoesNotExist, ValueError):
raise KeyError(f"{cls._meta.full_name} has no object {repr(key)}")

def update_from_dict(self, data: dict) -> MODEL:
"""
Updates the current model with the provided dict.
Expand Down

0 comments on commit 7f160c3

Please sign in to comment.