fastadmin 0.7.0__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {fastadmin-0.7.0 → fastadmin-0.8.0}/PKG-INFO +1 -1
  2. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/__init__.py +1 -0
  3. fastadmin-0.8.0/fastadmin/api/encoders.py +70 -0
  4. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/base.py +7 -1
  5. {fastadmin-0.7.0 → fastadmin-0.8.0}/pyproject.toml +1 -1
  6. {fastadmin-0.7.0 → fastadmin-0.8.0}/LICENSE.md +0 -0
  7. {fastadmin-0.7.0 → fastadmin-0.8.0}/README.md +0 -0
  8. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/__init__.py +0 -0
  9. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/exceptions.py +0 -0
  10. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/__init__.py +0 -0
  11. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/django/__init__.py +0 -0
  12. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/django/app/__init__.py +0 -0
  13. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/django/app/api.py +0 -0
  14. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/django/app/urls.py +0 -0
  15. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/django/app/views.py +0 -0
  16. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/fastapi/__init__.py +0 -0
  17. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/fastapi/api.py +0 -0
  18. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/fastapi/app.py +0 -0
  19. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/fastapi/views.py +0 -0
  20. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/flask/__init__.py +0 -0
  21. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/flask/api.py +0 -0
  22. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/flask/app.py +0 -0
  23. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/frameworks/flask/views.py +0 -0
  24. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/helpers.py +0 -0
  25. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/schemas.py +0 -0
  26. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/api/service.py +0 -0
  27. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/__init__.py +0 -0
  28. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/decorators.py +0 -0
  29. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/helpers.py +0 -0
  30. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/__init__.py +0 -0
  31. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/django.py +0 -0
  32. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/ponyorm.py +0 -0
  33. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/sqlalchemy.py +0 -0
  34. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/tortoise.py +0 -0
  35. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/orms/yaraorm.py +0 -0
  36. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/models/schemas.py +0 -0
  37. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/settings.py +0 -0
  38. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-6Z7niv9l.js +0 -0
  39. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-C151k0-L.js +0 -0
  40. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-C9KPOOKD.js +0 -0
  41. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-D1fCgYB7.js +0 -0
  42. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-D3TWcJOI.js +0 -0
  43. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-DRNcaZ-V.js +0 -0
  44. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/assets/worker-MF2p-l5_.js +0 -0
  45. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/images/favicon.png +0 -0
  46. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/images/header-logo.svg +0 -0
  47. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/images/sign-in-logo.svg +0 -0
  48. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/index.html +0 -0
  49. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/index.min.css +0 -0
  50. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/static/index.min.js +0 -0
  51. {fastadmin-0.7.0 → fastadmin-0.8.0}/fastadmin/templates/index.html +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastadmin
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: FastAdmin is an easy-to-use Admin Dashboard App for FastAPI/Flask/Django inspired by Django Admin.
5
5
  Keywords: admin,dashboard,fastapi,flask,django,tortoise-orm,sqlalchemy,pony,yara-orm,admin-dashboard,django-admin
6
6
  Author: Seva D
@@ -38,6 +38,7 @@ except ModuleNotFoundError: # pragma: no cover
38
38
  logging.info("Yara ORM is not installed") # pragma: no cover
39
39
 
40
40
  # api
41
+ from fastadmin.api.encoders import register_encoder, unregister_encoder # noqa: F401
41
42
  from fastadmin.api.exceptions import AdminApiException # noqa: F401
42
43
 
43
44
  # models
@@ -0,0 +1,70 @@
1
+ """User-registerable custom encoders for admin API serialization.
2
+
3
+ Model field values are converted to JSON-serializable representations during
4
+ serialization (see :meth:`fastadmin.models.base.BaseModelAdmin.serialize_obj_attributes`).
5
+ Register a custom encoder to control how instances of a given type are represented
6
+ in every admin API response — e.g. a custom datetime format, an ``Enum``'s label,
7
+ or a domain value object.
8
+
9
+ Example:
10
+
11
+ .. code-block:: python
12
+
13
+ import datetime
14
+
15
+ from fastadmin import register_encoder
16
+
17
+ # Render every datetime as "2024-01-31 14:05" instead of ISO 8601.
18
+ register_encoder(datetime.datetime, lambda dt: dt.strftime("%Y-%m-%d %H:%M"))
19
+
20
+ Encoders are matched via ``isinstance`` in registration order, so register more
21
+ specific types before their base types.
22
+ """
23
+
24
+ from collections.abc import Callable
25
+ from typing import Any
26
+
27
+ # Maps a type to a function converting an instance of that type to a JSON-serializable value.
28
+ CUSTOM_ENCODERS: dict[type, Callable[[Any], Any]] = {}
29
+
30
+
31
+ def register_encoder(type_: type, encoder: Callable[[Any], Any]) -> None:
32
+ """Register a custom encoder for a type used across all admin API responses.
33
+
34
+ :params type_: the type to encode (matched via ``isinstance``).
35
+ :params encoder: a callable converting an instance to a JSON-serializable value.
36
+ :return: None.
37
+ """
38
+ CUSTOM_ENCODERS[type_] = encoder
39
+
40
+
41
+ def unregister_encoder(type_: type) -> None:
42
+ """Remove a previously registered encoder for a type (no-op if absent).
43
+
44
+ :params type_: the type whose encoder should be removed.
45
+ :return: None.
46
+ """
47
+ CUSTOM_ENCODERS.pop(type_, None)
48
+
49
+
50
+ def clear_encoders() -> None:
51
+ """Remove all registered custom encoders.
52
+
53
+ :return: None.
54
+ """
55
+ CUSTOM_ENCODERS.clear()
56
+
57
+
58
+ def apply_custom_encoders(value: Any) -> Any:
59
+ """Return ``value`` encoded by the first matching custom encoder, else unchanged.
60
+
61
+ Types are matched via ``isinstance`` in registration order, so a more specific
62
+ type registered before its base type wins.
63
+
64
+ :params value: the value to encode.
65
+ :return: the encoded value, or the original value if no encoder matches.
66
+ """
67
+ for type_, encoder in CUSTOM_ENCODERS.items():
68
+ if isinstance(value, type_):
69
+ return encoder(value)
70
+ return value
@@ -11,6 +11,7 @@ from uuid import UUID
11
11
 
12
12
  from asgiref.sync import sync_to_async
13
13
 
14
+ from fastadmin.api.encoders import apply_custom_encoders
14
15
  from fastadmin.api.schemas import ExportFormat
15
16
  from fastadmin.models.schemas import ModelFieldWidgetSchema, WidgetType
16
17
 
@@ -419,7 +420,12 @@ class BaseModelAdmin:
419
420
  serialized_dict: dict[str, Any] = {}
420
421
  for field in attributes_to_serizalize:
421
422
  value = getattr(obj, field.column_name)
422
- if isinstance(value, Decimal):
423
+ # Let user-registered encoders (e.g. a custom datetime format) take
424
+ # precedence over the built-in handling below.
425
+ encoded = apply_custom_encoders(value)
426
+ if encoded is not value:
427
+ value = encoded
428
+ elif isinstance(value, Decimal):
423
429
  # Avoid scientific notation for Decimal values in API responses,
424
430
  # e.g. 3.75E+3 -> "3750"
425
431
  value = format(value, "f")
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "fastadmin"
7
- version = "0.7.0"
7
+ version = "0.8.0"
8
8
  description = "FastAdmin is an easy-to-use Admin Dashboard App for FastAPI/Flask/Django inspired by Django Admin."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
File without changes
File without changes