django-smartbase-admin 0.2.84__py3-none-any.whl → 0.2.86__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 +9 -5
- django_smartbase_admin/admin/admin_base.py +50 -41
- django_smartbase_admin/admin/widgets.py +2 -0
- django_smartbase_admin/engine/admin_base_view.py +71 -59
- django_smartbase_admin/static/sb_admin/dist/main_style.css +1 -1
- django_smartbase_admin/static/sb_admin/src/css/_inlines.css +11 -7
- django_smartbase_admin/templates/sb_admin/inlines/stacked_inline.html +19 -13
- {django_smartbase_admin-0.2.84.dist-info → django_smartbase_admin-0.2.86.dist-info}/METADATA +1 -1
- {django_smartbase_admin-0.2.84.dist-info → django_smartbase_admin-0.2.86.dist-info}/RECORD +11 -11
- {django_smartbase_admin-0.2.84.dist-info → django_smartbase_admin-0.2.86.dist-info}/LICENSE.md +0 -0
- {django_smartbase_admin-0.2.84.dist-info → django_smartbase_admin-0.2.86.dist-info}/WHEEL +0 -0
|
@@ -92,7 +92,7 @@ class SBAdminListAction(SBAdminAction):
|
|
|
92
92
|
)
|
|
93
93
|
self.deselected_rows = self.selection_data.get(DESELECTED_ROWS_KWARG_NAME, [])
|
|
94
94
|
self.page_size = page_size or self.table_params.get(
|
|
95
|
-
TABLE_PARAMS_SIZE_NAME, self.view.get_list_per_page()
|
|
95
|
+
TABLE_PARAMS_SIZE_NAME, self.view.get_list_per_page(request)
|
|
96
96
|
)
|
|
97
97
|
self.init_column_fields()
|
|
98
98
|
self.tabulator_definition = tabulator_definition
|
|
@@ -205,16 +205,18 @@ class SBAdminListAction(SBAdminAction):
|
|
|
205
205
|
self.threadsafe_request
|
|
206
206
|
),
|
|
207
207
|
"search_fields": self.view.get_search_fields(self.threadsafe_request),
|
|
208
|
-
"search_field_placeholder": self.view.get_search_field_placeholder(
|
|
208
|
+
"search_field_placeholder": self.view.get_search_field_placeholder(
|
|
209
|
+
self.threadsafe_request
|
|
210
|
+
),
|
|
209
211
|
"list_actions": self.view.process_actions_permissions(
|
|
210
212
|
self.threadsafe_request, list_actions
|
|
211
213
|
),
|
|
212
214
|
"list_selection_actions": self.view.get_sbadmin_list_selection_actions_grouped(
|
|
213
215
|
self.threadsafe_request
|
|
214
216
|
),
|
|
215
|
-
"config_url": self.view.get_config_url(),
|
|
217
|
+
"config_url": self.view.get_config_url(self.threadsafe_request),
|
|
216
218
|
"new_url": (
|
|
217
|
-
self.view.get_new_url()
|
|
219
|
+
self.view.get_new_url(self.threadsafe_request)
|
|
218
220
|
if self.view.has_add_permission(self.threadsafe_request)
|
|
219
221
|
else None
|
|
220
222
|
),
|
|
@@ -228,7 +230,9 @@ class SBAdminListAction(SBAdminAction):
|
|
|
228
230
|
for sort in self.table_params.get("sort", []):
|
|
229
231
|
order_by.append(f"{'-' if sort['dir'] == 'desc' else ''}{sort['field']}")
|
|
230
232
|
if len(order_by) == 0:
|
|
231
|
-
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
|
+
]
|
|
232
236
|
return order_by
|
|
233
237
|
|
|
234
238
|
def get_order_by_fields_from_request(self):
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import urllib.parse
|
|
3
|
+
from collections.abc import Iterable
|
|
3
4
|
from functools import partial
|
|
5
|
+
from typing import Any
|
|
4
6
|
|
|
5
7
|
from ckeditor.fields import RichTextFormField
|
|
6
8
|
from ckeditor_uploader.fields import RichTextUploadingFormField
|
|
@@ -16,6 +18,7 @@ from django.core.exceptions import (
|
|
|
16
18
|
PermissionDenied,
|
|
17
19
|
)
|
|
18
20
|
from django.db import models
|
|
21
|
+
from django.db.models import QuerySet
|
|
19
22
|
from django.forms import HiddenInput
|
|
20
23
|
from django.forms.models import (
|
|
21
24
|
ModelFormMetaclass,
|
|
@@ -24,7 +27,7 @@ from django.forms.models import (
|
|
|
24
27
|
from django.template.loader import render_to_string
|
|
25
28
|
from django.template.response import TemplateResponse
|
|
26
29
|
from django.urls import reverse
|
|
27
|
-
from django.utils.safestring import mark_safe
|
|
30
|
+
from django.utils.safestring import mark_safe, SafeString
|
|
28
31
|
from django.utils.text import capfirst
|
|
29
32
|
from django.utils.translation import gettext_lazy as _
|
|
30
33
|
from django_admin_inline_paginator.admin import TabularInlinePaginated
|
|
@@ -470,10 +473,10 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
|
470
473
|
configuration, inline_view_instance.model, admin_site
|
|
471
474
|
)
|
|
472
475
|
|
|
473
|
-
def get_sbadmin_fake_inlines(self, request, obj):
|
|
476
|
+
def get_sbadmin_fake_inlines(self, request, obj) -> Iterable:
|
|
474
477
|
return self.sbadmin_fake_inlines or []
|
|
475
478
|
|
|
476
|
-
def get_inline_instances(self, request, obj=None):
|
|
479
|
+
def get_inline_instances(self, request, obj=None) -> list:
|
|
477
480
|
inline_classes = self.get_inlines(request, obj)
|
|
478
481
|
inline_classes = [*inline_classes] or []
|
|
479
482
|
inline_classes.extend(self.get_sbadmin_fake_inlines(request, obj))
|
|
@@ -492,7 +495,7 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
|
492
495
|
inlines.append(inline)
|
|
493
496
|
return inlines
|
|
494
497
|
|
|
495
|
-
def init_view_dynamic(self, request, request_data=None, **kwargs):
|
|
498
|
+
def init_view_dynamic(self, request, request_data=None, **kwargs) -> None:
|
|
496
499
|
if SBAdminTranslationsService.is_translated_model(self.model):
|
|
497
500
|
has_default_form = (
|
|
498
501
|
self.form == TranslatableModelForm or self.form == forms.ModelForm
|
|
@@ -504,13 +507,13 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
|
504
507
|
f"Admin '{self}' form class '{self.form}' needs to extend SBTranslatableModelForm in case of translatable model."
|
|
505
508
|
)
|
|
506
509
|
super().init_view_dynamic(request, request_data, **kwargs)
|
|
507
|
-
self.initialize_form_class(self.form)
|
|
510
|
+
self.initialize_form_class(self.form, request)
|
|
508
511
|
|
|
509
|
-
def initialize_form_class(self, form):
|
|
512
|
+
def initialize_form_class(self, form, request) -> None:
|
|
510
513
|
if form:
|
|
511
514
|
form.view = self
|
|
512
515
|
|
|
513
|
-
def initialize_all_base_fields_form(self, request):
|
|
516
|
+
def initialize_all_base_fields_form(self, request) -> None:
|
|
514
517
|
params = {
|
|
515
518
|
"form": self.form,
|
|
516
519
|
"fields": "__all__",
|
|
@@ -520,10 +523,10 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
|
520
523
|
|
|
521
524
|
|
|
522
525
|
class SBAdminThirdParty(SBAdminInlineAndAdminCommon, SBAdminBaseView):
|
|
523
|
-
def get_menu_view_url(self, request):
|
|
526
|
+
def get_menu_view_url(self, request) -> str:
|
|
524
527
|
return reverse(f"sb_admin:{self.get_id()}_changelist")
|
|
525
528
|
|
|
526
|
-
def get_id(self):
|
|
529
|
+
def get_id(self) -> str:
|
|
527
530
|
return self.get_model_path()
|
|
528
531
|
|
|
529
532
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
@@ -536,7 +539,7 @@ class SBAdminThirdParty(SBAdminInlineAndAdminCommon, SBAdminBaseView):
|
|
|
536
539
|
extra_context.update(self.get_global_context(request))
|
|
537
540
|
return super().changelist_view(request, extra_context)
|
|
538
541
|
|
|
539
|
-
def get_action_url(self, action, modifier="template"):
|
|
542
|
+
def get_action_url(self, action, modifier="template") -> str:
|
|
540
543
|
return reverse(
|
|
541
544
|
"sb_admin:sb_admin_base",
|
|
542
545
|
kwargs={
|
|
@@ -555,7 +558,7 @@ class SBAdminTranslationStatusMixin:
|
|
|
555
558
|
main_language_code,
|
|
556
559
|
current_lang_code,
|
|
557
560
|
translations_edit_url,
|
|
558
|
-
):
|
|
561
|
+
) -> dict[str, Any]:
|
|
559
562
|
language_code = language[0]
|
|
560
563
|
language_title = language[1]
|
|
561
564
|
this_lang_count = languages_count.get(language_code, 0)
|
|
@@ -591,11 +594,11 @@ class SBAdminTranslationStatusMixin:
|
|
|
591
594
|
}
|
|
592
595
|
|
|
593
596
|
@classmethod
|
|
594
|
-
def get_empty_state(cls):
|
|
597
|
+
def get_empty_state(cls) -> SafeString:
|
|
595
598
|
return mark_safe("<div class='is-empty'></div>")
|
|
596
599
|
|
|
597
600
|
@admin.display(description="")
|
|
598
|
-
def sbadmin_translation_status(self, obj):
|
|
601
|
+
def sbadmin_translation_status(self, obj) -> SafeString:
|
|
599
602
|
if not SBAdminTranslationsService.is_i18n_enabled():
|
|
600
603
|
return self.get_empty_state()
|
|
601
604
|
|
|
@@ -666,19 +669,21 @@ class SBAdmin(
|
|
|
666
669
|
formset.inline_instance.parent_instance = form.instance
|
|
667
670
|
super().save_formset(request, form, formset, change)
|
|
668
671
|
|
|
669
|
-
def get_sbadmin_list_filter(self, request):
|
|
672
|
+
def get_sbadmin_list_filter(self, request) -> Iterable:
|
|
670
673
|
return self.sbadmin_list_filter or self.get_list_filter(request)
|
|
671
674
|
|
|
672
675
|
def get_form(self, request, obj=None, **kwargs):
|
|
673
676
|
self.initialize_all_base_fields_form(request)
|
|
674
677
|
form = super().get_form(request, obj, **kwargs)
|
|
675
|
-
self.initialize_form_class(form)
|
|
678
|
+
self.initialize_form_class(form, request)
|
|
676
679
|
return form
|
|
677
680
|
|
|
678
|
-
def get_id(self):
|
|
681
|
+
def get_id(self) -> str:
|
|
679
682
|
return self.get_model_path()
|
|
680
683
|
|
|
681
|
-
def get_sbadmin_fieldsets(
|
|
684
|
+
def get_sbadmin_fieldsets(
|
|
685
|
+
self, request, object_id=None
|
|
686
|
+
) -> Iterable[tuple[str | None, dict[str, Any]]]:
|
|
682
687
|
fieldsets = self.sbadmin_fieldsets or self.fieldsets
|
|
683
688
|
if fieldsets:
|
|
684
689
|
return fieldsets
|
|
@@ -690,7 +695,9 @@ class SBAdmin(
|
|
|
690
695
|
super().register_autocomplete_views(request)
|
|
691
696
|
self.get_form(request)()
|
|
692
697
|
|
|
693
|
-
def get_fieldsets(
|
|
698
|
+
def get_fieldsets(
|
|
699
|
+
self, request, obj=None
|
|
700
|
+
) -> list[tuple[str | None, dict[str, Any]]]:
|
|
694
701
|
fieldsets = []
|
|
695
702
|
object_id = obj.id if obj else None
|
|
696
703
|
for fieldset in self.get_sbadmin_fieldsets(request, object_id):
|
|
@@ -705,7 +712,9 @@ class SBAdmin(
|
|
|
705
712
|
fieldsets.append(fieldset_django)
|
|
706
713
|
return fieldsets
|
|
707
714
|
|
|
708
|
-
def get_fieldsets_context(
|
|
715
|
+
def get_fieldsets_context(
|
|
716
|
+
self, request, object_id
|
|
717
|
+
) -> dict[str, dict[str | None, dict[str, Any]]]:
|
|
709
718
|
fielsets_context = {}
|
|
710
719
|
for fieldset in self.get_sbadmin_fieldsets(request, object_id):
|
|
711
720
|
actions = fieldset[1].get("actions", [])
|
|
@@ -719,18 +728,18 @@ class SBAdmin(
|
|
|
719
728
|
fielsets_context[fieldset[0]] = fieldset[1]
|
|
720
729
|
return {"fieldsets_context": fielsets_context}
|
|
721
730
|
|
|
722
|
-
def get_sbadmin_tabs(self, request, object_id):
|
|
731
|
+
def get_sbadmin_tabs(self, request, object_id) -> Iterable:
|
|
723
732
|
return self.sbadmin_tabs
|
|
724
733
|
|
|
725
|
-
def get_tabs_context(self, request, object_id):
|
|
734
|
+
def get_tabs_context(self, request, object_id) -> dict[str, Iterable]:
|
|
726
735
|
return {"tabs_context": self.get_sbadmin_tabs(request, object_id)}
|
|
727
736
|
|
|
728
|
-
def get_context_data(self, request):
|
|
737
|
+
def get_context_data(self, request) -> dict[str, Any]:
|
|
729
738
|
return {
|
|
730
739
|
"base_change_list_template": self.change_list_template,
|
|
731
740
|
}
|
|
732
741
|
|
|
733
|
-
def get_menu_view_url(self, request):
|
|
742
|
+
def get_menu_view_url(self, request) -> str:
|
|
734
743
|
all_config = self.get_all_config(request)
|
|
735
744
|
url_suffix = ""
|
|
736
745
|
if all_config and all_config.get("all_params_changed", False):
|
|
@@ -744,10 +753,10 @@ class SBAdmin(
|
|
|
744
753
|
|
|
745
754
|
return f'{reverse(f"sb_admin:{self.get_id()}_changelist")}{url_suffix}'
|
|
746
755
|
|
|
747
|
-
def get_menu_label(self):
|
|
756
|
+
def get_menu_label(self) -> str:
|
|
748
757
|
return self.menu_label or self.model._meta.verbose_name_plural
|
|
749
758
|
|
|
750
|
-
def get_action_url(self, action, modifier="template"):
|
|
759
|
+
def get_action_url(self, action, modifier="template") -> str:
|
|
751
760
|
if not hasattr(self, action):
|
|
752
761
|
raise ImproperlyConfigured(f"Action {action} does not exist on {self}")
|
|
753
762
|
return reverse(
|
|
@@ -759,16 +768,16 @@ class SBAdmin(
|
|
|
759
768
|
},
|
|
760
769
|
)
|
|
761
770
|
|
|
762
|
-
def get_detail_url(self, object_id=None):
|
|
771
|
+
def get_detail_url(self, object_id=None) -> str:
|
|
763
772
|
return reverse(
|
|
764
773
|
f"sb_admin:{self.get_id()}_change",
|
|
765
774
|
kwargs={"object_id": object_id or OBJECT_ID_PLACEHOLDER},
|
|
766
775
|
)
|
|
767
776
|
|
|
768
|
-
def get_new_url(self):
|
|
777
|
+
def get_new_url(self, request) -> str:
|
|
769
778
|
return reverse(f"sb_admin:{self.get_id()}_add")
|
|
770
779
|
|
|
771
|
-
def get_previous_next_context(self, request, object_id):
|
|
780
|
+
def get_previous_next_context(self, request, object_id) -> dict | dict[str, Any]:
|
|
772
781
|
if not self.sbadmin_previous_next_buttons_enabled or not object_id:
|
|
773
782
|
return {}
|
|
774
783
|
changelist_filters = request.GET.get("_changelist_filters", "")
|
|
@@ -900,20 +909,20 @@ class SBAdminInline(
|
|
|
900
909
|
ordering = None
|
|
901
910
|
all_base_fields_form = None
|
|
902
911
|
|
|
903
|
-
def get_ordering(self, request):
|
|
912
|
+
def get_ordering(self, request) -> tuple[str]:
|
|
904
913
|
"""
|
|
905
914
|
Hook for specifying field ordering.
|
|
906
915
|
"""
|
|
907
916
|
return self.ordering or ("-id",)
|
|
908
917
|
|
|
909
|
-
def get_queryset(self, request=None):
|
|
918
|
+
def get_queryset(self, request=None) -> QuerySet:
|
|
910
919
|
qs = super().get_queryset(request)
|
|
911
920
|
return qs.order_by(*self.get_ordering(request))
|
|
912
921
|
|
|
913
|
-
def get_sbadmin_inline_list_actions(self, request):
|
|
922
|
+
def get_sbadmin_inline_list_actions(self, request) -> list:
|
|
914
923
|
return [*(self.sbadmin_inline_list_actions or [])]
|
|
915
924
|
|
|
916
|
-
def get_action_url(self, action, modifier="template"):
|
|
925
|
+
def get_action_url(self, action, modifier="template") -> str:
|
|
917
926
|
return reverse(
|
|
918
927
|
"sb_admin:sb_admin_base",
|
|
919
928
|
kwargs={
|
|
@@ -923,14 +932,14 @@ class SBAdminInline(
|
|
|
923
932
|
},
|
|
924
933
|
)
|
|
925
934
|
|
|
926
|
-
def register_autocomplete_views(self, request):
|
|
935
|
+
def register_autocomplete_views(self, request) -> None:
|
|
927
936
|
super().register_autocomplete_views(request)
|
|
928
937
|
form_class = self.get_formset(request, self.model()).form
|
|
929
|
-
self.initialize_form_class(form_class)
|
|
938
|
+
self.initialize_form_class(form_class, request)
|
|
930
939
|
form_class()
|
|
931
940
|
|
|
932
|
-
def get_context_data(self, request):
|
|
933
|
-
is_sortable_active = self.sortable_field_name and (
|
|
941
|
+
def get_context_data(self, request) -> dict[str, Any]:
|
|
942
|
+
is_sortable_active: bool = self.sortable_field_name and (
|
|
934
943
|
self.has_add_permission(request) or self.has_change_permission(request)
|
|
935
944
|
)
|
|
936
945
|
return {
|
|
@@ -938,7 +947,7 @@ class SBAdminInline(
|
|
|
938
947
|
"is_sortable_active": is_sortable_active,
|
|
939
948
|
}
|
|
940
949
|
|
|
941
|
-
def init_sortable_field(self):
|
|
950
|
+
def init_sortable_field(self) -> None:
|
|
942
951
|
if not self.sortable_field_name:
|
|
943
952
|
for field_name in self.sbadmin_sortable_field_options:
|
|
944
953
|
is_sortable_field_present = False
|
|
@@ -954,15 +963,15 @@ class SBAdminInline(
|
|
|
954
963
|
self.init_sortable_field()
|
|
955
964
|
super().__init__(parent_model, admin_site)
|
|
956
965
|
|
|
957
|
-
def init_view_dynamic(self, request, request_data=None, **kwargs):
|
|
966
|
+
def init_view_dynamic(self, request, request_data=None, **kwargs) -> None:
|
|
958
967
|
return super().init_view_dynamic(request, request_data, **kwargs)
|
|
959
968
|
|
|
960
|
-
def get_id(self):
|
|
969
|
+
def get_id(self) -> str:
|
|
961
970
|
return (
|
|
962
971
|
f"{self.__class__.__name__}_{SBAdminViewService.get_model_path(self.model)}"
|
|
963
972
|
)
|
|
964
973
|
|
|
965
|
-
def init_inline_dynamic(self, request, obj=None):
|
|
974
|
+
def init_inline_dynamic(self, request, obj=None) -> None:
|
|
966
975
|
self.threadsafe_request = request
|
|
967
976
|
self.parent_instance = obj
|
|
968
977
|
|
|
@@ -976,7 +985,7 @@ class SBAdminInline(
|
|
|
976
985
|
self.initialize_all_base_fields_form(request)
|
|
977
986
|
formset = super().get_formset(request, obj, **kwargs)
|
|
978
987
|
form_class = formset.form
|
|
979
|
-
self.initialize_form_class(form_class)
|
|
988
|
+
self.initialize_form_class(form_class, request)
|
|
980
989
|
return formset
|
|
981
990
|
|
|
982
991
|
|
|
@@ -269,6 +269,8 @@ class SBAdminAttributesWidget(SBAdminTextInputWidget):
|
|
|
269
269
|
dict_widgets = []
|
|
270
270
|
template_widget = {"attrs": {"class": "input"}}
|
|
271
271
|
if widget and value:
|
|
272
|
+
if isinstance(value, str):
|
|
273
|
+
value = json.loads(value)
|
|
272
274
|
dict_widgets = [
|
|
273
275
|
{
|
|
274
276
|
"key": {"value": key, **template_widget},
|