django-unfold 0.27.0__py3-none-any.whl → 0.28.1__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_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/METADATA +64 -9
- {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/RECORD +30 -27
- unfold/admin.py +1 -0
- unfold/contrib/forms/widgets.py +2 -0
- unfold/contrib/import_export/forms.py +21 -7
- unfold/contrib/import_export/templates/admin/import_export/change_list_export.html +5 -0
- unfold/contrib/import_export/templates/admin/import_export/export.html +1 -1
- unfold/contrib/simple_history/templates/simple_history/object_history.html +3 -5
- unfold/contrib/simple_history/templates/simple_history/{_object_history_list.html → object_history_list.html} +49 -11
- unfold/dataclasses.py +2 -0
- unfold/fields.py +9 -1
- unfold/static/unfold/css/styles.css +1 -1
- unfold/styles.css +1 -2
- unfold/templates/admin/login.html +4 -0
- unfold/templates/admin/submit_line.html +1 -1
- unfold/templates/unfold/helpers/attrs.html +1 -0
- unfold/templates/unfold/helpers/boolean.html +1 -1
- unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
- unfold/templates/unfold/helpers/fieldset_row.html +2 -2
- unfold/templates/unfold/helpers/navigation.html +1 -1
- unfold/templates/unfold/helpers/search_results.html +10 -10
- unfold/templates/unfold/layouts/base.html +11 -0
- unfold/templates/unfold/layouts/base_simple.html +7 -1
- unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
- unfold/templates/unfold/widgets/split_datetime.html +7 -7
- unfold/utils.py +21 -1
- unfold/views.py +18 -6
- unfold/widgets.py +12 -1
- {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/LICENSE.md +0 -0
- {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/WHEEL +0 -0
@@ -1,23 +1,23 @@
|
|
1
|
-
<div class="datetime flex flex-col max-w-2xl lg:flex-row">
|
2
|
-
<div class="basis-1/2 flex flex-col flex-wrap mb-4 lg:mb-0
|
3
|
-
<div class="font-medium mb-2 text-gray-500 text-sm dark:text-gray-400">
|
1
|
+
<div class="datetime flex flex-col gap-2 max-w-2xl lg:flex-row group-[.field-row]:flex-row group-[.field-row]:items-center">
|
2
|
+
<div class="basis-1/2 flex flex-col flex-wrap mb-4 lg:mb-0 group-[.field-row]:flex-row group-[.field-row]:gap-2">
|
3
|
+
<div class="font-medium mb-2 text-gray-500 text-sm dark:text-gray-400 group-[.field-row]:mb-0 group-[.field-row]:flex group-[.field-row]:items-center">
|
4
4
|
{{ date_label }}
|
5
5
|
</div>
|
6
6
|
|
7
7
|
{% with widget=widget.subwidgets.0 %}
|
8
|
-
<div class="flex flex-col relative">
|
8
|
+
<div class="flex flex-col relative group-[.field-row]:flex-grow">
|
9
9
|
{% include widget.template_name %}
|
10
10
|
</div>
|
11
11
|
{% endwith %}
|
12
12
|
</div>
|
13
13
|
|
14
|
-
<div class="basis-1/2 flex flex-col flex-wrap lg:ml-auto mt-3 md:mt-0">
|
15
|
-
<div class="font-medium mb-2 text-gray-500 text-sm dark:text-gray-400">
|
14
|
+
<div class="basis-1/2 flex flex-col flex-wrap lg:ml-auto mt-3 md:mt-0 group-[.field-row]:flex-row group-[.field-row]:gap-2">
|
15
|
+
<div class="font-medium mb-2 text-gray-500 text-sm dark:text-gray-400 group-[.field-row]:mb-0 group-[.field-row]:flex group-[.field-row]:items-center">
|
16
16
|
{{ time_label }}
|
17
17
|
</div>
|
18
18
|
|
19
19
|
{% with widget=widget.subwidgets.1 %}
|
20
|
-
<div class="flex flex-col relative">
|
20
|
+
<div class="flex flex-col relative group-[.field-row]:flex-grow">
|
21
21
|
{% include widget.template_name %}
|
22
22
|
</div>
|
23
23
|
{% endwith %}
|
unfold/utils.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import datetime
|
2
2
|
import decimal
|
3
3
|
import json
|
4
|
-
from typing import Any, Iterable, List
|
4
|
+
from typing import Any, Iterable, List, Optional
|
5
5
|
|
6
6
|
from django.db import models
|
7
7
|
from django.template.loader import render_to_string
|
@@ -121,3 +121,23 @@ def hex_to_rgb(hex_color: str) -> List[int]:
|
|
121
121
|
b = int(hex_color[4:6], 16)
|
122
122
|
|
123
123
|
return (r, g, b)
|
124
|
+
|
125
|
+
|
126
|
+
def prettify_json(data: Any) -> Optional[str]:
|
127
|
+
try:
|
128
|
+
from pygments import highlight
|
129
|
+
from pygments.formatters import HtmlFormatter
|
130
|
+
from pygments.lexers import JsonLexer
|
131
|
+
except ImportError:
|
132
|
+
return None
|
133
|
+
|
134
|
+
def format_response(response: str, theme: str) -> str:
|
135
|
+
formatter = HtmlFormatter(style=theme, noclasses=True, nobackground=True)
|
136
|
+
return highlight(response, JsonLexer(), formatter)
|
137
|
+
|
138
|
+
response = json.dumps(data, sort_keys=True, indent=4)
|
139
|
+
|
140
|
+
return mark_safe(
|
141
|
+
f'<div class="block dark:hidden">{format_response(response, "colorful")}</div>'
|
142
|
+
f'<div class="hidden dark:block">{format_response(response, "monokai")}</div>'
|
143
|
+
)
|
unfold/views.py
CHANGED
@@ -10,13 +10,25 @@ class UnfoldModelAdminViewMixin(PermissionRequiredMixin):
|
|
10
10
|
Prepares views to be displayed in admin
|
11
11
|
"""
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
model_admin = None
|
14
|
+
|
15
|
+
def __init__(self, model_admin, **kwargs):
|
16
|
+
self.model_admin = model_admin
|
17
|
+
super().__init__(**kwargs)
|
18
|
+
|
19
|
+
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
|
20
|
+
if not hasattr(self, "model_admin"):
|
15
21
|
raise UnfoldException(
|
16
22
|
"UnfoldModelAdminViewMixin was not provided with 'model_admin' argument"
|
17
23
|
)
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
|
25
|
+
if not hasattr(self, "title"):
|
26
|
+
raise UnfoldException(
|
27
|
+
"UnfoldModelAdminViewMixin was not provided with 'title' attribute"
|
28
|
+
)
|
29
|
+
|
30
|
+
return super().get_context_data(
|
31
|
+
**kwargs,
|
32
|
+
**self.model_admin.admin_site.each_context(self.request),
|
33
|
+
**{"title": self.title},
|
21
34
|
)
|
22
|
-
return context_data
|
unfold/widgets.py
CHANGED
@@ -288,7 +288,18 @@ class FileFieldMixin:
|
|
288
288
|
def get_context(self, name, value, attrs):
|
289
289
|
widget = super().get_context(name, value, attrs)
|
290
290
|
widget["widget"].update(
|
291
|
-
{
|
291
|
+
{
|
292
|
+
"class": " ".join([*CHECKBOX_CLASSES, *["form-check-input"]]),
|
293
|
+
"file_input_class": " ".join(
|
294
|
+
[
|
295
|
+
self.attrs.get("class", ""),
|
296
|
+
*[
|
297
|
+
"opacity-0",
|
298
|
+
"pointer-events-none",
|
299
|
+
],
|
300
|
+
]
|
301
|
+
),
|
302
|
+
}
|
292
303
|
)
|
293
304
|
return widget
|
294
305
|
|
File without changes
|
File without changes
|