sqladmin 0.19.0__tar.gz → 0.20.1__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.
- {sqladmin-0.19.0 → sqladmin-0.20.1}/PKG-INFO +1 -1
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/__init__.py +1 -1
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/application.py +9 -10
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/models.py +43 -8
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/pagination.py +4 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/.gitignore +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/LICENSE.md +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/README.md +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/pyproject.toml +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/_menu.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/_queries.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/_types.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/_validators.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/ajax.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/authentication.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/exceptions.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/fields.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/formatters.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/forms.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/helpers.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/py.typed +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/flatpickr.min.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/fontawesome.min.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/main.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/select2.min.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/tabler-icons.min.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/tabler-icons.min.css.map +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/css/tabler.min.css +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/bootstrap.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/flatpickr.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/jquery.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/main.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/popper.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/select2.full.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/js/tabler.min.js +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/webfonts/fa-brands-400.woff2 +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/webfonts/fa-regular-400.woff2 +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/webfonts/fa-solid-900.woff2 +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/statics/webfonts/tabler-icons.woff2 +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/_macros.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/base.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/create.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/details.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/edit.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/error.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/index.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/layout.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/list.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/login.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/modals/delete.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/modals/details_action_confirmation.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/modals/list_action_confirmation.html +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templating.py +0 -0
- {sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/widgets.py +0 -0
|
@@ -442,12 +442,13 @@ class Admin(BaseAdminView):
|
|
|
442
442
|
pagination = await model_view.list(request)
|
|
443
443
|
pagination.add_pagination_urls(request.url)
|
|
444
444
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
445
|
+
request_page = model_view.validate_page_number(
|
|
446
|
+
request.query_params.get("page"), 1
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
if request_page > pagination.page:
|
|
450
|
+
return RedirectResponse(
|
|
451
|
+
request.url.include_query_params(page=pagination.page), status_code=302
|
|
451
452
|
)
|
|
452
453
|
|
|
453
454
|
context = {"model_view": model_view, "pagination": pagination}
|
|
@@ -510,8 +511,7 @@ class Admin(BaseAdminView):
|
|
|
510
511
|
identity = request.path_params["identity"]
|
|
511
512
|
model_view = self._find_model_view(identity)
|
|
512
513
|
|
|
513
|
-
Form = await model_view.scaffold_form()
|
|
514
|
-
model_view._validate_form_class(model_view._form_create_rules, Form)
|
|
514
|
+
Form = await model_view.scaffold_form(model_view._form_create_rules)
|
|
515
515
|
form_data = await self._handle_form_data(request)
|
|
516
516
|
form = Form(form_data)
|
|
517
517
|
|
|
@@ -561,8 +561,7 @@ class Admin(BaseAdminView):
|
|
|
561
561
|
if not model:
|
|
562
562
|
raise HTTPException(status_code=404)
|
|
563
563
|
|
|
564
|
-
Form = await model_view.scaffold_form()
|
|
565
|
-
model_view._validate_form_class(model_view._form_edit_rules, Form)
|
|
564
|
+
Form = await model_view.scaffold_form(model_view._form_edit_rules)
|
|
566
565
|
context = {
|
|
567
566
|
"obj": model,
|
|
568
567
|
"model_view": model_view,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
import time
|
|
4
5
|
import warnings
|
|
5
6
|
from enum import Enum
|
|
@@ -402,16 +403,16 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
402
403
|
Normally, objects have three save options:
|
|
403
404
|
``Save`, `Save and continue editing` and `Save and add another`.
|
|
404
405
|
|
|
405
|
-
If save_as is True, `Save and add another` will be replaced
|
|
406
|
-
by a `Save as new` button
|
|
407
|
-
that creates a new object (with a new ID)
|
|
406
|
+
If save_as is True, `Save and add another` will be replaced
|
|
407
|
+
by a `Save as new` button
|
|
408
|
+
that creates a new object (with a new ID)
|
|
408
409
|
rather than updating the existing object.
|
|
409
410
|
|
|
410
411
|
By default, `save_as` is set to `False`.
|
|
411
412
|
"""
|
|
412
413
|
|
|
413
414
|
save_as_continue: ClassVar[bool] = True
|
|
414
|
-
"""When `save_as=True`, the default redirect after saving the new object
|
|
415
|
+
"""When `save_as=True`, the default redirect after saving the new object
|
|
415
416
|
is to the edit view for that object.
|
|
416
417
|
If you set `save_as_continue=False`, the redirect will be to the list view.
|
|
417
418
|
|
|
@@ -454,7 +455,7 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
454
455
|
```
|
|
455
456
|
"""
|
|
456
457
|
|
|
457
|
-
export_types: ClassVar[List[str]] = ["csv"]
|
|
458
|
+
export_types: ClassVar[List[str]] = ["csv", "json"]
|
|
458
459
|
"""A list of available export filetypes.
|
|
459
460
|
Currently only `csv` is supported.
|
|
460
461
|
"""
|
|
@@ -1015,10 +1016,11 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
1015
1016
|
By default do nothing.
|
|
1016
1017
|
"""
|
|
1017
1018
|
|
|
1018
|
-
async def scaffold_form(self) -> Type[Form]:
|
|
1019
|
+
async def scaffold_form(self, rules: List[str] | None = None) -> Type[Form]:
|
|
1019
1020
|
if self.form is not None:
|
|
1020
1021
|
return self.form
|
|
1021
|
-
|
|
1022
|
+
|
|
1023
|
+
form = await get_model_form(
|
|
1022
1024
|
model=self.model,
|
|
1023
1025
|
session_maker=self.session_maker,
|
|
1024
1026
|
only=self._form_prop_names,
|
|
@@ -1032,6 +1034,11 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
1032
1034
|
form_converter=self.form_converter,
|
|
1033
1035
|
)
|
|
1034
1036
|
|
|
1037
|
+
if rules:
|
|
1038
|
+
self._validate_form_class(rules, form)
|
|
1039
|
+
|
|
1040
|
+
return form
|
|
1041
|
+
|
|
1035
1042
|
def search_placeholder(self) -> str:
|
|
1036
1043
|
"""Return search placeholder text.
|
|
1037
1044
|
|
|
@@ -1152,7 +1159,9 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
1152
1159
|
) -> StreamingResponse:
|
|
1153
1160
|
if export_type == "csv":
|
|
1154
1161
|
return await self._export_csv(data)
|
|
1155
|
-
|
|
1162
|
+
elif export_type == "json":
|
|
1163
|
+
return await self._export_json(data)
|
|
1164
|
+
raise NotImplementedError("Only export_type='csv' or 'json' is implemented.")
|
|
1156
1165
|
|
|
1157
1166
|
async def _export_csv(
|
|
1158
1167
|
self,
|
|
@@ -1179,6 +1188,32 @@ class ModelView(BaseView, metaclass=ModelViewMeta):
|
|
|
1179
1188
|
headers={"Content-Disposition": f"attachment;filename={filename}"},
|
|
1180
1189
|
)
|
|
1181
1190
|
|
|
1191
|
+
async def _export_json(
|
|
1192
|
+
self,
|
|
1193
|
+
data: List[Any],
|
|
1194
|
+
) -> StreamingResponse:
|
|
1195
|
+
async def generate() -> AsyncGenerator[str, None]:
|
|
1196
|
+
yield "["
|
|
1197
|
+
len_data = len(data)
|
|
1198
|
+
last_idx = len_data - 1
|
|
1199
|
+
separator = "," if len_data > 1 else ""
|
|
1200
|
+
|
|
1201
|
+
for idx, row in enumerate(data):
|
|
1202
|
+
row_dict = {
|
|
1203
|
+
name: str(await self.get_prop_value(row, name))
|
|
1204
|
+
for name in self._export_prop_names
|
|
1205
|
+
}
|
|
1206
|
+
yield json.dumps(row_dict) + (separator if idx < last_idx else "")
|
|
1207
|
+
|
|
1208
|
+
yield "]"
|
|
1209
|
+
|
|
1210
|
+
filename = secure_filename(self.get_export_name(export_type="json"))
|
|
1211
|
+
return StreamingResponse(
|
|
1212
|
+
content=generate(),
|
|
1213
|
+
media_type="application/json",
|
|
1214
|
+
headers={"Content-Disposition": f"attachment;filename={filename}"},
|
|
1215
|
+
)
|
|
1216
|
+
|
|
1182
1217
|
def _refresh_form_rules_cache(self) -> None:
|
|
1183
1218
|
if self.form_rules:
|
|
1184
1219
|
self._form_create_rules = self.form_rules
|
|
@@ -46,6 +46,10 @@ class Pagination:
|
|
|
46
46
|
|
|
47
47
|
raise RuntimeError("Next page not found.")
|
|
48
48
|
|
|
49
|
+
def __post_init__(self) -> None:
|
|
50
|
+
# Clamp page
|
|
51
|
+
self.page = min(self.page, max(1, self.count // self.page_size + 1))
|
|
52
|
+
|
|
49
53
|
def resize(self, page_size: int) -> Pagination:
|
|
50
54
|
self.page = (self.page - 1) * self.page_size // page_size + 1
|
|
51
55
|
self.page_size = page_size
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sqladmin-0.19.0 → sqladmin-0.20.1}/sqladmin/templates/sqladmin/modals/list_action_confirmation.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|