django-smartbase-admin 0.2.73__py3-none-any.whl → 0.2.74__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.
@@ -6,7 +6,6 @@ from django.db.models import Q
6
6
  from django.utils import timezone
7
7
  from django.utils.text import smart_split, unescape_string_literal
8
8
 
9
- from django_smartbase_admin.engine.actions import SBAdminAction
10
9
  from django_smartbase_admin.engine.const import (
11
10
  XLSX_PAGE_CHUNK_SIZE,
12
11
  SELECTED_ROWS_KWARG_NAME,
@@ -43,6 +42,16 @@ QueryBuilderService = import_with_injection(
43
42
  )
44
43
 
45
44
 
45
+ class SBAdminAction(object):
46
+ view = None
47
+ threadsafe_request = None
48
+
49
+ def __init__(self, view, request) -> None:
50
+ super().__init__()
51
+ self.view = view
52
+ self.threadsafe_request = request
53
+
54
+
46
55
  class SBAdminListAction(SBAdminAction):
47
56
  def __init__(
48
57
  self,
@@ -37,6 +37,7 @@ from nested_admin.nested import (
37
37
 
38
38
  from django_smartbase_admin.actions.admin_action_list import SBAdminListAction
39
39
  from django_smartbase_admin.engine.actions import SBAdminCustomAction
40
+ from django_smartbase_admin.services.thread_local import SBAdminThreadLocalService
40
41
  from django_smartbase_admin.utils import FormFieldsetMixin
41
42
 
42
43
  parler_enabled = None
@@ -94,6 +95,7 @@ from django_smartbase_admin.admin.widgets import (
94
95
  SBAdminHiddenWidget,
95
96
  SBAdminCKEditorUploadingWidget,
96
97
  SBAdminAttributesWidget,
98
+ SBAdminMultipleChoiceInlineWidget,
97
99
  )
98
100
  from django_smartbase_admin.engine.admin_base_view import (
99
101
  SBAdminBaseListView,
@@ -132,6 +134,8 @@ class SBAdminFormFieldWidgetsMixin:
132
134
  RichTextUploadingFormField: SBAdminCKEditorUploadingWidget,
133
135
  forms.ChoiceField: SBAdminSelectWidget,
134
136
  forms.TypedChoiceField: SBAdminSelectWidget,
137
+ forms.MultipleChoiceField: SBAdminMultipleChoiceInlineWidget,
138
+ forms.TypedMultipleChoiceField: SBAdminMultipleChoiceInlineWidget,
135
139
  forms.NullBooleanField: SBAdminNullBooleanSelectWidget,
136
140
  AdminImageFormField: SBAdminImageWidget,
137
141
  ReadOnlyPasswordHashWidget: SBAdminReadOnlyPasswordHashWidget,
@@ -263,12 +267,13 @@ class SBAdminFormFieldWidgetsMixin:
263
267
 
264
268
 
265
269
  class SBAdminBaseFormInit(SBAdminFormFieldWidgetsMixin, FormFieldsetMixin):
266
- threadsafe_request = None
267
270
  view = None
268
271
 
269
272
  def __init__(self, *args, **kwargs):
270
273
  self.view = kwargs.pop("view", self.view)
271
- self.threadsafe_request = kwargs.pop("request", self.threadsafe_request)
274
+ threadsafe_request = kwargs.pop(
275
+ "request", SBAdminThreadLocalService.get_request()
276
+ )
272
277
  super().__init__(*args, **kwargs)
273
278
  for field in self.fields:
274
279
  if not hasattr(self.fields[field].widget, "init_widget_dynamic"):
@@ -278,14 +283,12 @@ class SBAdminBaseFormInit(SBAdminFormFieldWidgetsMixin, FormFieldsetMixin):
278
283
  self.fields[field],
279
284
  field,
280
285
  self.view,
281
- self.threadsafe_request,
286
+ threadsafe_request,
282
287
  )
283
288
  for field in self.declared_fields:
284
289
  form_field = self.fields.get(field)
285
290
  if form_field:
286
- self.assign_widget_to_form_field(
287
- form_field, request=self.threadsafe_request
288
- )
291
+ self.assign_widget_to_form_field(form_field, request=threadsafe_request)
289
292
 
290
293
 
291
294
  class SBAdminBaseForm(SBAdminBaseFormInit, forms.ModelForm):
@@ -485,11 +488,6 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
485
488
  if form:
486
489
  form.view = self
487
490
 
488
- def initialize_form_class_threadsafe(self, form, request):
489
- self.initialize_form_class(form)
490
- if form:
491
- form.threadsafe_request = request
492
-
493
491
 
494
492
  class SBAdminThirdParty(SBAdminInlineAndAdminCommon, SBAdminBaseView):
495
493
  def get_menu_view_url(self, request):
@@ -643,7 +641,7 @@ class SBAdmin(
643
641
 
644
642
  def get_form(self, request, obj=None, **kwargs):
645
643
  form = super().get_form(request, obj, **kwargs)
646
- self.initialize_form_class_threadsafe(form, request)
644
+ self.initialize_form_class(form)
647
645
  return form
648
646
 
649
647
  def get_id(self):
@@ -705,7 +703,11 @@ class SBAdmin(
705
703
  all_config = self.get_all_config(request)
706
704
  url_suffix = ""
707
705
  if all_config and all_config.get("all_params_changed", False):
708
- url_params_dict = all_config.get("url_params")
706
+ url_params_dict = SBAdminViewService.process_url_params(
707
+ view_id=self.get_id(),
708
+ url_params=all_config.get("url_params"),
709
+ filter_version=self.get_filters_version(request),
710
+ )
709
711
  if url_params_dict:
710
712
  url_suffix = f"?{SBAdminViewService.build_list_url(self.get_id(), url_params_dict)}"
711
713
 
@@ -912,7 +914,7 @@ class SBAdminInline(
912
914
  def register_autocomplete_views(self, request):
913
915
  super().register_autocomplete_views(request)
914
916
  form_class = self.get_formset(request, self.model()).form
915
- self.initialize_form_class_threadsafe(form_class, request)
917
+ self.initialize_form_class(form_class)
916
918
  form_class()
917
919
 
918
920
  @property
@@ -956,7 +958,7 @@ class SBAdminInline(
956
958
  def get_formset(self, request, obj=None, **kwargs):
957
959
  formset = super().get_formset(request, obj, **kwargs)
958
960
  form_class = formset.form
959
- self.initialize_form_class_threadsafe(form_class, request)
961
+ self.initialize_form_class(form_class)
960
962
  return formset
961
963
 
962
964
 
@@ -34,7 +34,7 @@ class SBAdminSite(admin.AdminSite):
34
34
  request.sbadmin_selected_view = selected_view
35
35
  kwargs["view"] = selected_view.get_id() if selected_view else None
36
36
  request_data = SBAdminViewRequestData.from_request_and_kwargs(request, **kwargs)
37
- SBAdminThreadLocalService.set_data("request", request)
37
+ SBAdminThreadLocalService.set_request(request)
38
38
  if selected_view:
39
39
  # Initialize SBAdmin, ModelAdmin instances, class-based SBAdminEntrypointView are initialized with request_data
40
40
  selected_view.init_view_dynamic(
@@ -49,7 +49,6 @@ class SBAdminSite(admin.AdminSite):
49
49
  response
50
50
  )
51
51
 
52
- SBAdminThreadLocalService.clear_data()
53
52
  return response
54
53
 
55
54
  def admin_view(self, view_function, cacheable=False):
@@ -16,6 +16,7 @@ from filer.fields.image import AdminImageWidget
16
16
  from django_smartbase_admin.engine.filter_widgets import (
17
17
  AutocompleteFilterWidget,
18
18
  )
19
+ from django_smartbase_admin.services.thread_local import SBAdminThreadLocalService
19
20
  from django_smartbase_admin.templatetags.sb_admin_tags import SBAdminJSONEncoder
20
21
 
21
22
 
@@ -277,7 +278,6 @@ class SBAdminAutocompleteWidget(
277
278
  view = None
278
279
  form = None
279
280
  field_name = None
280
- threadsafe_request = None
281
281
  initialised = None
282
282
 
283
283
  def __init__(self, form_field=None, *args, **kwargs):
@@ -285,6 +285,12 @@ class SBAdminAutocompleteWidget(
285
285
  super().__init__(form_field, *args, **kwargs)
286
286
  self.attrs = {} if attrs is None else attrs.copy()
287
287
 
288
+ def get_id(self):
289
+ base_id = super().get_id()
290
+ if self.form:
291
+ base_id += f"_{self.form.__class__.__name__}"
292
+ return base_id
293
+
288
294
  def init_widget_dynamic(self, form, form_field, field_name, view, request):
289
295
  super().init_widget_dynamic(form, form_field, field_name, view, request)
290
296
  if self.initialised:
@@ -293,11 +299,10 @@ class SBAdminAutocompleteWidget(
293
299
  self.field_name = field_name
294
300
  self.view = view
295
301
  self.form = form
296
- self.threadsafe_request = request
297
302
  self.init_autocomplete_widget_static(
298
303
  self.field_name,
299
304
  self.model,
300
- self.threadsafe_request.request_data.configuration,
305
+ request.request_data.configuration,
301
306
  )
302
307
 
303
308
  def get_field_name(self):
@@ -315,20 +320,21 @@ class SBAdminAutocompleteWidget(
315
320
  getattr(self.form_field, "empty_label", "---------") or "---------"
316
321
  )
317
322
  query_suffix = "__in"
323
+ threadsafe_request = SBAdminThreadLocalService.get_request()
318
324
  if not self.is_multiselect():
319
325
  query_suffix = ""
320
326
  self.multiselect = False
321
327
  if value:
322
- parsed_value = self.parse_value_from_input(self.threadsafe_request, value)
328
+ parsed_value = self.parse_value_from_input(threadsafe_request, value)
323
329
  if parsed_value:
324
330
  selected_options = []
325
- for item in self.get_queryset(self.threadsafe_request).filter(
331
+ for item in self.get_queryset(threadsafe_request).filter(
326
332
  **{f"{self.get_value_field()}{query_suffix}": parsed_value}
327
333
  ):
328
334
  selected_options.append(
329
335
  {
330
- "value": self.get_value(self.threadsafe_request, item),
331
- "label": self.get_label(self.threadsafe_request, item),
336
+ "value": self.get_value(threadsafe_request, item),
337
+ "label": self.get_label(threadsafe_request, item),
332
338
  }
333
339
  )
334
340
  context["widget"]["value"] = json.dumps(selected_options)
@@ -343,7 +349,8 @@ class SBAdminAutocompleteWidget(
343
349
 
344
350
  def value_from_datadict(self, data, files, name):
345
351
  input_value = super().value_from_datadict(data, files, name)
346
- parsed_value = self.parse_value_from_input(self.threadsafe_request, input_value)
352
+ threadsafe_request = SBAdminThreadLocalService.get_request()
353
+ parsed_value = self.parse_value_from_input(threadsafe_request, input_value)
347
354
  if parsed_value is None:
348
355
  return parsed_value
349
356
  return parsed_value if self.is_multiselect() else next(iter(parsed_value), None)
@@ -24,12 +24,6 @@ class SBAdminCustomAction(object):
24
24
  group=None,
25
25
  ) -> None:
26
26
  super().__init__()
27
-
28
- if not (url or (view and action_id)):
29
- raise ImproperlyConfigured(
30
- "You must provide either url or view and action_id"
31
- )
32
-
33
27
  self.title = title
34
28
  self.url = url
35
29
  self.view = view
@@ -39,17 +33,27 @@ class SBAdminCustomAction(object):
39
33
  self.no_params = no_params
40
34
  self.open_in_modal = open_in_modal
41
35
  self.group = group
42
- if not url and not action_modifier:
36
+ self.resolve_url()
37
+
38
+ def resolve_url(self):
39
+ if not (self.url or (self.view and self.action_id)):
40
+ raise ImproperlyConfigured(
41
+ "You must provide either url or view and action_id"
42
+ )
43
+
44
+ if not self.url and not self.action_modifier:
43
45
  self.url = self.view.get_action_url(self.action_id)
44
- if not url and action_modifier is not None:
45
- self.url = self.view.get_action_url(self.action_id, action_modifier)
46
+ if not self.url and self.action_modifier is not None:
47
+ self.url = self.view.get_action_url(self.action_id, self.action_modifier)
46
48
 
47
49
 
48
- class SBAdminAction(object):
49
- view = None
50
- threadsafe_request = None
50
+ class SBAdminFormViewAction(SBAdminCustomAction):
51
+ def __init__(self, target_view, *args, **kwargs) -> None:
52
+ self.target_view = target_view
53
+ super().__init__(*args, **kwargs)
51
54
 
52
- def __init__(self, view, request) -> None:
53
- super().__init__()
54
- self.view = view
55
- self.threadsafe_request = request
55
+ def resolve_url(self):
56
+ """
57
+ self.url and self.action_id is resolved in side django_smartbase_admin.engine.admin_base_view.SBAdminBaseView.process_actions
58
+ """
59
+ pass
@@ -13,7 +13,10 @@ from django.urls import reverse
13
13
  from django.utils.translation import gettext_lazy as _
14
14
 
15
15
  from django_smartbase_admin.actions.admin_action_list import SBAdminListAction
16
- from django_smartbase_admin.engine.actions import SBAdminCustomAction
16
+ from django_smartbase_admin.engine.actions import (
17
+ SBAdminCustomAction,
18
+ SBAdminFormViewAction,
19
+ )
17
20
  from django_smartbase_admin.engine.const import (
18
21
  Action,
19
22
  OBJECT_ID_PLACEHOLDER,
@@ -28,6 +31,7 @@ from django_smartbase_admin.engine.const import (
28
31
  BASE_PARAMS_NAME,
29
32
  TABLE_RELOAD_DATA_EVENT_NAME,
30
33
  TABLE_UPDATE_ROW_DATA_EVENT_NAME,
34
+ FILTER_DATA_NAME,
31
35
  )
32
36
  from django_smartbase_admin.services.views import SBAdminViewService
33
37
  from django_smartbase_admin.services.xlsx_export import (
@@ -82,6 +86,27 @@ class SBAdminBaseView(object):
82
86
  request, obj
83
87
  )
84
88
 
89
+ def delegate_to_action_view(self, processed_action):
90
+ def inner_view(request, modifier):
91
+ return processed_action.target_view.as_view(view=self)(request)
92
+
93
+ return inner_view
94
+
95
+ def process_actions(self, request, actions):
96
+ processed_actions = self.process_actions_permissions(request, actions)
97
+ for processed_action in processed_actions:
98
+ if isinstance(processed_action, SBAdminFormViewAction):
99
+ action_id = processed_action.target_view.__name__
100
+ setattr(
101
+ self,
102
+ action_id,
103
+ self.delegate_to_action_view(processed_action),
104
+ )
105
+ processed_action.url = self.get_action_url(action_id)
106
+ processed_action.action_id = action_id
107
+
108
+ return processed_actions
109
+
85
110
  def process_actions_permissions(self, request, actions):
86
111
  result = []
87
112
  for action in actions:
@@ -211,6 +236,7 @@ class SBAdminBaseListView(SBAdminBaseView):
211
236
  sbadmin_list_reorder_field = None
212
237
  search_field_placeholder = _("Search...")
213
238
  filters_version = None
239
+ sbadmin_actions_initialized = False
214
240
  sbadmin_list_action_class = SBAdminListAction
215
241
 
216
242
  def activate_reorder(self, request):
@@ -297,11 +323,18 @@ class SBAdminBaseListView(SBAdminBaseView):
297
323
  messages.add_message(request, messages.ERROR, "Not Implemented")
298
324
  return HttpResponse(status=200, content=render_notifications(request))
299
325
 
326
+ def init_actions(self, request):
327
+ if self.sbadmin_actions_initialized:
328
+ return
329
+ self.process_actions(request, self.get_sbadmin_list_selection_actions())
330
+ self.sbadmin_actions_initialized = True
331
+
300
332
  def init_view_dynamic(self, request, request_data=None, **kwargs):
301
333
  super().init_view_dynamic(request, request_data, **kwargs)
302
334
  self.init_fields_cache(
303
335
  self.get_sbamin_list_display(request), request.request_data.configuration
304
336
  )
337
+ self.init_actions(request)
305
338
 
306
339
  def get_sbamin_list_display(self, request):
307
340
  return self.sbadmin_list_display or self.list_display
@@ -313,6 +346,11 @@ class SBAdminBaseListView(SBAdminBaseView):
313
346
  request.request_data.configuration,
314
347
  force=True,
315
348
  )
349
+ for list_action in self.get_sbadmin_list_selection_actions():
350
+ if isinstance(list_action, SBAdminFormViewAction):
351
+ form = list_action.target_view.form_class
352
+ form.view = self
353
+ form()
316
354
 
317
355
  def get_list_display(self, request):
318
356
  return [
@@ -453,7 +491,7 @@ class SBAdminBaseListView(SBAdminBaseView):
453
491
 
454
492
  def get_sbadmin_list_selection_actions_grouped(self, request):
455
493
  result = {}
456
- list_selection_actions = self.process_actions_permissions(
494
+ list_selection_actions = self.process_actions(
457
495
  request, self.get_sbadmin_list_selection_actions()
458
496
  )
459
497
  for action in list_selection_actions:
@@ -607,6 +645,7 @@ class SBAdminBaseListView(SBAdminBaseView):
607
645
  if not list_filter:
608
646
  return all_config
609
647
  list_fields = self.get_sbamin_list_display(request) or []
648
+ self.init_fields_cache(list_fields, request.request_data.configuration)
610
649
  base_filter = {
611
650
  getattr(field, "filter_field", field): ""
612
651
  for field in list_fields
@@ -632,12 +671,15 @@ class SBAdminBaseListView(SBAdminBaseView):
632
671
  list_view_config = [self.get_all_config(request), *sbadmin_list_config]
633
672
  views = []
634
673
  for defined_view in list_view_config:
674
+ url_params = SBAdminViewService.process_url_params(
675
+ view_id=self.get_id(),
676
+ url_params=defined_view["url_params"],
677
+ filter_version=self.get_filters_version(request),
678
+ )
635
679
  views.append(
636
680
  {
637
681
  "name": defined_view["name"],
638
- "url_params": SBAdminViewService.json_dumps_for_url(
639
- defined_view["url_params"]
640
- ),
682
+ "url_params": SBAdminViewService.json_dumps_for_url(url_params),
641
683
  "default": True,
642
684
  }
643
685
  )
@@ -83,6 +83,7 @@ class SBAdminField(JSONSerializableMixin):
83
83
  python_formatter = None
84
84
  tabulator_options = None
85
85
  xlsx_options = None
86
+ initialized = False
86
87
 
87
88
  def __init__(
88
89
  self,
@@ -121,6 +122,7 @@ class SBAdminField(JSONSerializableMixin):
121
122
  if (list_visible is not None)
122
123
  else (self.list_visible if self.list_visible is not None else True)
123
124
  )
125
+ self.list_visible_arg = list_visible
124
126
  self.list_collapsed = list_collapsed or self.list_collapsed or False
125
127
  self.auto_created = auto_created or self.auto_created or False
126
128
  self.formatter = formatter
@@ -203,7 +205,9 @@ class SBAdminField(JSONSerializableMixin):
203
205
  if self.model_field:
204
206
  self.editable = self.model_field.editable
205
207
  if self.model_field.is_relation:
206
- self.list_visible = False
208
+ self.list_visible = (
209
+ False if self.list_visible_arg is None else self.list_visible_arg
210
+ )
207
211
  if self.model_field.auto_created:
208
212
  self.detail_visible = False
209
213
  self.title = self.title or getattr(
@@ -225,6 +229,7 @@ class SBAdminField(JSONSerializableMixin):
225
229
  self.formatter = "html"
226
230
  self.filter_field = self.filter_field or self.field
227
231
  self.init_filter_for_field(configuration)
232
+ self.initialized = True
228
233
 
229
234
  def serialize_tabulator(self):
230
235
  data = {
@@ -28,11 +28,15 @@ class ActionModalView(FormView):
28
28
  def get_form_class(self):
29
29
  form_class = super().get_form_class()
30
30
 
31
- class Form(form_class):
32
- view = self.view
33
- threadsafe_request = self.request
31
+ fake_form_class = type(
32
+ form_class.__name__,
33
+ (form_class,),
34
+ {
35
+ "view": self.view,
36
+ },
37
+ )
34
38
 
35
- return Form
39
+ return fake_form_class
36
40
 
37
41
  def post(self, request, *args, **kwargs):
38
42
  form = self.get_form()
@@ -1,26 +1,13 @@
1
- from threading import local
1
+ from contextvars import ContextVar
2
2
 
3
- _thread_locals = local()
3
+ sb_admin_request = ContextVar("sb_admin_request")
4
4
 
5
5
 
6
6
  class SBAdminThreadLocalService:
7
- THREAD_DATA_KEY = "SB_ADMIN_DATA"
8
-
9
- @classmethod
10
- def get_wrapper(cls):
11
- return getattr(_thread_locals, cls.THREAD_DATA_KEY, {})
12
-
13
- @classmethod
14
- def get_data(cls, key):
15
- data_wrapper = cls.get_wrapper()
16
- return data_wrapper.get(key)
17
-
18
7
  @classmethod
19
- def set_data(cls, key, data):
20
- data_wrapper = cls.get_wrapper()
21
- data_wrapper[key] = data
8
+ def get_request(cls):
9
+ return sb_admin_request.get()
22
10
 
23
11
  @classmethod
24
- def clear_data(cls):
25
- if hasattr(_thread_locals, cls.THREAD_DATA_KEY):
26
- delattr(_thread_locals, cls.THREAD_DATA_KEY)
12
+ def set_request(cls, request):
13
+ sb_admin_request.set(request)
@@ -4,6 +4,7 @@ import urllib
4
4
 
5
5
  from django.db.models import Q, FilteredRelation, F, Value, CharField
6
6
  from django.shortcuts import redirect
7
+ from django_smartbase_admin.templatetags.sb_admin_tags import SBAdminJSONEncoder
7
8
 
8
9
  from django_smartbase_admin.engine.const import (
9
10
  BASE_PARAMS_NAME,
@@ -20,17 +21,52 @@ from django_smartbase_admin.services.translations import SBAdminTranslationsServ
20
21
  class SBAdminViewService(object):
21
22
  @classmethod
22
23
  def json_dumps_for_url(cls, data):
23
- return json.dumps(data, separators=(",", ":"))
24
+ return json.dumps(data, separators=(",", ":"), cls=SBAdminJSONEncoder)
24
25
 
25
26
  @classmethod
26
27
  def json_dumps_and_replace(cls, data):
27
- return cls.json_dumps_for_url(data).replace('"', '\\"')
28
+ return cls.json_dumps_for_url(data)
28
29
 
29
30
  @classmethod
30
31
  def build_list_url(cls, view_id, url_params):
31
32
  params = {view_id: url_params}
32
33
  return f"{BASE_PARAMS_NAME}={cls.json_dumps_for_url(params)}"
33
34
 
35
+ @classmethod
36
+ def process_url_params(cls, view_id, url_params, filter_version):
37
+ filter_data = SBAdminViewService.process_filter_data_url(
38
+ view_id=view_id,
39
+ filter_data=url_params.get(FILTER_DATA_NAME, {}),
40
+ filter_version=filter_version,
41
+ )
42
+ url_params_processed = {**url_params}
43
+ if filter_data:
44
+ url_params_processed[FILTER_DATA_NAME] = filter_data
45
+ return url_params_processed
46
+
47
+ @classmethod
48
+ def process_filter_data_url(cls, view_id, filter_data, filter_version):
49
+ if filter_version == FilterVersions.FILTERS_VERSION_2:
50
+ filter_data_processed = []
51
+ for key, value in filter_data.items():
52
+ filter_value = {
53
+ "id": f"{view_id}-{key}",
54
+ "field": key,
55
+ "type": "string",
56
+ "input": "text",
57
+ "operator": "contains",
58
+ }
59
+ filter_value.update(value)
60
+ filter_data_processed.append(filter_value)
61
+ return filter_data_processed
62
+ else:
63
+ filter_data_processed = {}
64
+ for filter_key, filter_value in filter_data.items():
65
+ filter_data_processed[filter_key] = cls.json_dumps_and_replace(
66
+ filter_value
67
+ )
68
+ return filter_data_processed
69
+
34
70
  @classmethod
35
71
  def build_list_params_url(cls, view_id, filter_data=None, filter_version=None):
36
72
  if filter_version == FilterVersions.FILTERS_VERSION_2:
@@ -44,24 +80,18 @@ class SBAdminViewService(object):
44
80
  TABLE_PARAMS_SELECTED_FILTER_TYPE: TABLE_TAB_ADVANCED_FITLERS
45
81
  },
46
82
  }
47
- for key, value in filter_data.items():
48
- filter_value = {
49
- "id": f"{view_id}-{key}",
50
- "field": key,
51
- "type": "string",
52
- "input": "text",
53
- "operator": "contains",
54
- }
55
- filter_value.update(value)
56
- filter_dict[ADVANCED_FILTER_DATA_NAME]["rules"].append(filter_value)
83
+ filter_dict[ADVANCED_FILTER_DATA_NAME]["rules"].extend(
84
+ cls.process_filter_data_url(view_id, filter_data, filter_version)
85
+ )
57
86
  params = {BASE_PARAMS_NAME: cls.json_dumps_for_url({view_id: filter_dict})}
58
87
  return urllib.parse.urlencode(params)
59
88
  filter_data = filter_data or {}
60
- filter_data_processed = {}
61
- for filter_key, filter_value in filter_data.items():
62
- filter_data_processed[filter_key] = cls.json_dumps_and_replace(filter_value)
63
- view_params = {FILTER_DATA_NAME: filter_data_processed}
64
- return cls.build_list_url(view_id, view_params).replace("\\\\", "")
89
+ view_params = {
90
+ FILTER_DATA_NAME: cls.process_filter_data_url(
91
+ view_id, filter_data, filter_version
92
+ )
93
+ }
94
+ return cls.build_list_url(view_id, view_params)
65
95
 
66
96
  @classmethod
67
97
  def get_pk_field_for_model(cls, model):
@@ -75,7 +75,7 @@
75
75
  }
76
76
 
77
77
  #sortable-items {
78
- height: calc(100vh - 365px);
78
+ height: calc(100vh - 198px);
79
79
  overflow: auto;
80
80
  }
81
81
 
@@ -398,4 +398,4 @@
398
398
 
399
399
  mainSorting()
400
400
  </script>
401
- {% endblock %}
401
+ {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-smartbase-admin
3
- Version: 0.2.73
3
+ Version: 0.2.74
4
4
  Summary:
5
5
  Author: SmartBase
6
6
  Author-email: info@smartbase.sk
@@ -1,28 +1,28 @@
1
1
  django_smartbase_admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  django_smartbase_admin/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- django_smartbase_admin/actions/admin_action_list.py,sha256=qQ1pQt27TP4vapwNmuQMum8xYBdCnTwz__uIQa11E2U,19074
3
+ django_smartbase_admin/actions/admin_action_list.py,sha256=EWk0KTXDVVJDT8bh052xazukTpYFFOzrKTp36m1QNzE,19229
4
4
  django_smartbase_admin/actions/advanced_filters.py,sha256=Vm8b6TAwNehR8INjolFG7pEYL4ADO7XUiVOWpb0btM0,13481
5
5
  django_smartbase_admin/admin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- django_smartbase_admin/admin/admin_base.py,sha256=cr8Ir_iD1RoejIKlvxXsjqM0d0gllxxKR23OcKNlEwM,39920
7
- django_smartbase_admin/admin/site.py,sha256=ux0aPoI8DtLbzwXG1UzxYVo17QMhaWUoJYqMM6e7-as,6632
8
- django_smartbase_admin/admin/widgets.py,sha256=QkNgqOuNIOrYe7q2DocYYOJ3R19bQWZjYc1qgw9tLsw,14766
6
+ django_smartbase_admin/admin/admin_base.py,sha256=9fN3c41fNkav7uQiGfEnJaiqYKfDk57VrlYgiN04DE8,40100
7
+ django_smartbase_admin/admin/site.py,sha256=VrJBhwgZsLa2GohvjnNL7m4dVR3S4Ou1V1UzfE1qOoQ,6577
8
+ django_smartbase_admin/admin/widgets.py,sha256=udNG3fqDSTKnbPpvY02qhanPoCm_Kgn7Bg8R3EjWJT4,15035
9
9
  django_smartbase_admin/apps.py,sha256=3Wm88v1u-ejKVSRsdgsnOrjOfdlsp1qVULskabgH1iY,479
10
10
  django_smartbase_admin/compilemessages.py,sha256=-_FEFQlOvE4L8UzSuUxSxZQjgGlwL9IZtmg59fW_kIQ,342
11
11
  django_smartbase_admin/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- django_smartbase_admin/engine/actions.py,sha256=WMmXXeBOwU0-IZ6F9mn79EW6ZCNT2sadUyIz--g8APY,1464
13
- django_smartbase_admin/engine/admin_base_view.py,sha256=-L1CL2rKuTIENduBV7SvTTuaqvkCVco6nugMTqiUoJ8,26775
12
+ django_smartbase_admin/engine/actions.py,sha256=n8PiG60Kj1ECHB4lfVH_jvHMyOjOZ-DvQfO9F2CuqW0,1733
13
+ django_smartbase_admin/engine/admin_base_view.py,sha256=ni1UV_nc_oeccRhKi9nyy520QB18nhZnmmcdaAIE6Hs,28475
14
14
  django_smartbase_admin/engine/admin_entrypoint_view.py,sha256=jfMfcYPfdre2abHfC4KIxaP_epJFuCeTcujGhGd4Tl4,624
15
15
  django_smartbase_admin/engine/admin_view.py,sha256=9wGffahDR3IYmhL9ZbX8uitwGdXdw5DIL5GnWBawmJM,4238
16
16
  django_smartbase_admin/engine/configuration.py,sha256=P3iSiPm9QBl9etTDJIWzo7DzOBCryGwWtbF288PEtus,8120
17
17
  django_smartbase_admin/engine/const.py,sha256=vU_XMy76BYiw1tu88lw8UDGk-cW5oo62gh9mT36_2tk,2437
18
18
  django_smartbase_admin/engine/dashboard.py,sha256=wrvX0GI-SII2pG0DX8Kvy4JFaM6h8e6R7KSCFddFC64,23642
19
19
  django_smartbase_admin/engine/fake_inline.py,sha256=9C2_mltg2P9-xa3vuoo5X_RcFaCRpKGNSy7t1_iiasE,5802
20
- django_smartbase_admin/engine/field.py,sha256=Cx_tyqrGT96EqLCRmaG82SGv5PR0KoX7maoVw2PtS3M,10085
20
+ django_smartbase_admin/engine/field.py,sha256=BD_W0ekE5tQJxUGpUA8bo4ZyFk0u2F_6UTPH4drj0JU,10286
21
21
  django_smartbase_admin/engine/field_formatter.py,sha256=GzyvcBr8Cru34yMedd1GYOl2jTTopEGeSEhoM9_CfKQ,1754
22
22
  django_smartbase_admin/engine/filter_widgets.py,sha256=lHPMilA2tjtwnwqPw2nUE39BL1Dx_v4HNKhmg6szHUY,23687
23
23
  django_smartbase_admin/engine/global_filter_form.py,sha256=jlj6e9VYWDPyUNjcgj3gTIkCZXO01NZOWAeU3jFtkoA,249
24
24
  django_smartbase_admin/engine/menu_item.py,sha256=rMJFG5xm1T0wF8lUmiAZHzKtt9C0LdbpRFvaP0PlngM,2936
25
- django_smartbase_admin/engine/modal_view.py,sha256=M9jnh9wHenlOMFHhG42L3olGFO7EJezw5Nld0kjO4GQ,2181
25
+ django_smartbase_admin/engine/modal_view.py,sha256=6eAmncDV9UzTWemWFQXZpVCIixWo5gWvNZGnK4mw4FM,2251
26
26
  django_smartbase_admin/engine/request.py,sha256=sFjxgmzGXUeCD3hEx-Eu-ebgF8CnrBJDH2e8LF1ieRg,2615
27
27
  django_smartbase_admin/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  django_smartbase_admin/integration/django_cms.py,sha256=asLVmQUDHulGEpkqp5cUv6-aTcZPoeOllPE1_AIWUqM,1062
@@ -40,9 +40,9 @@ django_smartbase_admin/querysets.py,sha256=ST_6qxznqxJiv8Gk1bgYVMpK_gbU74ItKyvMm
40
40
  django_smartbase_admin/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  django_smartbase_admin/services/configuration.py,sha256=POMI0htBqFS9ptPXMtOhIlIKiF6Y4cOQ-IkYN6NWO1c,759
42
42
  django_smartbase_admin/services/data.py,sha256=o36B_H9RnBvaQz3Rs3NygY1hVTr6hc89M-RK1saRXzc,156
43
- django_smartbase_admin/services/thread_local.py,sha256=bupVV7cfCsn86ANCa2yhCeOg9XJmjFwBrxLt2KJDiKQ,642
43
+ django_smartbase_admin/services/thread_local.py,sha256=C3x7hPsKRCddr05RGiN0f6fcSQ8qsrYRdx9oeMHRovU,293
44
44
  django_smartbase_admin/services/translations.py,sha256=aiekREx8KQA9CQRmtkUcys4ICJERMrkxPnLysp0YXO8,5606
45
- django_smartbase_admin/services/views.py,sha256=arwWAOYeJXG3ZT834nqOo4HuezDaLs-elhl4FOiLli8,7847
45
+ django_smartbase_admin/services/views.py,sha256=oTZXHvZl-eGCaHRoQiEG-YLKAGGs3FcuVDZhdiuuv34,8953
46
46
  django_smartbase_admin/services/xlsx_export.py,sha256=fnIqahmZR6G5T5wSH-sXhhLSy1QD3A-OY6BAn1WLLOc,10723
47
47
  django_smartbase_admin/static/sb_admin/build/postcss.config.js,sha256=JlIB66vejH4YA3sPp7hDjimQXAGz5WlVhFDwjBDNTEo,610
48
48
  django_smartbase_admin/static/sb_admin/build/tailwind.config.js,sha256=5q5CGlXyn5s3hB6k2OCTu4auVcY4_yop5TrM5g0pT80,2369
@@ -593,7 +593,7 @@ django_smartbase_admin/templates/sb_admin/integrations/cms/translations_status_r
593
593
  django_smartbase_admin/templates/sb_admin/integrations/filer/filer_change_form.html,sha256=ts8H3F-0VVhxuJfgmPiMo5rGwub5pLzhUx513kw_zVE,3002
594
594
  django_smartbase_admin/templates/sb_admin/integrations/filer/folder_list.html,sha256=Z5dZRNprEslkBDwYE3u8brVNt9qOhLX1gYG8wWjVGk8,18834
595
595
  django_smartbase_admin/templates/sb_admin/integrations/filer/image_change_form.html,sha256=CESQuiGfbKdMEq9DRIXfOS-jpz8yr64TJ7R_cs6jZ9M,1909
596
- django_smartbase_admin/templates/sb_admin/integrations/sorting/change_list.html,sha256=wbXljeA0dZMkm_ZiKdIkVv5QQFJJD2JTCkeiRbANhIA,15189
596
+ django_smartbase_admin/templates/sb_admin/integrations/sorting/change_list.html,sha256=2TSTiKZ52Gpp_Jf5EHr4BEUxnxVXdEY9jEHrtn2f5Xc,15190
597
597
  django_smartbase_admin/templates/sb_admin/navigation.html,sha256=jU7aeGihp_oxhGHjVo_j5j7g03z-EPzYPk9PHt5NSFE,10613
598
598
  django_smartbase_admin/templates/sb_admin/partials/messages/alert_base.html,sha256=F61XeaBMR7YL9wx0VDXdJ9uTlBMNGSMsXmk6IHZuuNk,825
599
599
  django_smartbase_admin/templates/sb_admin/partials/messages/alert_close.html,sha256=-BhLje6G4Ey36hOseZ41WxjmdsMeCOza_2okBn0EWiM,121
@@ -658,7 +658,7 @@ django_smartbase_admin/views/dashboard_view.py,sha256=vtz5emYTQ5WDFeLA8HrcmjSOVd
658
658
  django_smartbase_admin/views/global_filter_view.py,sha256=eYo1moJGyi7jc2cPDA5ZBiEgA7Hmc-DxbQvbqUpDkg8,1127
659
659
  django_smartbase_admin/views/media_view.py,sha256=5BLWXuzynF7nM34t-mf2BQSRN5ojY8HxpLIqt7Jiq9g,292
660
660
  django_smartbase_admin/views/translations_view.py,sha256=A02q1t13akLKd2Pg_ej4tVi5qPUKYxB2LqsBbYXM0l8,20267
661
- django_smartbase_admin-0.2.73.dist-info/LICENSE.md,sha256=okRGMBOYvyhprt2eTpX_QXqpzC0MODF-U7zX-4fKPjQ,1078
662
- django_smartbase_admin-0.2.73.dist-info/METADATA,sha256=DyMvq20P0HULmg6fxT_SY4dNEGRR-eDXithHLzM7PpQ,945
663
- django_smartbase_admin-0.2.73.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
664
- django_smartbase_admin-0.2.73.dist-info/RECORD,,
661
+ django_smartbase_admin-0.2.74.dist-info/LICENSE.md,sha256=okRGMBOYvyhprt2eTpX_QXqpzC0MODF-U7zX-4fKPjQ,1078
662
+ django_smartbase_admin-0.2.74.dist-info/METADATA,sha256=iqrHWxzbyeBME7JNoGboxqWBnJX5U7EyyMCWhQ36bbk,945
663
+ django_smartbase_admin-0.2.74.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
664
+ django_smartbase_admin-0.2.74.dist-info/RECORD,,