#453 make first and get respect user ordering if set on main model

This commit is contained in:
collerek
2021-12-16 17:24:23 +01:00
parent bc5c6222b1
commit 1b9a59b49d
6 changed files with 429 additions and 442 deletions

View File

@ -7,8 +7,8 @@
## 🐛 Fixes ## 🐛 Fixes
* Fix `LargeBinary` fields that can be nullable [#409](https://github.com/collerek/ormar/issues/409) * Fix `LargeBinary` fields that can be nullable [#409](https://github.com/collerek/ormar/issues/409)
* Make `ormar` models pickable [#413](https://github.com/collerek/ormar/issues/413) * Make `ormar.Model` pickable [#413](https://github.com/collerek/ormar/issues/413)
* Make `first()` and `get()` without arguments respect ordering set by user, fallback to primary key (asc, and desc respectively) [#453](https://github.com/collerek/ormar/issues/453)
# 0.10.22 # 0.10.22

View File

@ -873,12 +873,16 @@ class QuerySet(Generic[T]):
expr = self.build_select_expression( expr = self.build_select_expression(
limit=1, limit=1,
order_bys=[ order_bys=(
OrderAction( [
order_str=f"{self.model.Meta.pkname}", OrderAction(
model_cls=self.model_cls, # type: ignore order_str=f"{self.model.Meta.pkname}",
) model_cls=self.model_cls, # type: ignore
] )
]
if not any([x.is_source_model_order for x in self.order_bys])
else []
)
+ self.order_bys, + self.order_bys,
) )
rows = await self.database.fetch_all(expr) rows = await self.database.fetch_all(expr)
@ -931,12 +935,16 @@ class QuerySet(Generic[T]):
if not self.filter_clauses: if not self.filter_clauses:
expr = self.build_select_expression( expr = self.build_select_expression(
limit=1, limit=1,
order_bys=[ order_bys=(
OrderAction( [
order_str=f"-{self.model.Meta.pkname}", OrderAction(
model_cls=self.model_cls, # type: ignore order_str=f"-{self.model.Meta.pkname}",
) model_cls=self.model_cls, # type: ignore
] )
]
if not any([x.is_source_model_order for x in self.order_bys])
else []
)
+ self.order_bys, + self.order_bys,
) )
else: else:

786
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ name = "ormar"
[tool.poetry] [tool.poetry]
name = "ormar" name = "ormar"
version = "0.10.22" version = "0.10.23"
description = "A simple async ORM with fastapi in mind and pydantic validation." description = "A simple async ORM with fastapi in mind and pydantic validation."
authors = ["Radosław Drążkiewicz <collerek@gmail.com>"] authors = ["Radosław Drążkiewicz <collerek@gmail.com>"]
license = "MIT" license = "MIT"
@ -44,7 +44,7 @@ classifiers = [
python = "^3.6.2" python = "^3.6.2"
databases = ">=0.3.2,<0.5.4" databases = ">=0.3.2,<0.5.4"
pydantic = ">=1.6.1,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<=1.8.2" pydantic = ">=1.6.1,!=1.7,!=1.7.1,!=1.7.2,!=1.7.3,!=1.8,!=1.8.1,<=1.8.2"
SQLAlchemy = ">=1.3.18,<1.4.28" SQLAlchemy = ">=1.3.18,<1.4.29"
asyncpg = { version = ">=0.24,<0.26", optional = true } asyncpg = { version = ">=0.24,<0.26", optional = true }
psycopg2-binary = { version = "^2.9.1", optional = true } psycopg2-binary = { version = "^2.9.1", optional = true }
aiomysql = { version = ">=0.0.21,<0.0.23", optional = true } aiomysql = { version = ">=0.0.21,<0.0.23", optional = true }
@ -82,7 +82,7 @@ pytest = "^6.2.5"
pytest-cov = "^3.0.0" pytest-cov = "^3.0.0"
codecov = "^2.1.12" codecov = "^2.1.12"
pytest-asyncio = "^0.16.0" pytest-asyncio = "^0.16.0"
fastapi = "^0.70.0" fastapi = "^0.70.1"
flake8 = "^3.9.2" flake8 = "^3.9.2"
flake8-black = "^0.2.3" flake8-black = "^0.2.3"
flake8-bugbear = "^21.11.29" flake8-bugbear = "^21.11.29"
@ -110,9 +110,9 @@ types-dataclasses = { version = "^0.6.1", markers = "python_version < '3.7'" }
# Documantation # Documantation
mkdocs = "^1.2.3" mkdocs = "^1.2.3"
mkdocs-material = "^8.0.5" mkdocs-material = "^8.1.2"
mkdocs-material-extensions = "^1.0.3" mkdocs-material-extensions = "^1.0.3"
pydoc-markdown = { version = "^4.3.2", markers = "python_version > '3.7'" } pydoc-markdown = { version = "^4.5.0", markers = "python_version > '3.7'" }
dataclasses = { version = ">=0.6.0,<0.8 || >0.8,<1.0.0" } dataclasses = { version = ">=0.6.0,<0.8 || >0.8,<1.0.0" }
# Performance testing # Performance testing

View File

@ -352,14 +352,16 @@ async def test_model_get():
lookup = await User.objects.get() lookup = await User.objects.get()
assert lookup == user assert lookup == user
user = await User.objects.create(name="Jane") user2 = await User.objects.create(name="Jane")
await User.objects.create(name="Jane") await User.objects.create(name="Jane")
with pytest.raises(ormar.MultipleMatches): with pytest.raises(ormar.MultipleMatches):
await User.objects.get(name="Jane") await User.objects.get(name="Jane")
same_user = await User.objects.get(pk=user.id) same_user = await User.objects.get(pk=user2.id)
assert same_user.id == user.id assert same_user.id == user2.id
assert same_user.pk == user.pk assert same_user.pk == user2.pk
assert await User.objects.order_by("-name").get() == user
@pytest.mark.asyncio @pytest.mark.asyncio
@ -495,6 +497,8 @@ 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.order_by("name").first() == jane
def not_contains(a, b): def not_contains(a, b):
return a not in b return a not in b

View File

@ -45,16 +45,17 @@ def create_test_database():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_dumping_and_loading_model_works(): async def test_dumping_and_loading_model_works():
user = await User(name="Test", properties={"aa": "bb"}).save() async with database:
post = Post(name="Test post") user = await User(name="Test", properties={"aa": "bb"}).save()
await user.posts.add(post) post = Post(name="Test post")
pickled_value = pickle.dumps(user) await user.posts.add(post)
python_value = pickle.loads(pickled_value) pickled_value = pickle.dumps(user)
assert isinstance(python_value, User) python_value = pickle.loads(pickled_value)
assert python_value.name == "Test" assert isinstance(python_value, User)
assert python_value.properties == {"aa": "bb"} assert python_value.name == "Test"
assert python_value.posts[0].name == "Test post" assert python_value.properties == {"aa": "bb"}
await python_value.load() assert python_value.posts[0].name == "Test post"
await python_value.update(name="Test2") await python_value.load()
check = await User.objects.get() await python_value.update(name="Test2")
assert check.name == "Test2" check = await User.objects.get()
assert check.name == "Test2"