Add QuerySet.first_or_none (#1137)
* Add QuerySet.first_or_none * restore docstrings for exceptions --------- Co-authored-by: collerek <collerek@gmail.com>
This commit is contained in:
@ -933,6 +933,23 @@ class QuerySet(Generic[T]):
|
|||||||
self.check_single_result_rows_count(processed_rows)
|
self.check_single_result_rows_count(processed_rows)
|
||||||
return processed_rows[0] # type: ignore
|
return processed_rows[0] # type: ignore
|
||||||
|
|
||||||
|
async def first_or_none(self, *args: Any, **kwargs: Any) -> Optional["T"]:
|
||||||
|
"""
|
||||||
|
Gets the first row from the db ordered by primary key column ascending.
|
||||||
|
|
||||||
|
If no match is found None will be returned.
|
||||||
|
|
||||||
|
:raises MultipleMatches: if more than 1 row is returned.
|
||||||
|
:param kwargs: fields names and proper value types
|
||||||
|
:type kwargs: Any
|
||||||
|
:return: returned model
|
||||||
|
:rtype: Model
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return await self.first(*args, **kwargs)
|
||||||
|
except ormar.NoMatch:
|
||||||
|
return None
|
||||||
|
|
||||||
async def get_or_none(self, *args: Any, **kwargs: Any) -> Optional["T"]:
|
async def get_or_none(self, *args: Any, **kwargs: Any) -> Optional["T"]:
|
||||||
"""
|
"""
|
||||||
Gets the first row from the db meeting the criteria set by kwargs.
|
Gets the first row from the db meeting the criteria set by kwargs.
|
||||||
@ -942,8 +959,9 @@ class QuerySet(Generic[T]):
|
|||||||
Passing a criteria is actually calling filter(*args, **kwargs) method described
|
Passing a criteria is actually calling filter(*args, **kwargs) method described
|
||||||
below.
|
below.
|
||||||
|
|
||||||
If not match is found None will be returned.
|
If no match is found None will be returned.
|
||||||
|
|
||||||
|
:raises MultipleMatches: if more than 1 row is returned.
|
||||||
:param kwargs: fields names and proper value types
|
:param kwargs: fields names and proper value types
|
||||||
:type kwargs: Any
|
:type kwargs: Any
|
||||||
:return: returned model
|
:return: returned model
|
||||||
|
|||||||
@ -451,6 +451,11 @@ async def test_offset():
|
|||||||
async def test_model_first():
|
async def test_model_first():
|
||||||
async with base_ormar_config.database:
|
async with base_ormar_config.database:
|
||||||
async with base_ormar_config.database.transaction(force_rollback=True):
|
async with base_ormar_config.database.transaction(force_rollback=True):
|
||||||
|
with pytest.raises(ormar.NoMatch):
|
||||||
|
await User.objects.first()
|
||||||
|
|
||||||
|
assert await User.objects.first_or_none() is None
|
||||||
|
|
||||||
tom = await User.objects.create(name="Tom")
|
tom = await User.objects.create(name="Tom")
|
||||||
jane = await User.objects.create(name="Jane")
|
jane = await User.objects.create(name="Jane")
|
||||||
|
|
||||||
@ -460,6 +465,9 @@ async def test_model_first():
|
|||||||
with pytest.raises(NoMatch):
|
with pytest.raises(NoMatch):
|
||||||
await User.objects.filter(name="Lucy").first()
|
await User.objects.filter(name="Lucy").first()
|
||||||
|
|
||||||
|
assert await User.objects.first_or_none(name="Lucy") is None
|
||||||
|
assert await User.objects.filter(name="Lucy").first_or_none() is None
|
||||||
|
|
||||||
assert await User.objects.order_by("name").first() == jane
|
assert await User.objects.order_by("name").first() == jane
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user