django-smartbase-admin 0.2.54__py3-none-any.whl → 1.0.42__py3-none-any.whl
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.
- django_smartbase_admin/actions/admin_action_list.py +79 -38
- django_smartbase_admin/actions/advanced_filters.py +24 -1
- django_smartbase_admin/admin/admin_base.py +402 -97
- django_smartbase_admin/admin/site.py +93 -35
- django_smartbase_admin/admin/widgets.py +636 -26
- django_smartbase_admin/apps.py +2 -0
- django_smartbase_admin/engine/actions.py +34 -16
- django_smartbase_admin/engine/admin_base_view.py +252 -115
- django_smartbase_admin/engine/configuration.py +186 -4
- django_smartbase_admin/engine/const.py +6 -0
- django_smartbase_admin/engine/dashboard.py +49 -24
- django_smartbase_admin/engine/fake_inline.py +15 -11
- django_smartbase_admin/engine/field.py +42 -12
- django_smartbase_admin/engine/field_formatter.py +38 -14
- django_smartbase_admin/engine/filter_widgets.py +348 -24
- django_smartbase_admin/engine/menu_item.py +8 -5
- django_smartbase_admin/engine/modal_view.py +12 -7
- django_smartbase_admin/engine/request.py +2 -0
- django_smartbase_admin/integration/__init__.py +0 -0
- django_smartbase_admin/integration/django_cms.py +43 -0
- django_smartbase_admin/locale/sk/LC_MESSAGES/django.mo +0 -0
- django_smartbase_admin/locale/sk/LC_MESSAGES/django.po +268 -37
- django_smartbase_admin/migrations/0005_sbadminuserconfiguration.py +26 -0
- django_smartbase_admin/migrations/0006_alter_sbadminuserconfiguration_color_scheme.py +18 -0
- django_smartbase_admin/models.py +22 -0
- django_smartbase_admin/monkeypatch/admin_readonly_field_monkeypatch.py +96 -0
- django_smartbase_admin/monkeypatch/fake_inline_monkeypatch.py +1 -1
- django_smartbase_admin/querysets.py +3 -0
- django_smartbase_admin/services/configuration.py +30 -0
- django_smartbase_admin/services/thread_local.py +6 -19
- django_smartbase_admin/services/views.py +80 -13
- django_smartbase_admin/services/xlsx_export.py +6 -0
- django_smartbase_admin/static/sb_admin/build/tailwind.config.js +1 -0
- django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/colors.js +4 -0
- django_smartbase_admin/static/sb_admin/build/tailwind_config_partials/spacing.js +1 -0
- django_smartbase_admin/static/sb_admin/build/webpack.common.js +11 -8
- django_smartbase_admin/static/sb_admin/css/ckeditor/ckeditor_content_dark.css +208 -0
- django_smartbase_admin/static/sb_admin/css/coloris/coloris.min.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar.js +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar_style.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/calendar_style.js +0 -0
- django_smartbase_admin/static/sb_admin/dist/chart.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/main.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/main_style.css +1 -1
- django_smartbase_admin/static/sb_admin/dist/table.js +1 -1
- django_smartbase_admin/static/sb_admin/dist/tree_widget.js +1 -0
- django_smartbase_admin/static/sb_admin/dist/tree_widget_style.css +1 -0
- django_smartbase_admin/static/sb_admin/dist/tree_widget_style.js +0 -0
- django_smartbase_admin/static/sb_admin/fancytree/jquery.fancytree-all-deps.min.js +1 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-csv.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-doc.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-docx.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-other.svg +13 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-pdf.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-ppt.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xls.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-xlsx.svg +11 -0
- django_smartbase_admin/static/sb_admin/images/file_types/file-zip.svg +18 -0
- django_smartbase_admin/static/sb_admin/images/flags/de-at.png +0 -0
- django_smartbase_admin/static/sb_admin/images/flags/de-ch.png +0 -0
- django_smartbase_admin/static/sb_admin/images/logo_light.svg +21 -0
- django_smartbase_admin/static/sb_admin/js/coloris/coloris.min.js +6 -0
- django_smartbase_admin/static/sb_admin/js/fullcalendar.min.js +14804 -0
- django_smartbase_admin/static/sb_admin/js/sbadmin_prepopulated_fields_init.js +25 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Bolt-one.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Calendar.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Caution.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Electric-drill.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Fire-extinguisher.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Gas.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Lightning-fill.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Moon.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Phone-telephone.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Printer.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Pull.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Sun-one.svg +3 -0
- django_smartbase_admin/static/sb_admin/sprites/sb_admin/Time.svg +3 -0
- django_smartbase_admin/static/sb_admin/src/css/_base.css +5 -1
- django_smartbase_admin/static/sb_admin/src/css/_colors.css +257 -82
- django_smartbase_admin/static/sb_admin/src/css/_components.css +61 -13
- django_smartbase_admin/static/sb_admin/src/css/_datepicker.css +8 -1
- django_smartbase_admin/static/sb_admin/src/css/_filer.css +60 -0
- django_smartbase_admin/static/sb_admin/src/css/_inlines.css +51 -10
- django_smartbase_admin/static/sb_admin/src/css/_tabulator.css +8 -2
- django_smartbase_admin/static/sb_admin/src/css/calendar.css +162 -0
- django_smartbase_admin/static/sb_admin/src/css/components/_button.css +41 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_dropdown.css +31 -7
- django_smartbase_admin/static/sb_admin/src/css/components/_input.css +62 -20
- django_smartbase_admin/static/sb_admin/src/css/components/_modal.css +1 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_query-builder.css +21 -2
- django_smartbase_admin/static/sb_admin/src/css/components/_toggle.css +12 -1
- django_smartbase_admin/static/sb_admin/src/css/components/_tooltip.css +8 -22
- django_smartbase_admin/static/sb_admin/src/css/style.css +17 -0
- django_smartbase_admin/static/sb_admin/src/css/tree_widget.css +411 -0
- django_smartbase_admin/static/sb_admin/src/js/autocomplete.js +69 -11
- django_smartbase_admin/static/sb_admin/src/js/calendar.js +56 -0
- django_smartbase_admin/static/sb_admin/src/js/chart.js +8 -22
- django_smartbase_admin/static/sb_admin/src/js/choices.js +18 -8
- django_smartbase_admin/static/sb_admin/src/js/datepicker.js +97 -336
- django_smartbase_admin/static/sb_admin/src/js/datepicker_plugins.js +357 -0
- django_smartbase_admin/static/sb_admin/src/js/main.js +306 -31
- django_smartbase_admin/static/sb_admin/src/js/multiselect.js +50 -41
- django_smartbase_admin/static/sb_admin/src/js/radio.js +31 -0
- django_smartbase_admin/static/sb_admin/src/js/range.js +3 -2
- django_smartbase_admin/static/sb_admin/src/js/table.js +34 -5
- django_smartbase_admin/static/sb_admin/src/js/table_modules/advanced_filter_module.js +43 -20
- django_smartbase_admin/static/sb_admin/src/js/table_modules/data_edit_module.js +8 -10
- django_smartbase_admin/static/sb_admin/src/js/table_modules/detail_view_module.js +50 -1
- django_smartbase_admin/static/sb_admin/src/js/table_modules/filter_module.js +10 -3
- django_smartbase_admin/static/sb_admin/src/js/table_modules/header_tabs_module.js +11 -11
- django_smartbase_admin/static/sb_admin/src/js/table_modules/selection_module.js +28 -8
- django_smartbase_admin/static/sb_admin/src/js/table_modules/table_params_module.js +6 -0
- django_smartbase_admin/static/sb_admin/src/js/table_modules/views_module.js +6 -0
- django_smartbase_admin/static/sb_admin/src/js/tree_widget.js +406 -0
- django_smartbase_admin/static/sb_admin/src/js/utils.js +56 -21
- django_smartbase_admin/templates/sb_admin/actions/change_form.html +176 -116
- django_smartbase_admin/templates/sb_admin/actions/dashboard.html +2 -2
- django_smartbase_admin/templates/sb_admin/actions/list.html +79 -39
- django_smartbase_admin/templates/sb_admin/actions/partials/action_link.html +14 -0
- django_smartbase_admin/templates/sb_admin/actions/partials/tabulator_header_v2.html +2 -2
- django_smartbase_admin/templates/sb_admin/actions/tree_list.html +63 -0
- django_smartbase_admin/templates/sb_admin/authentification/login_base.html +5 -1
- django_smartbase_admin/templates/sb_admin/components/columns.html +1 -1
- django_smartbase_admin/templates/sb_admin/components/filters.html +1 -0
- django_smartbase_admin/templates/sb_admin/components/filters_v2.html +99 -85
- django_smartbase_admin/templates/sb_admin/dashboard/calendar_widget.html +69 -0
- django_smartbase_admin/templates/sb_admin/dashboard/chart_widget.html +21 -2
- django_smartbase_admin/templates/sb_admin/dashboard/list_widget.html +6 -0
- django_smartbase_admin/templates/sb_admin/dashboard/widget_base.html +1 -1
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/date_field.html +18 -8
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/multiple_choice_field.html +1 -1
- django_smartbase_admin/templates/sb_admin/filter_widgets/advanced_filters/tree_select_filter.html +2 -0
- django_smartbase_admin/templates/sb_admin/filter_widgets/boolean_field.html +1 -14
- django_smartbase_admin/templates/sb_admin/filter_widgets/date_field.html +18 -4
- django_smartbase_admin/templates/sb_admin/filter_widgets/multiple_choice_field.html +14 -0
- django_smartbase_admin/templates/sb_admin/filter_widgets/partials/clear.html +12 -6
- django_smartbase_admin/templates/sb_admin/filter_widgets/radio_choice_field.html +5 -3
- django_smartbase_admin/templates/sb_admin/filter_widgets/tree_select_filter.html +16 -0
- django_smartbase_admin/templates/sb_admin/includes/change_form_title.html +3 -1
- django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html +48 -39
- django_smartbase_admin/templates/sb_admin/includes/notifications.html +2 -1
- django_smartbase_admin/templates/sb_admin/includes/readonly_boolean_field.html +9 -0
- django_smartbase_admin/templates/sb_admin/includes/readonly_field.html +12 -0
- django_smartbase_admin/templates/sb_admin/includes/table_inline_delete_button.html +4 -5
- django_smartbase_admin/templates/sb_admin/inlines/stacked_inline.html +68 -40
- django_smartbase_admin/templates/sb_admin/inlines/table_inline.html +76 -34
- django_smartbase_admin/templates/sb_admin/integrations/filer/folder_list.html +18 -0
- django_smartbase_admin/templates/sb_admin/navigation.html +166 -158
- django_smartbase_admin/templates/sb_admin/partials/modal/modal_content.html +2 -6
- django_smartbase_admin/templates/sb_admin/sb_admin_base.html +49 -4
- django_smartbase_admin/templates/sb_admin/sb_admin_base_no_sidebar.html +27 -11
- django_smartbase_admin/templates/sb_admin/sb_admin_js_trans.html +3 -0
- django_smartbase_admin/templates/sb_admin/sprites/sb_admin.svg +1 -1
- django_smartbase_admin/templates/sb_admin/tailwind_whitelist.html +6 -3
- django_smartbase_admin/templates/sb_admin/widgets/array.html +0 -1
- django_smartbase_admin/templates/sb_admin/widgets/attributes.html +68 -0
- django_smartbase_admin/templates/sb_admin/widgets/autocomplete.html +13 -2
- django_smartbase_admin/templates/sb_admin/widgets/{checkbox_select.html → checkbox_dropdown.html} +2 -2
- django_smartbase_admin/templates/sb_admin/widgets/clearable_file_input.html +2 -2
- django_smartbase_admin/templates/sb_admin/widgets/color_field.html +30 -0
- django_smartbase_admin/templates/sb_admin/widgets/date.html +8 -1
- django_smartbase_admin/templates/sb_admin/widgets/filer_file.html +84 -0
- django_smartbase_admin/templates/sb_admin/widgets/includes/related_item_buttons.html +38 -0
- django_smartbase_admin/templates/sb_admin/widgets/multiwidget.html +1 -1
- django_smartbase_admin/templates/sb_admin/widgets/radio.html +3 -2
- django_smartbase_admin/templates/sb_admin/widgets/radio_dropdown.html +30 -0
- django_smartbase_admin/templates/sb_admin/widgets/read_only_password_hash.html +3 -0
- django_smartbase_admin/templates/sb_admin/widgets/time.html +8 -1
- django_smartbase_admin/templates/sb_admin/widgets/toggle.html +1 -1
- django_smartbase_admin/templates/sb_admin/widgets/tree_base.html +59 -0
- django_smartbase_admin/templates/sb_admin/widgets/tree_select.html +24 -0
- django_smartbase_admin/templates/sb_admin/widgets/tree_select_inline.html +12 -0
- django_smartbase_admin/templatetags/sb_admin_tags.py +115 -4
- django_smartbase_admin/utils.py +22 -3
- django_smartbase_admin/views/dashboard_view.py +6 -0
- django_smartbase_admin/views/global_filter_view.py +8 -2
- django_smartbase_admin/views/translations_view.py +12 -5
- django_smartbase_admin/views/user_config_view.py +52 -0
- django_smartbase_admin-1.0.42.dist-info/METADATA +166 -0
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/RECORD +182 -118
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/WHEEL +1 -1
- django_smartbase_admin/templates/sb_admin/integrations/sorting/change_list.html +0 -401
- django_smartbase_admin-0.2.54.dist-info/METADATA +0 -25
- {django_smartbase_admin-0.2.54.dist-info → django_smartbase_admin-1.0.42.dist-info}/LICENSE.md +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
1
2
|
import json
|
|
2
3
|
import math
|
|
4
|
+
from typing import Any, TYPE_CHECKING
|
|
3
5
|
|
|
4
|
-
from django.core.paginator import Paginator
|
|
5
6
|
from django.db.models import Q
|
|
6
7
|
from django.utils import timezone
|
|
8
|
+
from django.utils.html import escape
|
|
9
|
+
from django.utils.safestring import SafeString
|
|
7
10
|
from django.utils.text import smart_split, unescape_string_literal
|
|
8
11
|
|
|
9
|
-
from django_smartbase_admin.engine.actions import SBAdminAction
|
|
10
12
|
from django_smartbase_admin.engine.const import (
|
|
11
13
|
XLSX_PAGE_CHUNK_SIZE,
|
|
12
14
|
SELECTED_ROWS_KWARG_NAME,
|
|
@@ -32,8 +34,8 @@ from django_smartbase_admin.engine.const import (
|
|
|
32
34
|
CONFIG_NAME,
|
|
33
35
|
TABLE_PARAMS_FULL_TEXT_SEARCH,
|
|
34
36
|
TABLE_PARAMS_SELECTED_FILTER_TYPE,
|
|
35
|
-
FilterVersions,
|
|
36
37
|
ADVANCED_FILTER_DATA_NAME,
|
|
38
|
+
IGNORE_LIST_SELECTION,
|
|
37
39
|
)
|
|
38
40
|
from django_smartbase_admin.services.views import SBAdminViewService
|
|
39
41
|
from django_smartbase_admin.utils import import_with_injection
|
|
@@ -42,6 +44,19 @@ QueryBuilderService = import_with_injection(
|
|
|
42
44
|
"django_smartbase_admin.actions.advanced_filters", "QueryBuilderService"
|
|
43
45
|
)
|
|
44
46
|
|
|
47
|
+
if TYPE_CHECKING:
|
|
48
|
+
from django_smartbase_admin.engine.field import SBAdminField
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class SBAdminAction(object):
|
|
52
|
+
view = None
|
|
53
|
+
threadsafe_request = None
|
|
54
|
+
|
|
55
|
+
def __init__(self, view, request) -> None:
|
|
56
|
+
super().__init__()
|
|
57
|
+
self.view = view
|
|
58
|
+
self.threadsafe_request = request
|
|
59
|
+
|
|
45
60
|
|
|
46
61
|
class SBAdminListAction(SBAdminAction):
|
|
47
62
|
def __init__(
|
|
@@ -83,7 +98,7 @@ class SBAdminListAction(SBAdminAction):
|
|
|
83
98
|
)
|
|
84
99
|
self.deselected_rows = self.selection_data.get(DESELECTED_ROWS_KWARG_NAME, [])
|
|
85
100
|
self.page_size = page_size or self.table_params.get(
|
|
86
|
-
TABLE_PARAMS_SIZE_NAME, self.view.get_list_per_page()
|
|
101
|
+
TABLE_PARAMS_SIZE_NAME, self.view.get_list_per_page(request)
|
|
87
102
|
)
|
|
88
103
|
self.init_column_fields()
|
|
89
104
|
self.tabulator_definition = tabulator_definition
|
|
@@ -132,11 +147,6 @@ class SBAdminListAction(SBAdminAction):
|
|
|
132
147
|
if field.field in values
|
|
133
148
|
]
|
|
134
149
|
|
|
135
|
-
def is_jquery_required(self, request):
|
|
136
|
-
return (
|
|
137
|
-
self.view.get_filters_version(request) == FilterVersions.FILTERS_VERSION_2
|
|
138
|
-
)
|
|
139
|
-
|
|
140
150
|
def get_template_data(self):
|
|
141
151
|
context_data = self.view.get_context_data(self.threadsafe_request)
|
|
142
152
|
constants = {
|
|
@@ -175,7 +185,9 @@ class SBAdminListAction(SBAdminAction):
|
|
|
175
185
|
tabulator_definition["tableIdColumnName"] = id_column_name
|
|
176
186
|
tabulator_definition["constants"] = constants
|
|
177
187
|
|
|
178
|
-
list_actions = self.list_actions or self.view._get_sbadmin_list_actions(
|
|
188
|
+
list_actions = self.list_actions or self.view._get_sbadmin_list_actions(
|
|
189
|
+
self.threadsafe_request
|
|
190
|
+
)
|
|
179
191
|
|
|
180
192
|
context_data.update(
|
|
181
193
|
{
|
|
@@ -183,7 +195,6 @@ class SBAdminListAction(SBAdminAction):
|
|
|
183
195
|
"tabulator_definition": tabulator_definition,
|
|
184
196
|
"id_column_name": id_column_name,
|
|
185
197
|
"filters": self.get_filters(),
|
|
186
|
-
"is_jquery_required": self.is_jquery_required(self.threadsafe_request),
|
|
187
198
|
"advanced_filters_data": QueryBuilderService.get_advanced_filters_context_data(
|
|
188
199
|
self
|
|
189
200
|
),
|
|
@@ -194,16 +205,18 @@ class SBAdminListAction(SBAdminAction):
|
|
|
194
205
|
self.threadsafe_request
|
|
195
206
|
),
|
|
196
207
|
"search_fields": self.view.get_search_fields(self.threadsafe_request),
|
|
197
|
-
"search_field_placeholder": self.view.get_search_field_placeholder(
|
|
198
|
-
|
|
208
|
+
"search_field_placeholder": self.view.get_search_field_placeholder(
|
|
209
|
+
self.threadsafe_request
|
|
210
|
+
),
|
|
211
|
+
"list_actions": self.view.process_actions(
|
|
199
212
|
self.threadsafe_request, list_actions
|
|
200
213
|
),
|
|
201
214
|
"list_selection_actions": self.view.get_sbadmin_list_selection_actions_grouped(
|
|
202
215
|
self.threadsafe_request
|
|
203
216
|
),
|
|
204
|
-
"config_url": self.view.get_config_url(),
|
|
217
|
+
"config_url": self.view.get_config_url(self.threadsafe_request),
|
|
205
218
|
"new_url": (
|
|
206
|
-
self.view.get_new_url()
|
|
219
|
+
self.view.get_new_url(self.threadsafe_request)
|
|
207
220
|
if self.view.has_add_permission(self.threadsafe_request)
|
|
208
221
|
else None
|
|
209
222
|
),
|
|
@@ -217,9 +230,23 @@ class SBAdminListAction(SBAdminAction):
|
|
|
217
230
|
for sort in self.table_params.get("sort", []):
|
|
218
231
|
order_by.append(f"{'-' if sort['dir'] == 'desc' else ''}{sort['field']}")
|
|
219
232
|
if len(order_by) == 0:
|
|
220
|
-
order_by = self.view.get_list_ordering() or [
|
|
233
|
+
order_by = self.view.get_list_ordering(self.threadsafe_request) or [
|
|
234
|
+
self.get_pk_field().name
|
|
235
|
+
]
|
|
221
236
|
return order_by
|
|
222
237
|
|
|
238
|
+
def get_order_by_fields_from_request(self):
|
|
239
|
+
order_by = self.get_order_by_from_request()
|
|
240
|
+
order_by_fields = []
|
|
241
|
+
order_by_fields_names = set()
|
|
242
|
+
for field in order_by:
|
|
243
|
+
field_name = field[1:] if field.startswith("-") else field
|
|
244
|
+
order_by_fields_names.add(field_name)
|
|
245
|
+
for field in self.column_fields:
|
|
246
|
+
if field.name in order_by_fields_names:
|
|
247
|
+
order_by_fields.append(field)
|
|
248
|
+
return order_by_fields
|
|
249
|
+
|
|
223
250
|
def get_filter_from_request(self):
|
|
224
251
|
base_filters = SBAdminViewService.get_filter_from_request(
|
|
225
252
|
self.threadsafe_request, self.column_fields, self.filter_data
|
|
@@ -246,6 +273,7 @@ class SBAdminListAction(SBAdminAction):
|
|
|
246
273
|
filter_fields.extend(
|
|
247
274
|
QueryBuilderService.get_filters_fields_for_list_action(self)
|
|
248
275
|
)
|
|
276
|
+
filter_fields.extend(self.get_order_by_fields_from_request())
|
|
249
277
|
if self.is_search_query():
|
|
250
278
|
search_fields = self.get_search_fields(self.threadsafe_request)
|
|
251
279
|
filter_fields.extend(search_fields)
|
|
@@ -264,7 +292,7 @@ class SBAdminListAction(SBAdminAction):
|
|
|
264
292
|
**self.get_annotates(visible_fields)
|
|
265
293
|
)
|
|
266
294
|
|
|
267
|
-
def get_visible_column_fields(self):
|
|
295
|
+
def get_visible_column_fields(self) -> list[SBAdminField]:
|
|
268
296
|
columns_data_dict = self.columns_data.get(COLUMNS_DATA_COLUMNS_NAME, {})
|
|
269
297
|
return [
|
|
270
298
|
field
|
|
@@ -281,8 +309,15 @@ class SBAdminListAction(SBAdminAction):
|
|
|
281
309
|
values = [self.get_pk_field().name]
|
|
282
310
|
visible_column_fields = self.get_visible_column_fields()
|
|
283
311
|
values.extend([field.field for field in visible_column_fields])
|
|
312
|
+
# Include supporting_annotates keys for visible columns
|
|
313
|
+
for field in visible_column_fields:
|
|
314
|
+
if field.supporting_annotates:
|
|
315
|
+
values.extend(field.supporting_annotates.keys())
|
|
284
316
|
if self.view.sbadmin_list_display_data:
|
|
285
317
|
values.extend(self.view.sbadmin_list_display_data)
|
|
318
|
+
values.extend(
|
|
319
|
+
[field.field for field in self.get_order_by_fields_from_request()]
|
|
320
|
+
)
|
|
286
321
|
return values
|
|
287
322
|
|
|
288
323
|
def get_search_results(self, request, queryset, search_term):
|
|
@@ -379,32 +414,33 @@ class SBAdminListAction(SBAdminAction):
|
|
|
379
414
|
"last_row": total_count,
|
|
380
415
|
}
|
|
381
416
|
|
|
382
|
-
def process_final_data(self, final_data):
|
|
417
|
+
def process_final_data(self, final_data: list[dict[str, Any]]) -> None:
|
|
383
418
|
visible_columns = self.get_visible_column_fields()
|
|
384
|
-
|
|
385
|
-
field
|
|
386
|
-
|
|
387
|
-
if field.view_method or field.python_formatter
|
|
388
|
-
]
|
|
419
|
+
field_key_field_map: dict[str, SBAdminField] = {
|
|
420
|
+
field.field: field for field in visible_columns
|
|
421
|
+
}
|
|
389
422
|
for row in final_data:
|
|
423
|
+
obj_id = row.get(self.get_pk_field().name, None)
|
|
390
424
|
additional_data = {}
|
|
391
425
|
if self.view.sbadmin_list_display_data:
|
|
392
426
|
additional_data = {
|
|
393
427
|
data: row.get(data, None)
|
|
394
428
|
for data in self.view.sbadmin_list_display_data
|
|
395
429
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
430
|
+
# Include supporting_annotates values in additional_data
|
|
431
|
+
for field in visible_columns:
|
|
432
|
+
if field.supporting_annotates:
|
|
433
|
+
for key in field.supporting_annotates.keys():
|
|
434
|
+
additional_data[key] = row.get(key, None)
|
|
435
|
+
for field_key, value in row.items():
|
|
436
|
+
if field_key in field_key_field_map:
|
|
437
|
+
field = field_key_field_map[field_key]
|
|
438
|
+
value = self.view.process_field_data(
|
|
439
|
+
self.threadsafe_request, field, obj_id, value, additional_data
|
|
403
440
|
)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
row[field.field] = formatted_value
|
|
441
|
+
if isinstance(value, str) and not isinstance(value, SafeString):
|
|
442
|
+
value = escape(value)
|
|
443
|
+
row[field_key] = value
|
|
408
444
|
|
|
409
445
|
def get_json_data(self):
|
|
410
446
|
return self.get_data()
|
|
@@ -419,6 +455,9 @@ class SBAdminListAction(SBAdminAction):
|
|
|
419
455
|
return final_data
|
|
420
456
|
|
|
421
457
|
def get_selection_queryset(self):
|
|
458
|
+
if not self.selection_data:
|
|
459
|
+
# don't run with no selection data as it will result in querying all records
|
|
460
|
+
return Q(id__in=[])
|
|
422
461
|
additional_filter = None
|
|
423
462
|
if self.selected_rows and self.selected_rows != SELECT_ALL_KEYWORD:
|
|
424
463
|
additional_filter = Q(id__in=self.selected_rows)
|
|
@@ -427,13 +466,15 @@ class SBAdminListAction(SBAdminAction):
|
|
|
427
466
|
additional_filter = ~Q(id__in=self.deselected_rows)
|
|
428
467
|
return additional_filter
|
|
429
468
|
|
|
430
|
-
def get_xlsx_data(self):
|
|
469
|
+
def get_xlsx_data(self, request):
|
|
431
470
|
page_size = XLSX_PAGE_CHUNK_SIZE
|
|
432
471
|
file_name = (
|
|
433
472
|
f'{self.view.get_menu_label()}__{timezone.now().strftime("%Y-%m-%d")}.xlsx'
|
|
434
473
|
)
|
|
435
474
|
columns = self.get_excel_columns()
|
|
436
|
-
additional_filter =
|
|
475
|
+
additional_filter = Q()
|
|
476
|
+
if request.request_data.modifier != IGNORE_LIST_SELECTION:
|
|
477
|
+
additional_filter = self.get_selection_queryset()
|
|
437
478
|
data_list = []
|
|
438
479
|
report_data = self.get_data(
|
|
439
480
|
page_size=page_size,
|
|
@@ -450,8 +491,8 @@ class SBAdminListAction(SBAdminAction):
|
|
|
450
491
|
)["data"]
|
|
451
492
|
)
|
|
452
493
|
options = (
|
|
453
|
-
self.view.get_sbadmin_xlsx_options().to_json()
|
|
454
|
-
if self.view.get_sbadmin_xlsx_options()
|
|
494
|
+
self.view.get_sbadmin_xlsx_options(request).to_json()
|
|
495
|
+
if self.view.get_sbadmin_xlsx_options(request)
|
|
455
496
|
else {}
|
|
456
497
|
)
|
|
457
498
|
return [file_name, data_list, columns, options]
|
|
@@ -5,7 +5,7 @@ from dataclasses import field as dataclass_field
|
|
|
5
5
|
from typing import List, Optional, TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from django.db import models
|
|
8
|
-
from django.db.models import Q
|
|
8
|
+
from django.db.models import Q, Count
|
|
9
9
|
from django.template.loader import render_to_string
|
|
10
10
|
from django.utils.translation import gettext_lazy as _
|
|
11
11
|
|
|
@@ -45,6 +45,8 @@ class AllOperators(models.TextChoices):
|
|
|
45
45
|
IS_NOT_NULL = "is_not_null", _("Is not null")
|
|
46
46
|
BEFORE = "before", _("Before")
|
|
47
47
|
AFTER = "after", _("After")
|
|
48
|
+
IN_THE_LAST = "in_the_last", _("In the last")
|
|
49
|
+
IN_THE_NEXT = "in_the_next", _("In the next")
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
NULL_ATTRIBUTES = [
|
|
@@ -59,6 +61,8 @@ DATE_ATTRIBUTES = [
|
|
|
59
61
|
AllOperators.AFTER,
|
|
60
62
|
AllOperators.IS_NULL,
|
|
61
63
|
AllOperators.IS_NOT_NULL,
|
|
64
|
+
AllOperators.IN_THE_LAST,
|
|
65
|
+
AllOperators.IN_THE_NEXT,
|
|
62
66
|
]
|
|
63
67
|
|
|
64
68
|
NUMBER_ATTRIBUTES = [
|
|
@@ -157,6 +161,8 @@ class QueryBuilderService:
|
|
|
157
161
|
AllOperators.IS_NOT_NULL.value: "__isnull",
|
|
158
162
|
AllOperators.BEFORE.value: "__lt",
|
|
159
163
|
AllOperators.AFTER.value: "__gte",
|
|
164
|
+
AllOperators.IN_THE_LAST.value: "__range",
|
|
165
|
+
AllOperators.IN_THE_NEXT.value: "__range",
|
|
160
166
|
}
|
|
161
167
|
|
|
162
168
|
ZERO_INPUTS_OPERATORS = {
|
|
@@ -252,11 +258,28 @@ class QueryBuilderService:
|
|
|
252
258
|
if operator in [AllOperators.IS_NULL, AllOperators.IS_NOT_NULL]
|
|
253
259
|
else ""
|
|
254
260
|
)
|
|
261
|
+
if field.annotate and isinstance(field.annotate, Count):
|
|
262
|
+
filter_value = 0
|
|
255
263
|
q = Q(
|
|
256
264
|
**{
|
|
257
265
|
f"{field.filter_field}{cls.OPERATOR_MAP[operator]}": filter_value,
|
|
258
266
|
}
|
|
259
267
|
)
|
|
268
|
+
from django_smartbase_admin.engine.filter_widgets import (
|
|
269
|
+
StringFilterWidget,
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
if isinstance(
|
|
273
|
+
field.filter_widget, StringFilterWidget
|
|
274
|
+
) and operator in [
|
|
275
|
+
AllOperators.IS_EMPTY,
|
|
276
|
+
AllOperators.IS_NOT_EMPTY,
|
|
277
|
+
]:
|
|
278
|
+
q = q | Q(
|
|
279
|
+
**{
|
|
280
|
+
f"{field.filter_field}{cls.OPERATOR_MAP[AllOperators.IS_NULL]}": True
|
|
281
|
+
}
|
|
282
|
+
)
|
|
260
283
|
else:
|
|
261
284
|
value = field.filter_widget.parse_value_from_input(
|
|
262
285
|
request, rule["value"]
|