fix quoting in order_by, add get_or_none

This commit is contained in:
collerek
2021-03-23 17:36:20 +01:00
parent b08d616dc0
commit 4ad843a6a5
14 changed files with 214 additions and 2 deletions

View File

@ -75,7 +75,7 @@ class UndefinedType: # pragma no cover
Undefined = UndefinedType()
__version__ = "0.10.0"
__version__ = "0.10.1"
__all__ = [
"Integer",
"BigInteger",

View File

@ -69,7 +69,13 @@ class OrderAction(QueryAction):
:rtype: sqlalchemy.sql.elements.TextClause
"""
prefix = f"{self.table_prefix}_" if self.table_prefix else ""
return text(f"{prefix}{self.table}" f".{self.field_alias} {self.direction}")
table_name = self.table.name
field_name = self.field_alias
if not prefix:
dialect = self.target_model.Meta.database._backend._dialect
table_name = dialect.identifier_preparer.quote(table_name)
field_name = dialect.identifier_preparer.quote(field_name)
return text(f"{prefix}{table_name}" f".{field_name} {self.direction}")
def _split_value_into_parts(self, order_str: str) -> None:
if order_str.startswith("-"):

View File

@ -778,6 +778,26 @@ class QuerySet(Generic[T]):
self.check_single_result_rows_count(processed_rows)
return processed_rows[0] # type: ignore
async def get_or_none(self, **kwargs: Any) -> Optional["T"]:
"""
Get's the first row from the db meeting the criteria set by kwargs.
If no criteria set it will return the last row in db sorted by pk.
Passing a criteria is actually calling filter(**kwargs) method described below.
If not match is found None will be returned.
:param kwargs: fields names and proper value types
:type kwargs: Any
:return: returned model
:rtype: Model
"""
try:
return await self.get(**kwargs)
except ormar.NoMatch:
return None
async def get(self, **kwargs: Any) -> "T":
"""
Get's the first row from the db meeting the criteria set by kwargs.

View File

@ -279,6 +279,30 @@ class QuerysetProxy(Generic[T]):
self._register_related(first)
return first
async def get_or_none(self, **kwargs: Any) -> Optional["T"]:
"""
Get's the first row from the db meeting the criteria set by kwargs.
If no criteria set it will return the last row in db sorted by pk.
Passing a criteria is actually calling filter(**kwargs) method described below.
If not match is found None will be returned.
:param kwargs: fields names and proper value types
:type kwargs: Any
:return: returned model
:rtype: Model
"""
try:
get = await self.queryset.get(**kwargs)
except ormar.NoMatch:
return None
self._clean_items_on_load()
self._register_related(get)
return get
async def get(self, **kwargs: Any) -> "T":
"""
Get's the first row from the db meeting the criteria set by kwargs.