django-unfold 0.46.0__py3-none-any.whl → 0.47.0__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.46.0.dist-info → django_unfold-0.47.0.dist-info}/METADATA +5 -6
- {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/RECORD +38 -31
- {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/WHEEL +1 -1
- unfold/admin.py +15 -16
- unfold/checks.py +4 -4
- unfold/components.py +5 -5
- unfold/contrib/filters/admin/__init__.py +43 -0
- unfold/contrib/filters/admin/autocomplete_filters.py +16 -0
- unfold/contrib/filters/admin/datetime_filters.py +212 -0
- unfold/contrib/filters/admin/dropdown_filters.py +100 -0
- unfold/contrib/filters/admin/mixins.py +146 -0
- unfold/contrib/filters/admin/numeric_filters.py +196 -0
- unfold/contrib/filters/admin/text_filters.py +65 -0
- unfold/contrib/filters/admin.py +32 -32
- unfold/contrib/filters/forms.py +68 -17
- unfold/contrib/forms/widgets.py +9 -9
- unfold/contrib/inlines/checks.py +2 -4
- unfold/contrib/simple_history/templates/simple_history/object_history.html +17 -1
- unfold/contrib/simple_history/templates/simple_history/object_history_list.html +1 -1
- unfold/dataclasses.py +2 -2
- unfold/decorators.py +4 -3
- unfold/settings.py +2 -2
- unfold/sites.py +156 -140
- unfold/static/unfold/css/styles.css +1 -1
- unfold/static/unfold/js/app.js +2 -2
- unfold/templates/admin/filter.html +1 -1
- unfold/templates/unfold/helpers/change_list_filter.html +2 -2
- unfold/templates/unfold/helpers/change_list_filter_actions.html +1 -1
- unfold/templates/unfold/helpers/header_back_button.html +2 -2
- unfold/templates/unfold/helpers/tab_list.html +7 -1
- unfold/templates/unfold/layouts/skeleton.html +1 -1
- unfold/templatetags/unfold.py +55 -22
- unfold/templatetags/unfold_list.py +2 -2
- unfold/typing.py +5 -4
- unfold/utils.py +3 -2
- unfold/views.py +2 -2
- unfold/widgets.py +27 -27
- {django_unfold-0.46.0.dist-info → django_unfold-0.47.0.dist-info}/LICENSE.md +0 -0
unfold/static/unfold/js/app.js
CHANGED
@@ -78,9 +78,9 @@ const filterForm = () => {
|
|
78
78
|
}
|
79
79
|
|
80
80
|
filterForm.addEventListener("formdata", (event) => {
|
81
|
-
|
81
|
+
Array.from(event.formData.entries()).forEach(([key, value]) => {
|
82
82
|
if (value === "") event.formData.delete(key);
|
83
|
-
}
|
83
|
+
});
|
84
84
|
});
|
85
85
|
};
|
86
86
|
|
@@ -12,7 +12,7 @@
|
|
12
12
|
{% endfor %}
|
13
13
|
|
14
14
|
{% if spec|class_name == "BooleanFieldListFilter" %}
|
15
|
-
<ul class="
|
15
|
+
<ul class="dark:bg-base-900 border border-base-200 flex min-w-20 rounded shadow-sm text-font-default-light dark:border-base-700 dark:text-font-default-dark w-full">
|
16
16
|
{% for choice in choices %}
|
17
17
|
<li class="basis-1/3 border-r border-base-200 flex-grow truncate last:border-r-0 dark:border-base-700 {% if choice.selected %}font-semibold text-primary-600 dark:text-primary-500 {% else %}hover:text-base-700 dark:hover:text-base-200{% endif %}">
|
18
18
|
<a href="{{ choice.query_string|iriencode }}" title="{{ choice.display }}" class="block px-3 py-2 text-center hover:text-primary-600 dark:hover:text-primary-500">
|
@@ -10,8 +10,8 @@
|
|
10
10
|
{% preserve_filters %}
|
11
11
|
{% endif %}
|
12
12
|
|
13
|
-
<div class="flex flex-col grow gap-4 overflow-auto *:mb-0"
|
14
|
-
<div class="flex flex-col gap-4 {% if cl.model_admin.list_filter_sheet %}px-
|
13
|
+
<div class="flex flex-col grow gap-4 overflow-auto *:mb-0" data-simplebar data-simplebar-direction="rtl">
|
14
|
+
<div class="flex flex-col gap-4 mx-1 px-2 py-2.5 {% if not cl.model_admin.list_filter_sheet %} 2xl:px-0 2xl:py-0{% endif %} *:mb-0">
|
15
15
|
{% for spec in cl.filter_specs %}
|
16
16
|
{% admin_list_filter cl spec %}
|
17
17
|
{% endfor %}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% load i18n %}
|
2
2
|
|
3
|
-
<div class="
|
3
|
+
<div class="bg-white border-t border-base-200 p-3 py-2.5 dark:bg-base-800 dark:border-base-700{% if not cl.model_admin.list_filter_sheet %} 2xl:!border-t-0 2xl:!bg-transparent 2xl:px-0{% endif %}">
|
4
4
|
{% if cl.model_admin.list_filter_submit %}
|
5
5
|
<button type="submit" class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded text-white w-full">
|
6
6
|
{% trans "Apply Filters" %}
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
{% if show_back_button %}
|
4
4
|
{% if opts and adminform %}
|
5
|
-
{% url opts|admin_urlname:'changelist' as
|
5
|
+
{% url opts|admin_urlname:'changelist' as changelist_url %}
|
6
6
|
|
7
|
-
<a href="{
|
7
|
+
<a href="{% add_preserved_filters changelist_url %}" class="block h-4.5 mr-3" title="{% trans "Go back" %}">
|
8
8
|
<span class="material-symbols-outlined">
|
9
9
|
arrow_back
|
10
10
|
</span>
|
@@ -8,7 +8,13 @@
|
|
8
8
|
{% for item in tabs_list %}
|
9
9
|
{% if item.has_permission %}
|
10
10
|
<li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-base-800">
|
11
|
-
<a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}"
|
11
|
+
<a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}"
|
12
|
+
class="block px-3 py-2 md:py-4 md:px-0 dark:border-base-800 {% if item.active and not item.inline %} border-b font-semibold -mb-px text-primary-600 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-500 md:border-primary-500 dark:md:!border-primary-600{% else %}font-medium hover:text-primary-600 dark:hover:text-primary-500{% endif %}"
|
13
|
+
{% if item.inline %}
|
14
|
+
x-on:click="activeTab = '{{ item.inline }}'"
|
15
|
+
x-bind:class="{'border-b border-base-200 dark:border-base-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ item.inline }}'}"
|
16
|
+
{% endif %}
|
17
|
+
>
|
12
18
|
{{ item.title }}
|
13
19
|
</a>
|
14
20
|
</li>
|
@@ -59,7 +59,7 @@
|
|
59
59
|
{% endblock %}
|
60
60
|
</head>
|
61
61
|
|
62
|
-
<body class="antialiased bg-white font-sans text-font-default-light text-sm dark:bg-base-900 dark:text-font-default-dark {% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}" data-admin-utc-offset="{% now "Z" %}" x-data="{ mainWidth: 0, activeTab: 'general', sidebarMobileOpen: false, sidebarDesktopOpen: {% if request.session.toggle_sidebar == False %}false{% else %}true{% endif %} }" x-init="activeTab = window.location.hash?.replace('#', '') || 'general'">
|
62
|
+
<body class="antialiased bg-white font-sans text-font-default-light text-sm dark:bg-base-900 dark:text-font-default-dark {% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}" data-admin-utc-offset="{% now "Z" %}" x-data="{ mainWidth: 0, {% if opts %}activeTab: 'general',{% endif %} sidebarMobileOpen: false, sidebarDesktopOpen: {% if request.session.toggle_sidebar == False %}false{% else %}true{% endif %} }" x-init="activeTab = {% if opts %}window.location.hash?.replace('#', '') || 'general'{% else %}''{% endif %}">
|
63
63
|
{% if colors %}
|
64
64
|
<style id="unfold-theme-colors">
|
65
65
|
:root {
|
unfold/templatetags/unfold.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Mapping
|
2
|
+
from typing import Any, Optional, Union
|
2
3
|
|
3
4
|
from django import template
|
4
5
|
from django.contrib.admin.helpers import AdminForm, Fieldset
|
5
6
|
from django.contrib.admin.views.main import ChangeList
|
7
|
+
from django.db.models.options import Options
|
6
8
|
from django.forms import Field
|
7
9
|
from django.http import HttpRequest
|
8
10
|
from django.template import Context, Library, Node, RequestContext, TemplateSyntaxError
|
@@ -15,9 +17,44 @@ from unfold.components import ComponentRegistry
|
|
15
17
|
register = Library()
|
16
18
|
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
+
def _get_tabs_list(
|
21
|
+
context: RequestContext, page: str, opts: Optional[Options] = None
|
22
|
+
) -> list:
|
20
23
|
tabs_list = []
|
24
|
+
page_id = None
|
25
|
+
|
26
|
+
if page not in ["changeform", "changelist"]:
|
27
|
+
page_id = page
|
28
|
+
|
29
|
+
for tab in context.get("tab_list", []):
|
30
|
+
if page_id:
|
31
|
+
if tab.get("page") == page_id:
|
32
|
+
tabs_list = tab["items"]
|
33
|
+
break
|
34
|
+
|
35
|
+
continue
|
36
|
+
|
37
|
+
if "models" not in tab:
|
38
|
+
continue
|
39
|
+
|
40
|
+
for tab_model in tab["models"]:
|
41
|
+
if isinstance(tab_model, str):
|
42
|
+
if str(opts) == tab_model and page == "changelist":
|
43
|
+
tabs_list = tab["items"]
|
44
|
+
break
|
45
|
+
elif isinstance(tab_model, dict) and str(opts) == tab_model["name"]:
|
46
|
+
is_detail = tab_model.get("detail", False)
|
47
|
+
|
48
|
+
if (page == "changeform" and is_detail) or (
|
49
|
+
page == "changelist" and not is_detail
|
50
|
+
):
|
51
|
+
tabs_list = tab["items"]
|
52
|
+
break
|
53
|
+
return tabs_list
|
54
|
+
|
55
|
+
|
56
|
+
@register.simple_tag(name="tab_list", takes_context=True)
|
57
|
+
def tab_list(context: RequestContext, page: str, opts: Optional[Options] = None) -> str:
|
21
58
|
inlines_list = []
|
22
59
|
|
23
60
|
data = {
|
@@ -26,22 +63,18 @@ def tab_list(context, page, opts) -> str:
|
|
26
63
|
"actions_list": context.get("actions_list"),
|
27
64
|
"actions_items": context.get("actions_items"),
|
28
65
|
"is_popup": context.get("is_popup"),
|
66
|
+
"tabs_list": _get_tabs_list(context, page, opts),
|
29
67
|
}
|
30
68
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
data["tabs_list"] = tabs_list
|
38
|
-
|
39
|
-
for inline in context.get("inline_admin_formsets", []):
|
40
|
-
if hasattr(inline.opts, "tab"):
|
41
|
-
inlines_list.append(inline)
|
69
|
+
# If the changeform is rendered and there are no custom tab navigation
|
70
|
+
# specified, check for inlines to put into tabs
|
71
|
+
if page == "changeform" and len(data["tabs_list"]) == 0:
|
72
|
+
for inline in context.get("inline_admin_formsets", []):
|
73
|
+
if opts and hasattr(inline.opts, "tab"):
|
74
|
+
inlines_list.append(inline)
|
42
75
|
|
43
|
-
|
44
|
-
|
76
|
+
if len(inlines_list) > 0:
|
77
|
+
data["inlines_list"] = inlines_list
|
45
78
|
|
46
79
|
return render_to_string(
|
47
80
|
"unfold/helpers/tab_list.html",
|
@@ -70,7 +103,7 @@ def index(indexable: Mapping[int, Any], i: int) -> Any:
|
|
70
103
|
|
71
104
|
|
72
105
|
@register.filter
|
73
|
-
def tabs(adminform: AdminForm) ->
|
106
|
+
def tabs(adminform: AdminForm) -> list[Fieldset]:
|
74
107
|
result = []
|
75
108
|
|
76
109
|
for fieldset in adminform:
|
@@ -86,7 +119,7 @@ class CaptureNode(Node):
|
|
86
119
|
self.varname = varname
|
87
120
|
self.silent = silent
|
88
121
|
|
89
|
-
def render(self, context:
|
122
|
+
def render(self, context: dict[str, Any]) -> Union[str, SafeText]:
|
90
123
|
output = self.nodelist.render(context)
|
91
124
|
context[self.varname] = output
|
92
125
|
if self.silent:
|
@@ -155,7 +188,7 @@ class RenderComponentNode(template.Node):
|
|
155
188
|
self,
|
156
189
|
template_name: str,
|
157
190
|
nodelist: NodeList,
|
158
|
-
extra_context: Optional[
|
191
|
+
extra_context: Optional[dict] = None,
|
159
192
|
include_context: bool = False,
|
160
193
|
*args,
|
161
194
|
**kwargs,
|
@@ -252,7 +285,7 @@ def add_css_class(field: Field, classes: Union[list, tuple]) -> Field:
|
|
252
285
|
takes_context=True,
|
253
286
|
name="preserve_filters",
|
254
287
|
)
|
255
|
-
def preserve_changelist_filters(context: Context) ->
|
288
|
+
def preserve_changelist_filters(context: Context) -> dict[str, dict[str, str]]:
|
256
289
|
"""
|
257
290
|
Generate hidden input fields to preserve filters for POST forms.
|
258
291
|
"""
|
@@ -262,10 +295,10 @@ def preserve_changelist_filters(context: Context) -> Dict[str, Dict[str, str]]:
|
|
262
295
|
if not request or not changelist:
|
263
296
|
return {"params": {}}
|
264
297
|
|
265
|
-
used_params:
|
298
|
+
used_params: set[str] = {
|
266
299
|
param for spec in changelist.filter_specs for param in spec.used_parameters
|
267
300
|
}
|
268
|
-
preserved_params:
|
301
|
+
preserved_params: dict[str, str] = {
|
269
302
|
param: value for param, value in request.GET.items() if param not in used_params
|
270
303
|
}
|
271
304
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import datetime
|
2
|
-
from typing import Any,
|
2
|
+
from typing import Any, Optional, Union
|
3
3
|
|
4
4
|
from django.contrib.admin.templatetags.admin_list import (
|
5
5
|
ResultList,
|
@@ -355,7 +355,7 @@ def results(cl: ChangeList):
|
|
355
355
|
yield UnfoldResultList(pk_value, None, items_for_result(cl, res, None))
|
356
356
|
|
357
357
|
|
358
|
-
def result_list(context:
|
358
|
+
def result_list(context: dict[str, Any], cl: ChangeList) -> dict[str, Any]:
|
359
359
|
"""
|
360
360
|
Display the headers and data list together.
|
361
361
|
"""
|
unfold/typing.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
from
|
1
|
+
from collections.abc import Iterable
|
2
|
+
from typing import Any, Protocol, Union
|
2
3
|
|
3
4
|
|
4
5
|
class ActionFunction(Protocol):
|
@@ -11,13 +12,13 @@ class ActionFunction(Protocol):
|
|
11
12
|
allowed_permissions: Iterable[str]
|
12
13
|
short_description: str
|
13
14
|
url_path: str
|
14
|
-
attrs:
|
15
|
+
attrs: dict[str, Any]
|
15
16
|
|
16
17
|
def __call__(self, *args, **kwargs):
|
17
18
|
pass
|
18
19
|
|
19
20
|
|
20
21
|
FieldsetsType = Union[
|
21
|
-
|
22
|
-
|
22
|
+
list[tuple[Union[str, None], dict[str, Any]]],
|
23
|
+
tuple[tuple[Union[str, None], dict[str, Any]]],
|
23
24
|
]
|
unfold/utils.py
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
import datetime
|
2
2
|
import decimal
|
3
3
|
import json
|
4
|
-
from
|
4
|
+
from collections.abc import Iterable
|
5
|
+
from typing import Any, Optional
|
5
6
|
|
6
7
|
from django.conf import settings
|
7
8
|
from django.db import models
|
@@ -114,7 +115,7 @@ def display_for_field(value: Any, field: Any, empty_value_display: str) -> str:
|
|
114
115
|
return display_for_value(value, empty_value_display)
|
115
116
|
|
116
117
|
|
117
|
-
def hex_to_rgb(hex_color: str) ->
|
118
|
+
def hex_to_rgb(hex_color: str) -> list[int]:
|
118
119
|
hex_color = hex_color.lstrip("#")
|
119
120
|
|
120
121
|
r = int(hex_color[0:2], 16)
|
unfold/views.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Any
|
1
|
+
from typing import Any
|
2
2
|
|
3
3
|
from django.contrib.auth.mixins import PermissionRequiredMixin
|
4
4
|
|
@@ -16,7 +16,7 @@ class UnfoldModelAdminViewMixin(PermissionRequiredMixin):
|
|
16
16
|
self.model_admin = model_admin
|
17
17
|
super().__init__(**kwargs)
|
18
18
|
|
19
|
-
def get_context_data(self, **kwargs: Any) ->
|
19
|
+
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
20
20
|
if not hasattr(self, "model_admin"):
|
21
21
|
raise UnfoldException(
|
22
22
|
"UnfoldModelAdminViewMixin was not provided with 'model_admin' argument"
|
unfold/widgets.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Any, Callable,
|
1
|
+
from typing import Any, Callable, Optional, Union
|
2
2
|
|
3
3
|
from django.contrib.admin.options import VERTICAL
|
4
4
|
from django.contrib.admin.sites import AdminSite
|
@@ -255,7 +255,7 @@ SWITCH_CLASSES = [
|
|
255
255
|
|
256
256
|
|
257
257
|
class UnfoldAdminTextInputWidget(AdminTextInputWidget):
|
258
|
-
def __init__(self, attrs: Optional[
|
258
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
259
259
|
super().__init__(
|
260
260
|
attrs={
|
261
261
|
**(attrs or {}),
|
@@ -269,7 +269,7 @@ class UnfoldAdminTextInputWidget(AdminTextInputWidget):
|
|
269
269
|
class UnfoldAdminURLInputWidget(AdminURLFieldWidget):
|
270
270
|
template_name = "unfold/widgets/url.html"
|
271
271
|
|
272
|
-
def __init__(self, attrs: Optional[
|
272
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
273
273
|
super().__init__(
|
274
274
|
attrs={
|
275
275
|
**(attrs or {}),
|
@@ -281,7 +281,7 @@ class UnfoldAdminURLInputWidget(AdminURLFieldWidget):
|
|
281
281
|
|
282
282
|
|
283
283
|
class UnfoldAdminColorInputWidget(AdminTextInputWidget):
|
284
|
-
def __init__(self, attrs: Optional[
|
284
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
285
285
|
super().__init__(
|
286
286
|
attrs={
|
287
287
|
**(attrs or {}),
|
@@ -294,7 +294,7 @@ class UnfoldAdminColorInputWidget(AdminTextInputWidget):
|
|
294
294
|
|
295
295
|
|
296
296
|
class UnfoldAdminUUIDInputWidget(AdminUUIDInputWidget):
|
297
|
-
def __init__(self, attrs: Optional[
|
297
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
298
298
|
super().__init__(
|
299
299
|
attrs={
|
300
300
|
**(attrs or {}),
|
@@ -308,7 +308,7 @@ class UnfoldAdminUUIDInputWidget(AdminUUIDInputWidget):
|
|
308
308
|
class UnfoldAdminIntegerRangeWidget(MultiWidget):
|
309
309
|
template_name = "unfold/widgets/range.html"
|
310
310
|
|
311
|
-
def __init__(self, attrs: Optional[
|
311
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
312
312
|
if attrs is None:
|
313
313
|
attrs = {}
|
314
314
|
|
@@ -320,14 +320,14 @@ class UnfoldAdminIntegerRangeWidget(MultiWidget):
|
|
320
320
|
|
321
321
|
super().__init__(_widgets, attrs)
|
322
322
|
|
323
|
-
def decompress(self, value: Union[str, None]) ->
|
323
|
+
def decompress(self, value: Union[str, None]) -> tuple[Optional[Callable], ...]:
|
324
324
|
if value:
|
325
325
|
return value.lower, value.upper
|
326
326
|
return None, None
|
327
327
|
|
328
328
|
|
329
329
|
class UnfoldAdminEmailInputWidget(AdminEmailInputWidget):
|
330
|
-
def __init__(self, attrs: Optional[
|
330
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
331
331
|
super().__init__(
|
332
332
|
attrs={
|
333
333
|
**(attrs or {}),
|
@@ -374,7 +374,7 @@ class UnfoldAdminDateWidget(AdminDateWidget):
|
|
374
374
|
template_name = "unfold/widgets/date.html"
|
375
375
|
|
376
376
|
def __init__(
|
377
|
-
self, attrs: Optional[
|
377
|
+
self, attrs: Optional[dict[str, Any]] = None, format: Optional[str] = None
|
378
378
|
) -> None:
|
379
379
|
attrs = {
|
380
380
|
**(attrs or {}),
|
@@ -394,7 +394,7 @@ class UnfoldAdminSingleDateWidget(AdminDateWidget):
|
|
394
394
|
template_name = "unfold/widgets/date.html"
|
395
395
|
|
396
396
|
def __init__(
|
397
|
-
self, attrs: Optional[
|
397
|
+
self, attrs: Optional[dict[str, Any]] = None, format: Optional[str] = None
|
398
398
|
) -> None:
|
399
399
|
attrs = {
|
400
400
|
**(attrs or {}),
|
@@ -414,7 +414,7 @@ class UnfoldAdminTimeWidget(AdminTimeWidget):
|
|
414
414
|
template_name = "unfold/widgets/time.html"
|
415
415
|
|
416
416
|
def __init__(
|
417
|
-
self, attrs: Optional[
|
417
|
+
self, attrs: Optional[dict[str, Any]] = None, format: Optional[str] = None
|
418
418
|
) -> None:
|
419
419
|
attrs = {
|
420
420
|
**(attrs or {}),
|
@@ -434,7 +434,7 @@ class UnfoldAdminSingleTimeWidget(AdminTimeWidget):
|
|
434
434
|
template_name = "unfold/widgets/time.html"
|
435
435
|
|
436
436
|
def __init__(
|
437
|
-
self, attrs: Optional[
|
437
|
+
self, attrs: Optional[dict[str, Any]] = None, format: Optional[str] = None
|
438
438
|
) -> None:
|
439
439
|
attrs = {
|
440
440
|
**(attrs or {}),
|
@@ -453,7 +453,7 @@ class UnfoldAdminSingleTimeWidget(AdminTimeWidget):
|
|
453
453
|
class UnfoldAdminTextareaWidget(AdminTextareaWidget):
|
454
454
|
template_name = "unfold/widgets/textarea.html"
|
455
455
|
|
456
|
-
def __init__(self, attrs: Optional[
|
456
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
457
457
|
attrs = attrs or {}
|
458
458
|
|
459
459
|
super().__init__(
|
@@ -473,7 +473,7 @@ class UnfoldAdminTextareaWidget(AdminTextareaWidget):
|
|
473
473
|
class UnfoldAdminExpandableTextareaWidget(AdminTextareaWidget):
|
474
474
|
template_name = "unfold/widgets/textarea_expandable.html"
|
475
475
|
|
476
|
-
def __init__(self, attrs: Optional[
|
476
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
477
477
|
attrs = attrs or {}
|
478
478
|
|
479
479
|
attrs.update({"rows": 2})
|
@@ -496,7 +496,7 @@ class UnfoldAdminExpandableTextareaWidget(AdminTextareaWidget):
|
|
496
496
|
class UnfoldAdminSplitDateTimeWidget(AdminSplitDateTime):
|
497
497
|
template_name = "unfold/widgets/split_datetime.html"
|
498
498
|
|
499
|
-
def __init__(self, attrs: Optional[
|
499
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
500
500
|
widgets = [UnfoldAdminDateWidget, UnfoldAdminTimeWidget]
|
501
501
|
MultiWidget.__init__(self, widgets, attrs)
|
502
502
|
|
@@ -506,9 +506,9 @@ class UnfoldAdminSplitDateTimeVerticalWidget(AdminSplitDateTime):
|
|
506
506
|
|
507
507
|
def __init__(
|
508
508
|
self,
|
509
|
-
attrs: Optional[
|
510
|
-
date_attrs: Optional[
|
511
|
-
time_attrs: Optional[
|
509
|
+
attrs: Optional[dict[str, Any]] = None,
|
510
|
+
date_attrs: Optional[dict[str, Any]] = None,
|
511
|
+
time_attrs: Optional[dict[str, Any]] = None,
|
512
512
|
date_label: Optional[str] = None,
|
513
513
|
time_label: Optional[str] = None,
|
514
514
|
) -> None:
|
@@ -522,8 +522,8 @@ class UnfoldAdminSplitDateTimeVerticalWidget(AdminSplitDateTime):
|
|
522
522
|
MultiWidget.__init__(self, widgets, attrs)
|
523
523
|
|
524
524
|
def get_context(
|
525
|
-
self, name: str, value: Any, attrs: Optional[
|
526
|
-
) ->
|
525
|
+
self, name: str, value: Any, attrs: Optional[dict[str, Any]]
|
526
|
+
) -> dict[str, Any]:
|
527
527
|
context = super().get_context(name, value, attrs)
|
528
528
|
|
529
529
|
if self.date_label is not None:
|
@@ -540,7 +540,7 @@ class UnfoldAdminSplitDateTimeVerticalWidget(AdminSplitDateTime):
|
|
540
540
|
|
541
541
|
|
542
542
|
class UnfoldAdminIntegerFieldWidget(AdminIntegerFieldWidget):
|
543
|
-
def __init__(self, attrs: Optional[
|
543
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
544
544
|
super().__init__(
|
545
545
|
attrs={
|
546
546
|
**(attrs or {}),
|
@@ -552,7 +552,7 @@ class UnfoldAdminIntegerFieldWidget(AdminIntegerFieldWidget):
|
|
552
552
|
|
553
553
|
|
554
554
|
class UnfoldAdminDecimalFieldWidget(AdminIntegerFieldWidget):
|
555
|
-
def __init__(self, attrs: Optional[
|
555
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
556
556
|
super().__init__(
|
557
557
|
attrs={
|
558
558
|
**(attrs or {}),
|
@@ -564,7 +564,7 @@ class UnfoldAdminDecimalFieldWidget(AdminIntegerFieldWidget):
|
|
564
564
|
|
565
565
|
|
566
566
|
class UnfoldAdminBigIntegerFieldWidget(AdminBigIntegerFieldWidget):
|
567
|
-
def __init__(self, attrs: Optional[
|
567
|
+
def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
|
568
568
|
super().__init__(
|
569
569
|
attrs={
|
570
570
|
**(attrs or {}),
|
@@ -621,7 +621,7 @@ class UnfoldAdminRadioSelectWidget(AdminRadioSelect):
|
|
621
621
|
self.radio_style = radio_style
|
622
622
|
self.attrs["class"] = " ".join([*RADIO_CLASSES, self.attrs.get("class", "")])
|
623
623
|
|
624
|
-
def get_context(self, *args, **kwargs) ->
|
624
|
+
def get_context(self, *args, **kwargs) -> dict[str, Any]:
|
625
625
|
context = super().get_context(*args, **kwargs)
|
626
626
|
context.update({"radio_style": self.radio_style})
|
627
627
|
return context
|
@@ -666,7 +666,7 @@ except ImportError:
|
|
666
666
|
|
667
667
|
class UnfoldBooleanWidget(CheckboxInput):
|
668
668
|
def __init__(
|
669
|
-
self, attrs: Optional[
|
669
|
+
self, attrs: Optional[dict[str, Any]] = None, check_test: Callable = None
|
670
670
|
) -> None:
|
671
671
|
if attrs is None:
|
672
672
|
attrs = {}
|
@@ -684,7 +684,7 @@ class UnfoldBooleanWidget(CheckboxInput):
|
|
684
684
|
|
685
685
|
class UnfoldBooleanSwitchWidget(CheckboxInput):
|
686
686
|
def __init__(
|
687
|
-
self, attrs: Optional[
|
687
|
+
self, attrs: Optional[dict[str, Any]] = None, check_test: Callable = None
|
688
688
|
) -> None:
|
689
689
|
super().__init__(
|
690
690
|
attrs={
|
@@ -708,7 +708,7 @@ class UnfoldForeignKeyRawIdWidget(ForeignKeyRawIdWidget):
|
|
708
708
|
self,
|
709
709
|
rel: ForeignObjectRel,
|
710
710
|
admin_site: AdminSite,
|
711
|
-
attrs: Optional[
|
711
|
+
attrs: Optional[dict] = None,
|
712
712
|
using: Optional[Any] = None,
|
713
713
|
) -> None:
|
714
714
|
attrs = {
|
File without changes
|