django-smartbase-admin 0.2.72__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
@@ -62,6 +63,16 @@ try:
62
63
  except ImportError:
63
64
  pass
64
65
 
66
+
67
+ django_cms_attributes = None
68
+ try:
69
+ from djangocms_attributes_field.fields import AttributesFormField
70
+
71
+ django_cms_attributes = True
72
+ except ImportError:
73
+ pass
74
+
75
+
65
76
  from django_smartbase_admin.admin.widgets import (
66
77
  SBAdminTextInputWidget,
67
78
  SBAdminTextareaWidget,
@@ -83,6 +94,8 @@ from django_smartbase_admin.admin.widgets import (
83
94
  SBAdminReadOnlyPasswordHashWidget,
84
95
  SBAdminHiddenWidget,
85
96
  SBAdminCKEditorUploadingWidget,
97
+ SBAdminAttributesWidget,
98
+ SBAdminMultipleChoiceInlineWidget,
86
99
  )
87
100
  from django_smartbase_admin.engine.admin_base_view import (
88
101
  SBAdminBaseListView,
@@ -121,6 +134,8 @@ class SBAdminFormFieldWidgetsMixin:
121
134
  RichTextUploadingFormField: SBAdminCKEditorUploadingWidget,
122
135
  forms.ChoiceField: SBAdminSelectWidget,
123
136
  forms.TypedChoiceField: SBAdminSelectWidget,
137
+ forms.MultipleChoiceField: SBAdminMultipleChoiceInlineWidget,
138
+ forms.TypedMultipleChoiceField: SBAdminMultipleChoiceInlineWidget,
124
139
  forms.NullBooleanField: SBAdminNullBooleanSelectWidget,
125
140
  AdminImageFormField: SBAdminImageWidget,
126
141
  ReadOnlyPasswordHashWidget: SBAdminReadOnlyPasswordHashWidget,
@@ -128,6 +143,8 @@ class SBAdminFormFieldWidgetsMixin:
128
143
  }
129
144
  if postrgres_enabled:
130
145
  formfield_widgets[SimpleArrayField] = SBAdminArrayWidget
146
+ if django_cms_attributes:
147
+ formfield_widgets[AttributesFormField] = SBAdminAttributesWidget
131
148
 
132
149
  django_widget_to_widget = {
133
150
  forms.PasswordInput: SBAdminPasswordInputWidget,
@@ -250,12 +267,13 @@ class SBAdminFormFieldWidgetsMixin:
250
267
 
251
268
 
252
269
  class SBAdminBaseFormInit(SBAdminFormFieldWidgetsMixin, FormFieldsetMixin):
253
- threadsafe_request = None
254
270
  view = None
255
271
 
256
272
  def __init__(self, *args, **kwargs):
257
273
  self.view = kwargs.pop("view", self.view)
258
- self.threadsafe_request = kwargs.pop("request", self.threadsafe_request)
274
+ threadsafe_request = kwargs.pop(
275
+ "request", SBAdminThreadLocalService.get_request()
276
+ )
259
277
  super().__init__(*args, **kwargs)
260
278
  for field in self.fields:
261
279
  if not hasattr(self.fields[field].widget, "init_widget_dynamic"):
@@ -265,14 +283,12 @@ class SBAdminBaseFormInit(SBAdminFormFieldWidgetsMixin, FormFieldsetMixin):
265
283
  self.fields[field],
266
284
  field,
267
285
  self.view,
268
- self.threadsafe_request,
286
+ threadsafe_request,
269
287
  )
270
288
  for field in self.declared_fields:
271
289
  form_field = self.fields.get(field)
272
290
  if form_field:
273
- self.assign_widget_to_form_field(
274
- form_field, request=self.threadsafe_request
275
- )
291
+ self.assign_widget_to_form_field(form_field, request=threadsafe_request)
276
292
 
277
293
 
278
294
  class SBAdminBaseForm(SBAdminBaseFormInit, forms.ModelForm):
@@ -472,11 +488,6 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
472
488
  if form:
473
489
  form.view = self
474
490
 
475
- def initialize_form_class_threadsafe(self, form, request):
476
- self.initialize_form_class(form)
477
- if form:
478
- form.threadsafe_request = request
479
-
480
491
 
481
492
  class SBAdminThirdParty(SBAdminInlineAndAdminCommon, SBAdminBaseView):
482
493
  def get_menu_view_url(self, request):
@@ -630,7 +641,7 @@ class SBAdmin(
630
641
 
631
642
  def get_form(self, request, obj=None, **kwargs):
632
643
  form = super().get_form(request, obj, **kwargs)
633
- self.initialize_form_class_threadsafe(form, request)
644
+ self.initialize_form_class(form)
634
645
  return form
635
646
 
636
647
  def get_id(self):
@@ -692,7 +703,11 @@ class SBAdmin(
692
703
  all_config = self.get_all_config(request)
693
704
  url_suffix = ""
694
705
  if all_config and all_config.get("all_params_changed", False):
695
- 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
+ )
696
711
  if url_params_dict:
697
712
  url_suffix = f"?{SBAdminViewService.build_list_url(self.get_id(), url_params_dict)}"
698
713
 
@@ -899,7 +914,7 @@ class SBAdminInline(
899
914
  def register_autocomplete_views(self, request):
900
915
  super().register_autocomplete_views(request)
901
916
  form_class = self.get_formset(request, self.model()).form
902
- self.initialize_form_class_threadsafe(form_class, request)
917
+ self.initialize_form_class(form_class)
903
918
  form_class()
904
919
 
905
920
  @property
@@ -943,7 +958,7 @@ class SBAdminInline(
943
958
  def get_formset(self, request, obj=None, **kwargs):
944
959
  formset = super().get_formset(request, obj, **kwargs)
945
960
  form_class = formset.form
946
- self.initialize_form_class_threadsafe(form_class, request)
961
+ self.initialize_form_class(form_class)
947
962
  return formset
948
963
 
949
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
 
@@ -249,6 +250,27 @@ class SBAdminArrayWidget(SBAdminTextInputWidget):
249
250
  return context
250
251
 
251
252
 
253
+ class SBAdminAttributesWidget(SBAdminTextInputWidget):
254
+ template_name = "sb_admin/widgets/attributes.html"
255
+
256
+ def get_context(self, name, value, attrs):
257
+ context = super().get_context(name, value, attrs)
258
+ widget = context.get("widget", None)
259
+ dict_widgets = []
260
+ template_widget = {"attrs": {"class": "input"}}
261
+ if widget and value:
262
+ dict_widgets = [
263
+ {
264
+ "key": {"value": key, **template_widget},
265
+ "value": {"value": value, **template_widget},
266
+ }
267
+ for key, value in value.items()
268
+ ]
269
+ context["dict_widgets"] = dict_widgets
270
+ context["template_widget"] = template_widget
271
+ return context
272
+
273
+
252
274
  class SBAdminAutocompleteWidget(
253
275
  SBAdminBaseWidget, AutocompleteFilterWidget, forms.Widget
254
276
  ):
@@ -256,7 +278,6 @@ class SBAdminAutocompleteWidget(
256
278
  view = None
257
279
  form = None
258
280
  field_name = None
259
- threadsafe_request = None
260
281
  initialised = None
261
282
 
262
283
  def __init__(self, form_field=None, *args, **kwargs):
@@ -264,6 +285,12 @@ class SBAdminAutocompleteWidget(
264
285
  super().__init__(form_field, *args, **kwargs)
265
286
  self.attrs = {} if attrs is None else attrs.copy()
266
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
+
267
294
  def init_widget_dynamic(self, form, form_field, field_name, view, request):
268
295
  super().init_widget_dynamic(form, form_field, field_name, view, request)
269
296
  if self.initialised:
@@ -272,11 +299,10 @@ class SBAdminAutocompleteWidget(
272
299
  self.field_name = field_name
273
300
  self.view = view
274
301
  self.form = form
275
- self.threadsafe_request = request
276
302
  self.init_autocomplete_widget_static(
277
303
  self.field_name,
278
304
  self.model,
279
- self.threadsafe_request.request_data.configuration,
305
+ request.request_data.configuration,
280
306
  )
281
307
 
282
308
  def get_field_name(self):
@@ -294,20 +320,21 @@ class SBAdminAutocompleteWidget(
294
320
  getattr(self.form_field, "empty_label", "---------") or "---------"
295
321
  )
296
322
  query_suffix = "__in"
323
+ threadsafe_request = SBAdminThreadLocalService.get_request()
297
324
  if not self.is_multiselect():
298
325
  query_suffix = ""
299
326
  self.multiselect = False
300
327
  if value:
301
- parsed_value = self.parse_value_from_input(self.threadsafe_request, value)
328
+ parsed_value = self.parse_value_from_input(threadsafe_request, value)
302
329
  if parsed_value:
303
330
  selected_options = []
304
- for item in self.get_queryset(self.threadsafe_request).filter(
331
+ for item in self.get_queryset(threadsafe_request).filter(
305
332
  **{f"{self.get_value_field()}{query_suffix}": parsed_value}
306
333
  ):
307
334
  selected_options.append(
308
335
  {
309
- "value": self.get_value(self.threadsafe_request, item),
310
- "label": self.get_label(self.threadsafe_request, item),
336
+ "value": self.get_value(threadsafe_request, item),
337
+ "label": self.get_label(threadsafe_request, item),
311
338
  }
312
339
  )
313
340
  context["widget"]["value"] = json.dumps(selected_options)
@@ -322,7 +349,8 @@ class SBAdminAutocompleteWidget(
322
349
 
323
350
  def value_from_datadict(self, data, files, name):
324
351
  input_value = super().value_from_datadict(data, files, name)
325
- 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)
326
354
  if parsed_value is None:
327
355
  return parsed_value
328
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):