Skip to content

Commit b553f24

Browse files
committed
fixes defaults
1 parent 3181710 commit b553f24

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

packages/models-library/src/models_library/rest_ordering.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import Any, ClassVar
33

44
from models_library.utils.json_serialization import json_dumps
5-
from pydantic import BaseModel, Field, validator
5+
from pydantic import BaseModel, Extra, Field, validator
66

77
from .basic_types import IDStr
88
from .rest_base import RequestParameters
@@ -25,12 +25,6 @@ class OrderBy(BaseModel):
2525
),
2626
)
2727

28-
class Config:
29-
extra = "forbid"
30-
schema_extra: ClassVar[dict[str, Any]] = {
31-
"example": {"field": "some_field_name", "direction": "desc"}
32-
}
33-
3428

3529
class _BaseOrderQueryParams(RequestParameters):
3630
order_by: OrderBy | None = None
@@ -68,29 +62,43 @@ def create_ordering_query_model_classes(
6862
msg_direction_options = "|".join(sorted(OrderDirection))
6963

7064
class _OrderBy(OrderBy):
65+
class Config(OrderBy.Config):
66+
schema_extra: ClassVar[dict[str, Any]] = {
67+
"example": {
68+
"field": next(iter(ordering_fields)),
69+
"direction": OrderDirection.DESC.value,
70+
}
71+
}
72+
extra = Extra.forbid
73+
# Necessary to run _check_ordering_field_and_map in defaults and assignments
74+
validate_all = True
75+
validate_assignment = True
76+
7177
@validator("field", allow_reuse=True, always=True)
7278
@classmethod
73-
def _check_if_ordering_field(cls, v):
79+
def _check_ordering_field_and_map(cls, v):
7480
if v not in ordering_fields:
7581
msg = (
7682
f"We do not support ordering by provided field '{v}'. "
7783
f"Fields supported are {msg_field_options}."
7884
)
7985
raise ValueError(msg)
80-
return v
8186

82-
@validator("field", allow_reuse=True, always=True)
83-
@classmethod
84-
def _post_rename_order_by_field_as_db_column(cls, v):
85-
# API field name -> DB column_name
87+
# API field name -> DB column_name conversion
8688
return ordering_fields_api_to_column_map.get(v) or v
8789

88-
order_by_example: dict[str, Any] = OrderBy.Config.schema_extra["example"]
90+
order_by_example: dict[str, Any] = _OrderBy.Config.schema_extra["example"]
8991
order_by_example_json = json_dumps(order_by_example)
92+
assert _OrderBy.parse_obj(order_by_example), "Example is invalid" # nosec
93+
94+
converted_default = _OrderBy.parse_obj(
95+
# NOTE: enforces ordering_fields_api_to_column_map
96+
default.dict()
97+
)
9098

9199
class _OrderQueryParams(_BaseOrderQueryParams):
92100
order_by: _OrderBy = Field(
93-
default=default,
101+
default=converted_default,
94102
description=(
95103
f"Order by field (`{msg_field_options}`) and direction (`{msg_direction_options}`). "
96104
f"The default sorting order is `{json_dumps(default)}`."

packages/models-library/tests/test_rest_ordering.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@ def test_ordering_query_model_class__defaults():
104104
OrderQueryParamsModel = create_ordering_query_model_classes(
105105
ordering_fields={"modified", "name", "description"},
106106
default=OrderBy(field=IDStr("modified"), direction=OrderDirection.DESC),
107+
ordering_fields_api_to_column_map={"modified": "modified_at"},
107108
)
108109

109110
# checks all defaults
110111
model = OrderQueryParamsModel()
111112
assert model.order_by
112-
assert model.order_by.field == "modified"
113+
assert model.order_by.field == "modified_at" # NOTE that this was mapped!
113114
assert model.order_by.direction == OrderDirection.DESC
114115

115116
# partial defaults

0 commit comments

Comments
 (0)