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.
Files changed (30) hide show
  1. {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/METADATA +64 -9
  2. {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/RECORD +30 -27
  3. unfold/admin.py +1 -0
  4. unfold/contrib/forms/widgets.py +2 -0
  5. unfold/contrib/import_export/forms.py +21 -7
  6. unfold/contrib/import_export/templates/admin/import_export/change_list_export.html +5 -0
  7. unfold/contrib/import_export/templates/admin/import_export/export.html +1 -1
  8. unfold/contrib/simple_history/templates/simple_history/object_history.html +3 -5
  9. unfold/contrib/simple_history/templates/simple_history/{_object_history_list.html → object_history_list.html} +49 -11
  10. unfold/dataclasses.py +2 -0
  11. unfold/fields.py +9 -1
  12. unfold/static/unfold/css/styles.css +1 -1
  13. unfold/styles.css +1 -2
  14. unfold/templates/admin/login.html +4 -0
  15. unfold/templates/admin/submit_line.html +1 -1
  16. unfold/templates/unfold/helpers/attrs.html +1 -0
  17. unfold/templates/unfold/helpers/boolean.html +1 -1
  18. unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
  19. unfold/templates/unfold/helpers/fieldset_row.html +2 -2
  20. unfold/templates/unfold/helpers/navigation.html +1 -1
  21. unfold/templates/unfold/helpers/search_results.html +10 -10
  22. unfold/templates/unfold/layouts/base.html +11 -0
  23. unfold/templates/unfold/layouts/base_simple.html +7 -1
  24. unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
  25. unfold/templates/unfold/widgets/split_datetime.html +7 -7
  26. unfold/utils.py +21 -1
  27. unfold/views.py +18 -6
  28. unfold/widgets.py +12 -1
  29. {django_unfold-0.27.0.dist-info → django_unfold-0.28.1.dist-info}/LICENSE.md +0 -0
  30. {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 lg:mr-2">
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
- def get_context_data(self, **kwargs) -> Dict[str, Any]:
14
- if "model_admin" not in self.kwargs:
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
- model_admin = self.kwargs["model_admin"]
19
- context_data = super().get_context_data(
20
- **kwargs, **model_admin.admin_site.each_context(self.request)
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
- {"class": " ".join([*CHECKBOX_CLASSES, *["form-check-input"]])}
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