sqladmin 0.18.0__tar.gz → 0.19.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 (54) hide show
  1. {sqladmin-0.18.0 → sqladmin-0.19.0}/PKG-INFO +1 -1
  2. {sqladmin-0.18.0 → sqladmin-0.19.0}/pyproject.toml +1 -1
  3. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/__init__.py +1 -1
  4. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/ajax.py +8 -3
  5. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/application.py +5 -0
  6. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/forms.py +11 -3
  7. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/models.py +1 -1
  8. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/pagination.py +5 -0
  9. sqladmin-0.19.0/sqladmin/statics/css/tabler-icons.min.css +4 -0
  10. sqladmin-0.19.0/sqladmin/statics/css/tabler-icons.min.css.map +1 -0
  11. sqladmin-0.19.0/sqladmin/statics/webfonts/tabler-icons.woff2 +0 -0
  12. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/base.html +4 -0
  13. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/list.html +1 -1
  14. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/widgets.py +4 -1
  15. {sqladmin-0.18.0 → sqladmin-0.19.0}/.gitignore +0 -0
  16. {sqladmin-0.18.0 → sqladmin-0.19.0}/LICENSE.md +0 -0
  17. {sqladmin-0.18.0 → sqladmin-0.19.0}/README.md +0 -0
  18. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/_menu.py +0 -0
  19. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/_queries.py +0 -0
  20. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/_types.py +0 -0
  21. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/_validators.py +0 -0
  22. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/authentication.py +0 -0
  23. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/exceptions.py +0 -0
  24. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/fields.py +0 -0
  25. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/formatters.py +0 -0
  26. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/helpers.py +0 -0
  27. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/py.typed +0 -0
  28. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/css/flatpickr.min.css +0 -0
  29. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/css/fontawesome.min.css +0 -0
  30. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/css/main.css +0 -0
  31. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/css/select2.min.css +0 -0
  32. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/css/tabler.min.css +0 -0
  33. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/bootstrap.min.js +0 -0
  34. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/flatpickr.min.js +0 -0
  35. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/jquery.min.js +0 -0
  36. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/main.js +0 -0
  37. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/popper.min.js +0 -0
  38. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/select2.full.min.js +0 -0
  39. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/js/tabler.min.js +0 -0
  40. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/webfonts/fa-brands-400.woff2 +0 -0
  41. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/webfonts/fa-regular-400.woff2 +0 -0
  42. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/statics/webfonts/fa-solid-900.woff2 +0 -0
  43. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/_macros.html +0 -0
  44. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/create.html +0 -0
  45. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/details.html +0 -0
  46. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/edit.html +0 -0
  47. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/error.html +0 -0
  48. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/index.html +0 -0
  49. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/layout.html +0 -0
  50. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/login.html +0 -0
  51. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/modals/delete.html +0 -0
  52. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/modals/details_action_confirmation.html +0 -0
  53. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templates/sqladmin/modals/list_action_confirmation.html +0 -0
  54. {sqladmin-0.18.0 → sqladmin-0.19.0}/sqladmin/templating.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: sqladmin
3
- Version: 0.18.0
3
+ Version: 0.19.0
4
4
  Summary: SQLAlchemy admin for FastAPI and Starlette
5
5
  Project-URL: Documentation, https://aminalaee.dev/sqladmin
6
6
  Project-URL: Issues, https://github.com/aminalaee/sqladmin/issues
@@ -95,7 +95,7 @@ dependencies = [
95
95
  dependencies = [
96
96
  "mkdocs-material==9.1.3",
97
97
  "mkdocs==1.4.2",
98
- "mkdocstrings[python]==0.20.0",
98
+ "mkdocstrings[python]==0.25.0",
99
99
  ]
100
100
 
101
101
  [tool.hatch.envs.test.scripts]
@@ -1,7 +1,7 @@
1
1
  from sqladmin.application import Admin, action, expose
2
2
  from sqladmin.models import BaseView, ModelView
3
3
 
4
- __version__ = "0.18.0"
4
+ __version__ = "0.19.0"
5
5
 
6
6
  __all__ = [
7
7
  "Admin",
@@ -26,6 +26,7 @@ class QueryAjaxModelLoader:
26
26
  self.model_admin = model_admin
27
27
  self.fields = options.get("fields", {})
28
28
  self.order_by = options.get("order_by")
29
+ self.limit = options.get("limit", DEFAULT_PAGE_SIZE)
29
30
 
30
31
  pks = get_primary_keys(self.model)
31
32
  self.pk = pks[0] if len(pks) == 1 else None
@@ -60,7 +61,7 @@ class QueryAjaxModelLoader:
60
61
 
61
62
  return {"id": str(get_object_identifier(model)), "text": str(model)}
62
63
 
63
- async def get_list(self, term: str, limit: int = DEFAULT_PAGE_SIZE) -> list[Any]:
64
+ async def get_list(self, term: str) -> list[Any]:
64
65
  stmt = select(self.model)
65
66
 
66
67
  # no type casting to string if a ColumnAssociationProxyInstance is given
@@ -71,9 +72,13 @@ class QueryAjaxModelLoader:
71
72
  stmt = stmt.filter(or_(*filters))
72
73
 
73
74
  if self.order_by:
74
- stmt = stmt.order_by(self.order_by)
75
+ if isinstance(self.order_by, list):
76
+ for o in self.order_by:
77
+ stmt = stmt.order_by(o)
78
+ else:
79
+ stmt = stmt.order_by(self.order_by)
75
80
 
76
- stmt = stmt.limit(limit)
81
+ stmt = stmt.limit(self.limit)
77
82
  result = await self.model_admin._run_query(stmt)
78
83
  return result
79
84
 
@@ -68,6 +68,7 @@ class BaseAdmin:
68
68
  base_url: str = "/admin",
69
69
  title: str = "Admin",
70
70
  logo_url: str | None = None,
71
+ favicon_url: str | None = None,
71
72
  templates_dir: str = "templates",
72
73
  middlewares: Sequence[Middleware] | None = None,
73
74
  authentication_backend: AuthenticationBackend | None = None,
@@ -78,6 +79,7 @@ class BaseAdmin:
78
79
  self.templates_dir = templates_dir
79
80
  self.title = title
80
81
  self.logo_url = logo_url
82
+ self.favicon_url = favicon_url
81
83
 
82
84
  if session_maker:
83
85
  self.session_maker = session_maker
@@ -340,6 +342,7 @@ class Admin(BaseAdminView):
340
342
  base_url: str = "/admin",
341
343
  title: str = "Admin",
342
344
  logo_url: str | None = None,
345
+ favicon_url: str | None = None,
343
346
  middlewares: Sequence[Middleware] | None = None,
344
347
  debug: bool = False,
345
348
  templates_dir: str = "templates",
@@ -353,6 +356,7 @@ class Admin(BaseAdminView):
353
356
  base_url: Base URL for Admin interface.
354
357
  title: Admin title.
355
358
  logo_url: URL of logo to be displayed instead of title.
359
+ favicon_url: URL of favicon to be displayed.
356
360
  """
357
361
 
358
362
  super().__init__(
@@ -362,6 +366,7 @@ class Admin(BaseAdminView):
362
366
  base_url=base_url,
363
367
  title=title,
364
368
  logo_url=logo_url,
369
+ favicon_url=favicon_url,
365
370
  templates_dir=templates_dir,
366
371
  middlewares=middlewares,
367
372
  authentication_backend=authentication_backend,
@@ -18,7 +18,12 @@ from typing import (
18
18
  import anyio
19
19
  from sqlalchemy import Boolean, select
20
20
  from sqlalchemy import inspect as sqlalchemy_inspect
21
- from sqlalchemy.orm import ColumnProperty, RelationshipProperty, sessionmaker
21
+ from sqlalchemy.orm import (
22
+ ColumnProperty,
23
+ RelationshipProperty,
24
+ sessionmaker,
25
+ )
26
+ from sqlalchemy.sql.elements import Label
22
27
  from sqlalchemy.sql.schema import Column
23
28
  from wtforms import (
24
29
  BooleanField,
@@ -612,9 +617,12 @@ async def get_model_form(
612
617
  attributes = []
613
618
  names = only or mapper.attrs.keys()
614
619
  for name in names:
615
- if exclude and name in exclude:
620
+ attr = mapper.attrs[name]
621
+ if (exclude and name in exclude) or (
622
+ isinstance(attr, ColumnProperty) and isinstance(attr.expression, Label)
623
+ ):
616
624
  continue
617
- attributes.append((name, mapper.attrs[name]))
625
+ attributes.append((name, attr))
618
626
 
619
627
  field_dict = {}
620
628
  for name, attr in attributes:
@@ -176,7 +176,7 @@ class BaseView(BaseModelView):
176
176
 
177
177
  icon: ClassVar[str] = ""
178
178
  """Display icon for ModelAdmin in the sidebar.
179
- Currently only supports FontAwesome icons.
179
+ Currently only supports FontAwesome and Tabler icons.
180
180
  """
181
181
 
182
182
  category: ClassVar[str] = ""
@@ -46,6 +46,11 @@ class Pagination:
46
46
 
47
47
  raise RuntimeError("Next page not found.")
48
48
 
49
+ def resize(self, page_size: int) -> Pagination:
50
+ self.page = (self.page - 1) * self.page_size // page_size + 1
51
+ self.page_size = page_size
52
+ return self
53
+
49
54
  def add_pagination_urls(self, base_url: URL) -> None:
50
55
  # Previous pages
51
56
  for p in range(self.page - min(self.max_page_controls, 3), self.page):