request_query.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. # -*- coding: utf-8 -*-
  2. # (c) Nelen & Schuurmans
  3. from typing import List
  4. from fastapi import Query
  5. from pydantic import validator
  6. from clean_python.base.infrastructure.gateway import Filter
  7. from clean_python.base.domain.pagination import PageOptions
  8. from clean_python.base.domain.value_object import ValueObject
  9. __all__ = ["RequestQuery"]
  10. class RequestQuery(ValueObject):
  11. limit: int = Query(50, ge=1, le=100, description="Page size limit")
  12. offset: int = Query(0, ge=0, description="Page offset")
  13. order_by: str = Query(
  14. default="id", enum=["id", "-id"], description="Field to order by"
  15. )
  16. @validator("order_by")
  17. def validate_order_by_enum(cls, v):
  18. # the 'enum' parameter doesn't actually do anthing in validation
  19. # See: https://github.com/tiangolo/fastapi/issues/2910
  20. allowed = cls.__fields__["order_by"].field_info.extra["enum"]
  21. if v not in allowed:
  22. raise ValueError(f"'order_by' must be one of {allowed}")
  23. return v
  24. def as_page_options(self) -> PageOptions:
  25. if self.order_by.startswith("-"):
  26. order_by = self.order_by[1:]
  27. ascending = False
  28. else:
  29. order_by = self.order_by
  30. ascending = True
  31. return PageOptions(
  32. limit=self.limit, offset=self.offset, order_by=order_by, ascending=ascending
  33. )
  34. def filters(self) -> List[Filter]:
  35. result = []
  36. for name in self.__fields__:
  37. if name in {"limit", "offset", "order_by"}:
  38. continue
  39. value = getattr(self, name)
  40. if value is not None:
  41. result.append(Filter(field=name, values=[value]))
  42. return result