Skip to content

Commit

Permalink
fixes defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
pcrespov committed Nov 18, 2024
1 parent c1b2baa commit 357ba30
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 16 deletions.
38 changes: 23 additions & 15 deletions packages/models-library/src/models_library/rest_ordering.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Any, ClassVar

from models_library.utils.json_serialization import json_dumps
from pydantic import BaseModel, Field, validator
from pydantic import BaseModel, Extra, Field, validator

from .basic_types import IDStr
from .rest_base import RequestParameters
Expand All @@ -25,12 +25,6 @@ class OrderBy(BaseModel):
),
)

class Config:
extra = "forbid"
schema_extra: ClassVar[dict[str, Any]] = {
"example": {"field": "some_field_name", "direction": "desc"}
}


class _BaseOrderQueryParams(RequestParameters):
order_by: OrderBy | None = None
Expand Down Expand Up @@ -68,29 +62,43 @@ def create_ordering_query_model_classes(
msg_direction_options = "|".join(sorted(OrderDirection))

class _OrderBy(OrderBy):
class Config(OrderBy.Config):
schema_extra: ClassVar[dict[str, Any]] = {
"example": {
"field": next(iter(ordering_fields)),
"direction": OrderDirection.DESC.value,
}
}
extra = Extra.forbid
# Necessary to run _check_ordering_field_and_map in defaults and assignments
validate_all = True
validate_assignment = True

@validator("field", allow_reuse=True, always=True)
@classmethod
def _check_if_ordering_field(cls, v):
def _check_ordering_field_and_map(cls, v):
if v not in ordering_fields:
msg = (
f"We do not support ordering by provided field '{v}'. "
f"Fields supported are {msg_field_options}."
)
raise ValueError(msg)
return v

@validator("field", allow_reuse=True, always=True)
@classmethod
def _post_rename_order_by_field_as_db_column(cls, v):
# API field name -> DB column_name
# API field name -> DB column_name conversion
return ordering_fields_api_to_column_map.get(v) or v

order_by_example: dict[str, Any] = OrderBy.Config.schema_extra["example"]
order_by_example: dict[str, Any] = _OrderBy.Config.schema_extra["example"]
order_by_example_json = json_dumps(order_by_example)
assert _OrderBy.parse_obj(order_by_example), "Example is invalid" # nosec

converted_default = _OrderBy.parse_obj(
# NOTE: enforces ordering_fields_api_to_column_map
default.dict()
)

class _OrderQueryParams(_BaseOrderQueryParams):
order_by: _OrderBy = Field(
default=default,
default=converted_default,
description=(
f"Order by field (`{msg_field_options}`) and direction (`{msg_direction_options}`). "
f"The default sorting order is `{json_dumps(default)}`."
Expand Down
3 changes: 2 additions & 1 deletion packages/models-library/tests/test_rest_ordering.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,13 @@ def test_ordering_query_model_class__defaults():
OrderQueryParamsModel = create_ordering_query_model_classes(
ordering_fields={"modified", "name", "description"},
default=OrderBy(field=IDStr("modified"), direction=OrderDirection.DESC),
ordering_fields_api_to_column_map={"modified": "modified_at"},
)

# checks all defaults
model = OrderQueryParamsModel()
assert model.order_by
assert model.order_by.field == "modified"
assert model.order_by.field == "modified_at" # NOTE that this was mapped!
assert model.order_by.direction == OrderDirection.DESC

# partial defaults
Expand Down

0 comments on commit 357ba30

Please sign in to comment.