django-smartbase-admin 0.2.76__py3-none-any.whl → 0.2.78__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 +3 -3
- django_smartbase_admin/admin/admin_base.py +27 -29
- django_smartbase_admin/apps.py +1 -0
- django_smartbase_admin/engine/admin_base_view.py +2 -2
- django_smartbase_admin/engine/filter_widgets.py +2 -0
- django_smartbase_admin/monkeypatch/admin_readonly_field_monkeypatch.py +93 -0
- django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html +3 -1
- django_smartbase_admin/templates/sb_admin/includes/readonly_boolean_field.html +9 -0
- django_smartbase_admin/templates/sb_admin/includes/readonly_field.html +5 -14
- django_smartbase_admin/templates/sb_admin/inlines/table_inline.html +9 -4
- django_smartbase_admin/templatetags/sb_admin_tags.py +8 -0
- {django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/METADATA +2 -1
- {django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/RECORD +15 -13
- {django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/WHEEL +1 -1
- {django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/LICENSE.md +0 -0
|
@@ -454,7 +454,7 @@ class SBAdminListAction(SBAdminAction):
|
|
|
454
454
|
additional_filter = ~Q(id__in=self.deselected_rows)
|
|
455
455
|
return additional_filter
|
|
456
456
|
|
|
457
|
-
def get_xlsx_data(self):
|
|
457
|
+
def get_xlsx_data(self, request):
|
|
458
458
|
page_size = XLSX_PAGE_CHUNK_SIZE
|
|
459
459
|
file_name = (
|
|
460
460
|
f'{self.view.get_menu_label()}__{timezone.now().strftime("%Y-%m-%d")}.xlsx'
|
|
@@ -477,8 +477,8 @@ class SBAdminListAction(SBAdminAction):
|
|
|
477
477
|
)["data"]
|
|
478
478
|
)
|
|
479
479
|
options = (
|
|
480
|
-
self.view.get_sbadmin_xlsx_options().to_json()
|
|
481
|
-
if self.view.get_sbadmin_xlsx_options()
|
|
480
|
+
self.view.get_sbadmin_xlsx_options(request).to_json()
|
|
481
|
+
if self.view.get_sbadmin_xlsx_options(request)
|
|
482
482
|
else {}
|
|
483
483
|
)
|
|
484
484
|
return [file_name, data_list, columns, options]
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import urllib.parse
|
|
3
|
+
from functools import partial
|
|
3
4
|
|
|
4
5
|
from ckeditor.fields import RichTextFormField
|
|
5
6
|
from ckeditor_uploader.fields import RichTextUploadingFormField
|
|
6
7
|
from django import forms
|
|
7
8
|
from django.contrib import admin
|
|
8
9
|
from django.contrib.admin.options import get_content_type_for_model
|
|
9
|
-
from django.contrib.admin.utils import unquote
|
|
10
|
+
from django.contrib.admin.utils import unquote
|
|
10
11
|
from django.contrib.admin.widgets import AdminTextareaWidget
|
|
11
12
|
from django.contrib.auth.forms import UsernameField, ReadOnlyPasswordHashWidget
|
|
12
13
|
from django.core.exceptions import (
|
|
13
14
|
FieldDoesNotExist,
|
|
14
15
|
ImproperlyConfigured,
|
|
15
16
|
PermissionDenied,
|
|
16
|
-
ObjectDoesNotExist,
|
|
17
17
|
)
|
|
18
18
|
from django.db import models
|
|
19
19
|
from django.forms import HiddenInput
|
|
20
|
-
from django.forms.models import
|
|
20
|
+
from django.forms.models import (
|
|
21
|
+
ModelFormMetaclass,
|
|
22
|
+
modelform_factory,
|
|
23
|
+
)
|
|
21
24
|
from django.template.loader import render_to_string
|
|
22
25
|
from django.template.response import TemplateResponse
|
|
23
26
|
from django.urls import reverse
|
|
24
27
|
from django.utils.safestring import mark_safe
|
|
25
28
|
from django.utils.text import capfirst
|
|
26
29
|
from django.utils.translation import gettext_lazy as _
|
|
27
|
-
from django.utils.translation import override as translation_override
|
|
28
30
|
from django_admin_inline_paginator.admin import TabularInlinePaginated
|
|
29
31
|
from filer.fields.image import AdminImageFormField
|
|
30
32
|
from nested_admin.nested import (
|
|
@@ -35,7 +37,6 @@ from nested_admin.nested import (
|
|
|
35
37
|
NestedGenericStackedInline,
|
|
36
38
|
)
|
|
37
39
|
|
|
38
|
-
from django_smartbase_admin.actions.admin_action_list import SBAdminListAction
|
|
39
40
|
from django_smartbase_admin.engine.actions import SBAdminCustomAction
|
|
40
41
|
from django_smartbase_admin.services.thread_local import SBAdminThreadLocalService
|
|
41
42
|
from django_smartbase_admin.utils import FormFieldsetMixin
|
|
@@ -434,6 +435,7 @@ if parler_enabled:
|
|
|
434
435
|
|
|
435
436
|
class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
436
437
|
sbadmin_fake_inlines = None
|
|
438
|
+
all_base_fields_form = None
|
|
437
439
|
|
|
438
440
|
def init_view_static(self, configuration, model, admin_site):
|
|
439
441
|
configuration.view_map[self.get_id()] = self
|
|
@@ -488,6 +490,14 @@ class SBAdminInlineAndAdminCommon(SBAdminFormFieldWidgetsMixin):
|
|
|
488
490
|
if form:
|
|
489
491
|
form.view = self
|
|
490
492
|
|
|
493
|
+
def initialize_all_base_fields_form(self, request):
|
|
494
|
+
params = {
|
|
495
|
+
"form": self.form,
|
|
496
|
+
"fields": "__all__",
|
|
497
|
+
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
|
498
|
+
}
|
|
499
|
+
self.all_base_fields_form = modelform_factory(self.model, **params)
|
|
500
|
+
|
|
491
501
|
|
|
492
502
|
class SBAdminThirdParty(SBAdminInlineAndAdminCommon, SBAdminBaseView):
|
|
493
503
|
def get_menu_view_url(self, request):
|
|
@@ -640,6 +650,7 @@ class SBAdmin(
|
|
|
640
650
|
return self.sbadmin_list_filter or self.get_list_filter(request)
|
|
641
651
|
|
|
642
652
|
def get_form(self, request, obj=None, **kwargs):
|
|
653
|
+
self.initialize_all_base_fields_form(request)
|
|
643
654
|
form = super().get_form(request, obj, **kwargs)
|
|
644
655
|
self.initialize_form_class(form)
|
|
645
656
|
return form
|
|
@@ -775,30 +786,11 @@ class SBAdmin(
|
|
|
775
786
|
),
|
|
776
787
|
}
|
|
777
788
|
|
|
778
|
-
def get_readonly_base_fields_context(self, request, object_id=None):
|
|
779
|
-
obj = None
|
|
780
|
-
if object_id:
|
|
781
|
-
obj = self.get_object(request, object_id)
|
|
782
|
-
readonly_base_fields = {}
|
|
783
|
-
for field in self.readonly_fields:
|
|
784
|
-
base_field = self.form.base_fields.get(field)
|
|
785
|
-
if base_field:
|
|
786
|
-
try:
|
|
787
|
-
f, attr, value = lookup_field(field, obj, self)
|
|
788
|
-
except (AttributeError, ValueError, ObjectDoesNotExist):
|
|
789
|
-
value = base_field.initial
|
|
790
|
-
readonly_base_fields[field] = {
|
|
791
|
-
"field": base_field,
|
|
792
|
-
"value": value,
|
|
793
|
-
}
|
|
794
|
-
return {"readonly_base_fields": readonly_base_fields}
|
|
795
|
-
|
|
796
789
|
def add_view(self, request, form_url="", extra_context=None):
|
|
797
790
|
extra_context = extra_context or {}
|
|
798
791
|
extra_context.update(self.get_global_context(request, None))
|
|
799
792
|
extra_context.update(self.get_fieldsets_context(request, None))
|
|
800
793
|
extra_context.update(self.get_tabs_context(request, None))
|
|
801
|
-
extra_context.update(self.get_readonly_base_fields_context(request, None))
|
|
802
794
|
return self.changeform_view(request, None, form_url, extra_context)
|
|
803
795
|
|
|
804
796
|
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
@@ -807,7 +799,6 @@ class SBAdmin(
|
|
|
807
799
|
extra_context.update(self.get_fieldsets_context(request, object_id))
|
|
808
800
|
extra_context.update(self.get_tabs_context(request, object_id))
|
|
809
801
|
extra_context.update(self.get_previous_next_context(request, object_id))
|
|
810
|
-
extra_context.update(self.get_readonly_base_fields_context(request, object_id))
|
|
811
802
|
return super().change_view(request, object_id, form_url, extra_context)
|
|
812
803
|
|
|
813
804
|
def changelist_view(self, request, extra_context=None):
|
|
@@ -887,6 +878,7 @@ class SBAdminInline(
|
|
|
887
878
|
sbadmin_inline_list_actions = None
|
|
888
879
|
extra = 0
|
|
889
880
|
ordering = None
|
|
881
|
+
all_base_fields_form = None
|
|
890
882
|
|
|
891
883
|
def get_ordering(self, request):
|
|
892
884
|
"""
|
|
@@ -898,7 +890,7 @@ class SBAdminInline(
|
|
|
898
890
|
qs = super().get_queryset(request)
|
|
899
891
|
return qs.order_by(*self.get_ordering(request))
|
|
900
892
|
|
|
901
|
-
def get_sbadmin_inline_list_actions(self):
|
|
893
|
+
def get_sbadmin_inline_list_actions(self, request):
|
|
902
894
|
return [*(self.sbadmin_inline_list_actions or [])]
|
|
903
895
|
|
|
904
896
|
def get_action_url(self, action, modifier="template"):
|
|
@@ -917,9 +909,14 @@ class SBAdminInline(
|
|
|
917
909
|
self.initialize_form_class(form_class)
|
|
918
910
|
form_class()
|
|
919
911
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
912
|
+
def get_context_data(self, request):
|
|
913
|
+
is_sortable_active = self.sortable_field_name and (
|
|
914
|
+
self.has_add_permission(request) or self.has_change_permission(request)
|
|
915
|
+
)
|
|
916
|
+
return {
|
|
917
|
+
"inline_list_actions": self.get_sbadmin_inline_list_actions(request),
|
|
918
|
+
"is_sortable_active": is_sortable_active,
|
|
919
|
+
}
|
|
923
920
|
|
|
924
921
|
def init_sortable_field(self):
|
|
925
922
|
if not self.sortable_field_name:
|
|
@@ -956,6 +953,7 @@ class SBAdminInline(
|
|
|
956
953
|
return formfield
|
|
957
954
|
|
|
958
955
|
def get_formset(self, request, obj=None, **kwargs):
|
|
956
|
+
self.initialize_all_base_fields_form(request)
|
|
959
957
|
formset = super().get_formset(request, obj, **kwargs)
|
|
960
958
|
form_class = formset.form
|
|
961
959
|
self.initialize_form_class(form_class)
|
django_smartbase_admin/apps.py
CHANGED
|
@@ -11,6 +11,7 @@ class SBAdminConfig(AppConfig):
|
|
|
11
11
|
def ready(self):
|
|
12
12
|
super().ready()
|
|
13
13
|
from .monkeypatch import fake_inline_monkeypatch
|
|
14
|
+
from .monkeypatch import admin_readonly_field_monkeypatch
|
|
14
15
|
|
|
15
16
|
if settings.SB_ADMIN_CONFIGURATION:
|
|
16
17
|
autodiscover_modules("sb_admin", register_to=sb_admin_site)
|
|
@@ -500,7 +500,7 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
500
500
|
result[action.group].append(action)
|
|
501
501
|
return result
|
|
502
502
|
|
|
503
|
-
def get_sbadmin_xlsx_options(self):
|
|
503
|
+
def get_sbadmin_xlsx_options(self, request):
|
|
504
504
|
self.sbadmin_xlsx_options = self.sbadmin_xlsx_options or SBAdminXLSXOptions(
|
|
505
505
|
header_cell_format=SBAdminXLSXFormat(
|
|
506
506
|
bg_color="#00aaa7", font_color="#ffffff", bold=True
|
|
@@ -514,7 +514,7 @@ class SBAdminBaseListView(SBAdminBaseView):
|
|
|
514
514
|
|
|
515
515
|
def action_xlsx_export(self, request, modifier):
|
|
516
516
|
action = self.sbadmin_list_action_class(self, request)
|
|
517
|
-
data = action.get_xlsx_data()
|
|
517
|
+
data = action.get_xlsx_data(request)
|
|
518
518
|
return SBAdminXLSXExportService.create_workbook_http_respone(*data)
|
|
519
519
|
|
|
520
520
|
def action_bulk_delete(self, request, modifier):
|
|
@@ -621,6 +621,8 @@ class AutocompleteFilterWidget(
|
|
|
621
621
|
def get_label(self, request, item):
|
|
622
622
|
if self.label_lambda:
|
|
623
623
|
return self.label_lambda(request, item)
|
|
624
|
+
if isinstance(item, list):
|
|
625
|
+
return ", ".join(map(str, item))
|
|
624
626
|
return str(item)
|
|
625
627
|
|
|
626
628
|
def get_context(self, name, value, attrs):
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import django.contrib.admin.helpers
|
|
2
|
+
from django.contrib.admin.utils import lookup_field, display_for_field
|
|
3
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
4
|
+
from django.db import models
|
|
5
|
+
from django.db.models import ManyToManyRel, ForeignObjectRel, OneToOneField
|
|
6
|
+
from django.template.defaultfilters import linebreaksbr
|
|
7
|
+
from django.template.loader import render_to_string
|
|
8
|
+
from django.utils.html import conditional_escape
|
|
9
|
+
from django.utils.safestring import mark_safe
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SBAdminReadonlyField(django.contrib.admin.helpers.AdminReadonlyField):
|
|
13
|
+
readonly_template = "sb_admin/includes/readonly_field.html"
|
|
14
|
+
readonly_boolean_template = "sb_admin/includes/readonly_boolean_field.html"
|
|
15
|
+
|
|
16
|
+
def _boolean_field_content(self, value):
|
|
17
|
+
return mark_safe(
|
|
18
|
+
render_to_string(
|
|
19
|
+
template_name=self.readonly_boolean_template,
|
|
20
|
+
context={
|
|
21
|
+
"field_label": self.field.get("label"),
|
|
22
|
+
"field_name": self.field.get("name"),
|
|
23
|
+
"value": value,
|
|
24
|
+
},
|
|
25
|
+
),
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def contents(self, request=None):
|
|
29
|
+
if self.model_admin.admin_site.name != "sb_admin":
|
|
30
|
+
return super().contents()
|
|
31
|
+
|
|
32
|
+
field, obj, model_admin = (
|
|
33
|
+
self.field["field"],
|
|
34
|
+
self.form.instance,
|
|
35
|
+
self.model_admin,
|
|
36
|
+
)
|
|
37
|
+
try:
|
|
38
|
+
f, attr, value = lookup_field(field, obj, model_admin)
|
|
39
|
+
except (AttributeError, ValueError, ObjectDoesNotExist):
|
|
40
|
+
result_repr = self.empty_value_display
|
|
41
|
+
else:
|
|
42
|
+
if field in self.form.fields:
|
|
43
|
+
widget = self.form[field].field.widget
|
|
44
|
+
# This isn't elegant but suffices for contrib.auth's
|
|
45
|
+
# ReadOnlyPasswordHashWidget.
|
|
46
|
+
if getattr(widget, "read_only", False):
|
|
47
|
+
return widget.render(field, value)
|
|
48
|
+
if f is None:
|
|
49
|
+
if getattr(attr, "boolean", False):
|
|
50
|
+
return self._boolean_field_content(value)
|
|
51
|
+
else:
|
|
52
|
+
if hasattr(value, "__html__"):
|
|
53
|
+
result_repr = value
|
|
54
|
+
else:
|
|
55
|
+
result_repr = linebreaksbr(value)
|
|
56
|
+
else:
|
|
57
|
+
base_field = self.form.fields.get(
|
|
58
|
+
field
|
|
59
|
+
) or model_admin.all_base_fields_form.base_fields.get(field)
|
|
60
|
+
if isinstance(f.remote_field, ManyToManyRel) and value is not None:
|
|
61
|
+
# get label from widget if has base_field
|
|
62
|
+
if base_field:
|
|
63
|
+
result_repr = base_field.widget.get_label(
|
|
64
|
+
request, list(value.all())
|
|
65
|
+
)
|
|
66
|
+
else:
|
|
67
|
+
result_repr = ", ".join(map(str, value.all()))
|
|
68
|
+
elif (
|
|
69
|
+
isinstance(f.remote_field, (ForeignObjectRel, OneToOneField))
|
|
70
|
+
and value is not None
|
|
71
|
+
):
|
|
72
|
+
# get label from widget if has base_field
|
|
73
|
+
if base_field:
|
|
74
|
+
result_repr = base_field.widget.get_label(
|
|
75
|
+
request, getattr(obj, field)
|
|
76
|
+
)
|
|
77
|
+
else:
|
|
78
|
+
result_repr = self.get_admin_url(f.remote_field, value)
|
|
79
|
+
else:
|
|
80
|
+
if isinstance(f, models.BooleanField):
|
|
81
|
+
return self._boolean_field_content(value)
|
|
82
|
+
result_repr = display_for_field(value, f, self.empty_value_display)
|
|
83
|
+
result_repr = linebreaksbr(result_repr)
|
|
84
|
+
return render_to_string(
|
|
85
|
+
template_name=self.readonly_template,
|
|
86
|
+
context={
|
|
87
|
+
"readonly_content": conditional_escape(result_repr),
|
|
88
|
+
"field_label": self.field.get("label"),
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
django.contrib.admin.helpers.AdminReadonlyField = SBAdminReadonlyField
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
{% load sb_admin_tags %}
|
|
2
|
+
|
|
1
3
|
{% if fieldset.name %}
|
|
2
4
|
<header class="mb-24">
|
|
3
5
|
<span class="text-dark-900">{{ fieldset.name }}</span>
|
|
@@ -23,7 +25,7 @@
|
|
|
23
25
|
{% for field in line %}
|
|
24
26
|
<div class="mb-16 sm:mb-24 max-xs:w-full sm:flex-1{% if field.field.is_hidden %} hidden{% endif %}">
|
|
25
27
|
{% if field.is_readonly %}
|
|
26
|
-
{%
|
|
28
|
+
{% call_method field "contents" request %}
|
|
27
29
|
{% else %}
|
|
28
30
|
{{ field.field }}
|
|
29
31
|
{% if not line.fields|length == 1 %}{{ field.errors }}{% endif %}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="w-full">
|
|
2
|
+
<div class="text-14 w-full break-all">
|
|
3
|
+
<div class="relative">
|
|
4
|
+
<input type="checkbox" name="{{ field_name }}" id="id_{{ field_name }}" form="#" class="toggle"{% if value %} checked{% endif %} readonly disabled>
|
|
5
|
+
<label for="id_{{ field_name }}"></label>
|
|
6
|
+
<label for="id_{{ field_name }}">{{ field_label }}</label>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
{% load sb_admin_tags %}
|
|
2
2
|
|
|
3
3
|
<div class="w-full">
|
|
4
|
-
{%
|
|
5
|
-
|
|
6
|
-
<div class="relative">
|
|
7
|
-
<input type="checkbox" name="{{ field.field.name }}" id="id_{{ field.field.name }}" form="#" class="toggle"{% if readonly_field.value %} checked{% endif %} readonly disabled>
|
|
8
|
-
<label for="id_{{ field.field.name }}"></label>
|
|
9
|
-
<label for="id_{{ field.field.name }}">{{ field.field.label }}</label>
|
|
10
|
-
</div>
|
|
11
|
-
{% else %}
|
|
12
|
-
{% if field.field.label %}
|
|
13
|
-
<label class="inline-flex text-dark-900 text-14 leading-18 font-medium mb-8">{{ field.field.label }}:</label>
|
|
14
|
-
{% endif %}
|
|
15
|
-
<div class="text-14 w-full break-all">
|
|
16
|
-
{{ field.contents }}
|
|
17
|
-
</div>
|
|
4
|
+
{% if field_label %}
|
|
5
|
+
<label class="inline-flex text-dark-900 text-14 leading-18 font-medium mb-8">{{ field_label }}:</label>
|
|
18
6
|
{% endif %}
|
|
7
|
+
<div class="text-14 w-full break-all">
|
|
8
|
+
{{ readonly_content }}
|
|
9
|
+
</div>
|
|
19
10
|
</div>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{% load admin_urlname admin_urlquote from admin_urls %}
|
|
2
2
|
{% load i18n nested_admin static widget_tweaks sb_admin_tags %}
|
|
3
3
|
|
|
4
|
+
{% call_method inline_admin_formset.opts "get_context_data" request as context_data %}
|
|
4
5
|
{% with inline_admin_formset.formset.is_nested as is_nested %}
|
|
5
6
|
|
|
6
7
|
{% with inline_admin_formset.opts as inline_opts %}
|
|
@@ -18,7 +19,7 @@
|
|
|
18
19
|
{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}{% endif %}
|
|
19
20
|
</span>
|
|
20
21
|
<div class="ml-auto flex gap-8">
|
|
21
|
-
{% for list_action in
|
|
22
|
+
{% for list_action in context_data.inline_list_actions %}
|
|
22
23
|
<a {% if list_action.open_in_modal %}{% include 'sb_admin/actions/partials/open_modal_attrs.html' with action=list_action %}{% endif %} href="{{ list_action.url }}"
|
|
23
24
|
class="btn {{ list_action.css_class|default_if_none:'' }}">{{ list_action.title }}</a>
|
|
24
25
|
{% endfor %}
|
|
@@ -47,7 +48,9 @@
|
|
|
47
48
|
{% with inline_admin_formset.opts.sortable_field_name|default:"" as sortable_field_name %}
|
|
48
49
|
<thead class="djn-module djn-thead">
|
|
49
50
|
<tr>
|
|
50
|
-
|
|
51
|
+
{% if context_data.is_sortable_active %}
|
|
52
|
+
<th class="original{% if sortable_field_name %} is-sortable{% endif %}"></th>
|
|
53
|
+
{% endif %}
|
|
51
54
|
{% for field in inline_admin_formset.fields %}
|
|
52
55
|
{% if not field.widget.is_hidden %}
|
|
53
56
|
<th class="djn-th
|
|
@@ -98,7 +101,7 @@
|
|
|
98
101
|
</tr>
|
|
99
102
|
{% endif %}
|
|
100
103
|
<tr class="djn-tr form-row{% if inline_admin_form.original or inline_admin_form.show_url %} has_original{% endif %}">
|
|
101
|
-
<td class="original{% if inline_admin_formset.opts.sortable_field_name %} is-sortable{% endif %}">
|
|
104
|
+
<td class="original{% if inline_admin_formset.opts.sortable_field_name %} is-sortable{% endif %}" style="{% if not context_data.is_sortable_active %}display: none;{% endif %}">
|
|
102
105
|
{% if inline_admin_formset.opts.sortable_field_name %}
|
|
103
106
|
<div class="djn-drag-handler">
|
|
104
107
|
<svg class="w-20 h-20 text-dark-400">
|
|
@@ -145,7 +148,9 @@
|
|
|
145
148
|
{% if not field.field.is_hidden %}
|
|
146
149
|
<td class="djn-td field-{{ field.field.name }}">
|
|
147
150
|
{% if field.is_readonly %}
|
|
148
|
-
<div class="px-10 py-8">
|
|
151
|
+
<div class="px-10 py-8">
|
|
152
|
+
{% call_method field "contents" request %}
|
|
153
|
+
</div>
|
|
149
154
|
{% else %}
|
|
150
155
|
{{ field.field }}
|
|
151
156
|
{% if field.field.errors %}
|
|
@@ -212,3 +212,11 @@ def get_log_entry_message(log_entry):
|
|
|
212
212
|
return get_change_message_legacy(log_entry)
|
|
213
213
|
except Exception as e:
|
|
214
214
|
return ""
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@register.simple_tag
|
|
218
|
+
def call_method(obj, method_name, *args):
|
|
219
|
+
method = getattr(obj, method_name, None)
|
|
220
|
+
if method:
|
|
221
|
+
return method(*args)
|
|
222
|
+
return False
|
{django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-smartbase-admin
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.78
|
|
4
4
|
Summary:
|
|
5
5
|
Author: SmartBase
|
|
6
6
|
Author-email: info@smartbase.sk
|
|
@@ -9,6 +9,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
13
|
Requires-Dist: django (>=4.1,<6.0)
|
|
13
14
|
Requires-Dist: django-admin-inline-paginator (>=0.4.0,<0.5.0)
|
|
14
15
|
Requires-Dist: django-ckeditor (>=6.7.1,<7.0.0)
|
|
@@ -1,16 +1,16 @@
|
|
|
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=
|
|
3
|
+
django_smartbase_admin/actions/admin_action_list.py,sha256=2DthQWmdzUh1Bh4d8xZjpFqhwzzaIBk_QJsSXKIrZgA,19297
|
|
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=
|
|
6
|
+
django_smartbase_admin/admin/admin_base.py,sha256=wMAjZW9YpUsO_5nBZOIUAZUuonQHKZwQk06Gd32nQP0,39787
|
|
7
7
|
django_smartbase_admin/admin/site.py,sha256=VrJBhwgZsLa2GohvjnNL7m4dVR3S4Ou1V1UzfE1qOoQ,6577
|
|
8
8
|
django_smartbase_admin/admin/widgets.py,sha256=udNG3fqDSTKnbPpvY02qhanPoCm_Kgn7Bg8R3EjWJT4,15035
|
|
9
|
-
django_smartbase_admin/apps.py,sha256=
|
|
9
|
+
django_smartbase_admin/apps.py,sha256=C1wT1YUEZNKcUJfpD01nIZEFgYEsuav52WFKvEURRDU,545
|
|
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
12
|
django_smartbase_admin/engine/actions.py,sha256=n8PiG60Kj1ECHB4lfVH_jvHMyOjOZ-DvQfO9F2CuqW0,1733
|
|
13
|
-
django_smartbase_admin/engine/admin_base_view.py,sha256=
|
|
13
|
+
django_smartbase_admin/engine/admin_base_view.py,sha256=0yMQO-Aa9UtEBcqcgPEJ6VpkaEa30LetmCRfkaH3X2E,28591
|
|
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
|
|
@@ -19,7 +19,7 @@ django_smartbase_admin/engine/dashboard.py,sha256=wrvX0GI-SII2pG0DX8Kvy4JFaM6h8e
|
|
|
19
19
|
django_smartbase_admin/engine/fake_inline.py,sha256=9C2_mltg2P9-xa3vuoo5X_RcFaCRpKGNSy7t1_iiasE,5802
|
|
20
20
|
django_smartbase_admin/engine/field.py,sha256=BD_W0ekE5tQJxUGpUA8bo4ZyFk0u2F_6UTPH4drj0JU,10286
|
|
21
21
|
django_smartbase_admin/engine/field_formatter.py,sha256=eHbXEBwG8jBc9zKpDQ4T64N5J4afF0Cbb8RFeFfgQRg,1950
|
|
22
|
-
django_smartbase_admin/engine/filter_widgets.py,sha256=
|
|
22
|
+
django_smartbase_admin/engine/filter_widgets.py,sha256=dA5tUQ3d6STmMhMWj0pYH_G1tl0eYX3ZuDQ8b7qHLrE,23767
|
|
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
25
|
django_smartbase_admin/engine/modal_view.py,sha256=6eAmncDV9UzTWemWFQXZpVCIixWo5gWvNZGnK4mw4FM,2251
|
|
@@ -35,6 +35,7 @@ django_smartbase_admin/migrations/0003_auto_20230402_2328.py,sha256=-4fknf4126mz
|
|
|
35
35
|
django_smartbase_admin/migrations/0004_alter_sbadminlistviewconfiguration_action_and_more.py,sha256=j3cz6sz5ahxkIuHYlSU0opCt6iLolrnda6u9wRDbUsE,648
|
|
36
36
|
django_smartbase_admin/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
django_smartbase_admin/models.py,sha256=mvIe4-X8sapMfISZ1KitkEX8ljmVisVbTjxf_hgIjzs,743
|
|
38
|
+
django_smartbase_admin/monkeypatch/admin_readonly_field_monkeypatch.py,sha256=a4KmV1xgfjEuRGVizi6zdLfBY0-uyAR5jemUJa7sERY,3968
|
|
38
39
|
django_smartbase_admin/monkeypatch/fake_inline_monkeypatch.py,sha256=Wfrz_BmgF4XBKsqncaB3uyZaE13OOdPpQWsZe5_Idls,833
|
|
39
40
|
django_smartbase_admin/querysets.py,sha256=ST_6qxznqxJiv8Gk1bgYVMpK_gbU74ItKyvMmVmJX04,385
|
|
40
41
|
django_smartbase_admin/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -579,14 +580,15 @@ django_smartbase_admin/templates/sb_admin/includes/change_form_title.html,sha256
|
|
|
579
580
|
django_smartbase_admin/templates/sb_admin/includes/components.html,sha256=ixhN__EcMbCfjXQXdCElda18sqWZYj9scV3nsR9nXts,18822
|
|
580
581
|
django_smartbase_admin/templates/sb_admin/includes/confirmation.html,sha256=F2lgUPCIF6pveCSyS7L4k8ifZxa_DoJp-NZb4uwmtyI,1844
|
|
581
582
|
django_smartbase_admin/templates/sb_admin/includes/fieldset.html,sha256=cSaqkdB2OOMXW4UFysoDQP4x-Wm4fgMtClPHqHepv1o,280
|
|
582
|
-
django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html,sha256=
|
|
583
|
+
django_smartbase_admin/templates/sb_admin/includes/inline_fieldset.html,sha256=ov6iySp8Oo8VZ8Z54kTHh6PF254OufH2xqmqp0NX_W4,1936
|
|
583
584
|
django_smartbase_admin/templates/sb_admin/includes/loading.html,sha256=mI-Ya6y0vTOqPVUS9n_GPXmQDvyaDdL9637I5oqcnBE,287
|
|
584
585
|
django_smartbase_admin/templates/sb_admin/includes/loading_absolute.html,sha256=Eck62NW9ByTw6Mu5QOcYZZJVebhRUNbxTB29XmN5drE,304
|
|
585
586
|
django_smartbase_admin/templates/sb_admin/includes/notifications.html,sha256=wEEcrcdX3Wrlz-tVCJouiUFSZV_vVEqrc5opV_nifAw,783
|
|
586
|
-
django_smartbase_admin/templates/sb_admin/includes/
|
|
587
|
+
django_smartbase_admin/templates/sb_admin/includes/readonly_boolean_field.html,sha256=sCU7DKBeWVD7ILcOAd20APS3gTBLBwXJpDjzTETwp5M,412
|
|
588
|
+
django_smartbase_admin/templates/sb_admin/includes/readonly_field.html,sha256=uGysgcSJJRIwG-AW9Vtfysulz4HOKUNH9Wx0f8sZkuE,291
|
|
587
589
|
django_smartbase_admin/templates/sb_admin/includes/table_inline_delete_button.html,sha256=pgXePfkFu71wquoKGs-q-TQbuUuLqNEh5-MOINPp39o,1109
|
|
588
590
|
django_smartbase_admin/templates/sb_admin/inlines/stacked_inline.html,sha256=fB__KCS8tQq8zU_WMKVQcXJC20OLoG-pCyb_CYzMYXU,7592
|
|
589
|
-
django_smartbase_admin/templates/sb_admin/inlines/table_inline.html,sha256=
|
|
591
|
+
django_smartbase_admin/templates/sb_admin/inlines/table_inline.html,sha256=WxdbhtKrJOjbvHTC7vKmm5pILVGqXlJxO_n3sroZMZI,14816
|
|
590
592
|
django_smartbase_admin/templates/sb_admin/inlines/table_inline_paginated.html,sha256=2I59KWM_7yvchNjlIWHaHklrklnNsJBwaLlp9mZUYfQ,3046
|
|
591
593
|
django_smartbase_admin/templates/sb_admin/integrations/cms/page_list.html,sha256=juoU5UaqPozIgRX5EJyWpm2-mb1hqM2pfBoePZ1Vs-I,18190
|
|
592
594
|
django_smartbase_admin/templates/sb_admin/integrations/cms/translations_status_row.html,sha256=Ppm6oEmNZkZC_XV5QNFbgccsBumB6LVy1e0Vk8dPMCM,308
|
|
@@ -650,7 +652,7 @@ django_smartbase_admin/templates/sb_admin/widgets/toggle.html,sha256=H9D_SIeS2wn
|
|
|
650
652
|
django_smartbase_admin/templates/sb_admin/widgets/url.html,sha256=piw2218tiWPfOwncIvSGAW14Gc5FIzkL_YllirK4yTs,160
|
|
651
653
|
django_smartbase_admin/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
652
654
|
django_smartbase_admin/templatetags/base.py,sha256=XF1wUQxUjULXfdlV-PeHvITfbw65LTHjlDzRikJa_F4,1520
|
|
653
|
-
django_smartbase_admin/templatetags/sb_admin_tags.py,sha256=
|
|
655
|
+
django_smartbase_admin/templatetags/sb_admin_tags.py,sha256=FozRhcHjPxFFnJUb1zYWVI97eJg7up3b7qBtr14wUX0,7616
|
|
654
656
|
django_smartbase_admin/urls.py,sha256=Bjdewssljt0LIefjixBem9JN0kkghPvmrIETj3GdXbY,17
|
|
655
657
|
django_smartbase_admin/utils.py,sha256=0SUIA-n6XiPeDH7PvdekV1xIKwUjvyPxaBPEKsZKXyM,2775
|
|
656
658
|
django_smartbase_admin/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -658,7 +660,7 @@ django_smartbase_admin/views/dashboard_view.py,sha256=vtz5emYTQ5WDFeLA8HrcmjSOVd
|
|
|
658
660
|
django_smartbase_admin/views/global_filter_view.py,sha256=eYo1moJGyi7jc2cPDA5ZBiEgA7Hmc-DxbQvbqUpDkg8,1127
|
|
659
661
|
django_smartbase_admin/views/media_view.py,sha256=5BLWXuzynF7nM34t-mf2BQSRN5ojY8HxpLIqt7Jiq9g,292
|
|
660
662
|
django_smartbase_admin/views/translations_view.py,sha256=A02q1t13akLKd2Pg_ej4tVi5qPUKYxB2LqsBbYXM0l8,20267
|
|
661
|
-
django_smartbase_admin-0.2.
|
|
662
|
-
django_smartbase_admin-0.2.
|
|
663
|
-
django_smartbase_admin-0.2.
|
|
664
|
-
django_smartbase_admin-0.2.
|
|
663
|
+
django_smartbase_admin-0.2.78.dist-info/LICENSE.md,sha256=okRGMBOYvyhprt2eTpX_QXqpzC0MODF-U7zX-4fKPjQ,1078
|
|
664
|
+
django_smartbase_admin-0.2.78.dist-info/METADATA,sha256=Iwe2H_P_yL-Yaob7MitUD-RDF8MI4i3LTir3tiPi8Yw,996
|
|
665
|
+
django_smartbase_admin-0.2.78.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
|
666
|
+
django_smartbase_admin-0.2.78.dist-info/RECORD,,
|
{django_smartbase_admin-0.2.76.dist-info → django_smartbase_admin-0.2.78.dist-info}/LICENSE.md
RENAMED
|
File without changes
|