djgentelella 0.3.18__py3-none-any.whl → 0.3.20__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.
- djgentelella/__init__.py +1 -1
- djgentelella/blog/forms.py +3 -3
- djgentelella/fields/files.py +125 -0
- djgentelella/forms/decorators.py +3 -3
- djgentelella/forms/forms.py +153 -33
- djgentelella/forms/models.py +2 -2
- djgentelella/serializers/selects.py +32 -0
- djgentelella/settings.py +1 -1
- djgentelella/static/djgentelella.flags.vendors.min.css +1 -1
- djgentelella/static/djgentelella.readonly.vendors.min.js +1 -1
- djgentelella/static/djgentelella.vendors.header.min.js +1 -1
- djgentelella/static/djgentelella.vendors.min.js +3 -2
- djgentelella/static/gentelella/css/custom.css +42 -2
- djgentelella/static/gentelella/js/base/dateranges_gridslider.js +1 -2
- djgentelella/static/gentelella/js/base/fileupload.widget.js +175 -72
- djgentelella/static/gentelella/js/base.js +178 -75
- djgentelella/static/gentelella/js/datatables.js +20 -3
- djgentelella/static/gentelella/js/obj_api_management.js +150 -51
- djgentelella/static/gentelella/js/widgets.js +2 -1
- djgentelella/static/vendors/flags/1x1/cp.svg +2 -2
- djgentelella/static/vendors/flags/1x1/dg.svg +2 -2
- djgentelella/static/vendors/flags/1x1/es-ga.svg +2 -2
- djgentelella/static/vendors/flags/4x3/ac.svg +2 -2
- djgentelella/static/vendors/flags/4x3/ea.svg +2 -2
- djgentelella/static/vendors/flags/4x3/es-ct.svg +2 -2
- djgentelella/static/vendors/friconix/friconix.js +1 -1
- djgentelella/static/vendors/interact/interact.min.js +3 -2
- djgentelella/static/vendors/storymapjs/storymap.js +1 -1
- djgentelella/templates/forms/as_grid.html +39 -0
- djgentelella/templates/forms/as_horizontal.html +36 -0
- djgentelella/templates/forms/as_inline.html +38 -0
- djgentelella/templates/forms/as_plain.html +33 -0
- djgentelella/templates/gentelella/index.html +14 -14
- djgentelella/templates/gentelella/widgets/chunkedupload.html +9 -14
- djgentelella/templates/gentelella/widgets/file.html +4 -9
- djgentelella/tests/__init__.py +2 -1
- djgentelella/tests/fields/__init__.py +0 -0
- djgentelella/tests/fields/files.py +39 -0
- djgentelella/views/select2autocomplete.py +8 -2
- djgentelella/widgets/core.py +33 -0
- djgentelella/widgets/files.py +37 -8
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/METADATA +30 -15
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/RECORD +47 -39
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/WHEEL +1 -1
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/AUTHORS +0 -0
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/LICENSE.txt +0 -0
- {djgentelella-0.3.18.dist-info → djgentelella-0.3.20.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{% if errors %}
|
|
2
|
+
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
|
3
|
+
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
|
|
4
|
+
<use xlink:href="#exclamation-triangle-fill"/>
|
|
5
|
+
</svg>
|
|
6
|
+
<div>
|
|
7
|
+
{{ errors }}
|
|
8
|
+
{% if not fields %}
|
|
9
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% for column in form.grid %}
|
|
16
|
+
<div class="row">{% for row in column %}
|
|
17
|
+
<div class="col">{% for field in row %}
|
|
18
|
+
<div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}" {% else %} class="mb-3" {% endif %}
|
|
19
|
+
{% endwith %}>
|
|
20
|
+
{{ errors }}
|
|
21
|
+
{% if field.label %}{{ field.label_tag }}{% endif %}
|
|
22
|
+
{{ field }}
|
|
23
|
+
{% if field.help_text %}
|
|
24
|
+
<div class="feedback text-info" {% if field.auto_id %} id="{{ field.auto_id }}_helptext" {% endif %}>
|
|
25
|
+
{{ field.help_text|safe }}
|
|
26
|
+
</div>
|
|
27
|
+
{% endif %}
|
|
28
|
+
</div>
|
|
29
|
+
{% endfor %}
|
|
30
|
+
</div>
|
|
31
|
+
{% endfor %}
|
|
32
|
+
{% if forloop.last %}
|
|
33
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
34
|
+
{% endif %}
|
|
35
|
+
</div>{% endfor %}
|
|
36
|
+
|
|
37
|
+
{% if not fields and not errors %}
|
|
38
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
39
|
+
{% endif %}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{% if errors %}
|
|
2
|
+
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
|
3
|
+
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
|
|
4
|
+
<use xlink:href="#exclamation-triangle-fill"/>
|
|
5
|
+
</svg>
|
|
6
|
+
<div>
|
|
7
|
+
{{ errors }}
|
|
8
|
+
{% if not fields %}
|
|
9
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% for field, errors in fields %}
|
|
16
|
+
<div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}" {% else %}class="row form-group mb-3"
|
|
17
|
+
{% endif %}{% endwith %}>
|
|
18
|
+
{{ errors }}
|
|
19
|
+
{% if field.label %}<label for="{{ field.id_for_label }}" class="col-sm-2 col-form-label">{{ field.label }} </label>
|
|
20
|
+
{% endif %}
|
|
21
|
+
<div class="col-sm-10">
|
|
22
|
+
{{ field }}
|
|
23
|
+
{% if field.help_text %}
|
|
24
|
+
<div class="valid-feedback" {% if field.auto_id %} id="{{ field.auto_id }}_helptext" {% endif %}>
|
|
25
|
+
{{ field.help_text|safe }}
|
|
26
|
+
</div>
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% if forloop.last %}
|
|
29
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
30
|
+
{% endif %}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
{% endfor %}
|
|
34
|
+
{% if not fields and not errors %}
|
|
35
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
36
|
+
{% endif %}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{% if errors %}
|
|
2
|
+
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
|
3
|
+
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
|
|
4
|
+
<use xlink:href="#exclamation-triangle-fill"/>
|
|
5
|
+
</svg>
|
|
6
|
+
<div>
|
|
7
|
+
{{ errors }}
|
|
8
|
+
{% if not fields %}
|
|
9
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
<div class="row">
|
|
16
|
+
{% for field, errors in fields %}
|
|
17
|
+
<div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}" {% else %}class="col"
|
|
18
|
+
{% endif %}{% endwith %}>
|
|
19
|
+
{{ errors }}
|
|
20
|
+
{% if field.label %}{{ field.label_tag }}{% endif %}
|
|
21
|
+
|
|
22
|
+
{{ field }}
|
|
23
|
+
{% if field.help_text %}
|
|
24
|
+
{% if forloop.last %}
|
|
25
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
26
|
+
{% endif %}
|
|
27
|
+
|
|
28
|
+
<div class="feedback text-info" {% if field.auto_id %} id="{{ field.auto_id }}_helptext" {% endif %}>
|
|
29
|
+
{{ field.help_text|safe }}
|
|
30
|
+
</div>
|
|
31
|
+
{% endif %}
|
|
32
|
+
|
|
33
|
+
</div>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
{% if not fields and not errors %}
|
|
36
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
37
|
+
{% endif %}
|
|
38
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{% if errors %}
|
|
2
|
+
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
|
3
|
+
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Warning:">
|
|
4
|
+
<use xlink:href="#exclamation-triangle-fill"/>
|
|
5
|
+
</svg>
|
|
6
|
+
<div>
|
|
7
|
+
{{ errors }}
|
|
8
|
+
{% if not fields %}
|
|
9
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{% endif %}
|
|
15
|
+
{% for field, errors in fields %}
|
|
16
|
+
<div {% with classes=field.css_classes %}{% if classes %} class="{{ classes }}" {% else %}class="col-12"
|
|
17
|
+
{% endif %}{% endwith %}>
|
|
18
|
+
{{ errors }}
|
|
19
|
+
{% if field.label %}{{ field.label_tag }}{% endif %}
|
|
20
|
+
{{ field }}
|
|
21
|
+
{% if field.help_text %}
|
|
22
|
+
<div class="valid-feedback" {% if field.auto_id %} id="{{ field.auto_id }}_helptext" {% endif %}>
|
|
23
|
+
{{ field.help_text|safe }}
|
|
24
|
+
</div>
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if forloop.last %}
|
|
27
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
28
|
+
{% endif %}
|
|
29
|
+
</div>
|
|
30
|
+
{% endfor %}
|
|
31
|
+
{% if not fields and not errors %}
|
|
32
|
+
{% for field in hidden_fields %}{{ field }}{% endfor %}
|
|
33
|
+
{% endif %}
|
|
@@ -11,22 +11,22 @@
|
|
|
11
11
|
{% endblock%}
|
|
12
12
|
<div class="row">
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
<div class='col-sm-12 col-md-12 col-lg-12'>
|
|
15
|
+
<div class="card">
|
|
16
|
+
<div class="card-body">
|
|
17
|
+
<div class="card-title titles">
|
|
18
|
+
<h2> A form </h2>
|
|
19
|
+
</div>
|
|
20
|
+
<form action="" method="POST" enctype="multipart/form-data">
|
|
21
|
+
{% csrf_token %}
|
|
22
|
+
{{form}}
|
|
23
|
+
<input class="btn btn-success" type="submit" value="Save"/>
|
|
24
|
+
</form>
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
</div>
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
30
|
</div>
|
|
31
31
|
{% endblock %}
|
|
32
32
|
{% block js %} {{ form.media }} {% endblock %}
|
|
@@ -6,24 +6,19 @@
|
|
|
6
6
|
<input class="chunkedupload-input" style="" type="{{ widget.type }}" data-inputtoken="{{ widget.name }}" data-process=".{{ widget.name }}_progress" data-message=".{{ widget.name }}_messages" name="{{ widget.name }}_widget" {% include "gentelella/widgets/attrs.html" %}>
|
|
7
7
|
</div>
|
|
8
8
|
<div class="form-control {{ widget.name }}_messages" style="display:none;"></div>
|
|
9
|
-
<input type="hidden" name="{{ widget.name }}" value=""
|
|
9
|
+
<input class="chunkedvalue" type="hidden" name="{{ widget.name }}" value='{{widget.value}}' autocomplete="off"/>
|
|
10
10
|
<div class="input-group-text fileshow" ><i class="fa fa-eye"></i></div>
|
|
11
|
-
{% if widget.value %}
|
|
12
|
-
|
|
13
|
-
<a href="{{widget.value.url}}" target="_blank"><i class="fa fa-download text-light"></i></a>
|
|
11
|
+
<div id="download_{{ widget.name }}" class="input-group-text bg-danger" {% if not widget.value %}style="display:none;"{% endif %} >
|
|
12
|
+
<a href="" target="_blank"><i class="fa fa-download text-light"></i></a>
|
|
14
13
|
</div>
|
|
15
|
-
{% endif %}
|
|
16
14
|
</div>
|
|
17
|
-
|
|
18
|
-
{% if widget.value and not widget.required %}
|
|
19
|
-
<div class="checkbox">
|
|
15
|
+
<div id="remove_{{ widget.name }}" class="checkbox">
|
|
20
16
|
<label class="">
|
|
21
|
-
<div class="icheckbox_flat-green
|
|
22
|
-
<input type="checkbox" autocomplete="off" data-widget="CheckboxInput" class="flat" style="position: absolute; opacity: 0;">
|
|
17
|
+
<div class="icheckbox_flat-green" style="position: relative;">
|
|
18
|
+
<input id="id_remove_{{ widget.name }}" type="checkbox" autocomplete="off" data-widget="CheckboxInput" name="remove_{{ widget.name }}_gt" class="flat" style="position: absolute; opacity: 0;">
|
|
23
19
|
<ins class="iCheck-helper" ></ins></div>
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
{% trans 'Delete this file' %}
|
|
26
21
|
</label>
|
|
27
22
|
</div>
|
|
28
|
-
|
|
29
|
-
</div>
|
|
23
|
+
|
|
24
|
+
</div>
|
|
@@ -7,24 +7,19 @@
|
|
|
7
7
|
<input type="{{ widget.type }}" data-inputtoken="{{ widget.name }}" data-process=".{{ widget.name }}_progress" data-message=".{{ widget.name }}_messages" name="{{ widget.name }}_widget" {% include "gentelella/widgets/attrs.html" %}>
|
|
8
8
|
</div>
|
|
9
9
|
<div class="form-control {{ widget.name }}_messages" style="display:none;"></div>
|
|
10
|
-
|
|
10
|
+
<input type="hidden" name="{{ widget.name }}" value="{{ widget.value }}" />
|
|
11
11
|
<div class="input-group-text fileshow" ><i class="fa fa-eye"></i></div>
|
|
12
|
-
{% if widget.value %}
|
|
13
12
|
<div id="download_{{ widget.name }}" class="input-group-text bg-danger" >
|
|
14
|
-
<a href="
|
|
13
|
+
<a href="" target="_blank"><i class="fa fa-download text-light"></i></a>
|
|
15
14
|
</div>
|
|
16
|
-
{% endif %}
|
|
17
15
|
</div>
|
|
18
|
-
|
|
19
|
-
{% if widget.value and not widget.required %}
|
|
20
|
-
<div class="checkbox">
|
|
16
|
+
<div id="check_{{ widget.name }}" class="checkbox">
|
|
21
17
|
<label class="">
|
|
22
|
-
<div class="icheckbox_flat-green
|
|
18
|
+
<div class="icheckbox_flat-green " style="position: relative;">
|
|
23
19
|
<input type="checkbox" autocomplete="off" data-widget="CheckboxInput" class="flat" style="position: absolute; opacity: 0;">
|
|
24
20
|
<ins class="iCheck-helper" ></ins></div>
|
|
25
21
|
{% trans 'Delete this file' %}
|
|
26
22
|
|
|
27
23
|
</label>
|
|
28
24
|
</div>
|
|
29
|
-
{% endif %}
|
|
30
25
|
</div>
|
djgentelella/tests/__init__.py
CHANGED
|
File without changes
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
from django.core.files.base import ContentFile
|
|
4
|
+
from django.test import TestCase
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
from djgentelella.fields.files import GTBase64FileField
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class GTBase64FileFieldTestCase(TestCase):
|
|
11
|
+
def test_to_internal_value_with_valid_data(self):
|
|
12
|
+
field = GTBase64FileField()
|
|
13
|
+
data = {
|
|
14
|
+
"name": "test.txt",
|
|
15
|
+
"value": base64.b64encode(b"Test content").decode("utf-8"),
|
|
16
|
+
}
|
|
17
|
+
expected_content = ContentFile(b"Test content")
|
|
18
|
+
|
|
19
|
+
result = field.to_internal_value(data)
|
|
20
|
+
|
|
21
|
+
self.assertEqual(result.read(), expected_content.read())
|
|
22
|
+
self.assertEqual(result.name, expected_content.name)
|
|
23
|
+
|
|
24
|
+
def test_to_internal_value_with_missing_fields(self):
|
|
25
|
+
field = GTBase64FileField()
|
|
26
|
+
data = {"name": "test.txt"}
|
|
27
|
+
|
|
28
|
+
with self.assertRaises(serializers.ValidationError):
|
|
29
|
+
field.to_internal_value(data)
|
|
30
|
+
|
|
31
|
+
def test_to_internal_value_with_invalid_base64(self):
|
|
32
|
+
field = GTBase64FileField()
|
|
33
|
+
data = {
|
|
34
|
+
"name": "test.txt",
|
|
35
|
+
"value": "invalid_base64",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
with self.assertRaises(serializers.ValidationError):
|
|
39
|
+
field.to_internal_value(data)
|
|
@@ -71,14 +71,20 @@ class BaseSelect2View(generics.ListAPIView, viewsets.GenericViewSet):
|
|
|
71
71
|
text_wrapper = ''
|
|
72
72
|
order_by = 'pk'
|
|
73
73
|
|
|
74
|
+
def get_filter_suffix(self, fieldname):
|
|
75
|
+
if hasattr(self, f'get_filter_suffix_{fieldname}'):
|
|
76
|
+
return getattr(self, f'get_filter_suffix_{fieldname}')()
|
|
77
|
+
return '__icontains'
|
|
78
|
+
|
|
74
79
|
def filter_data(self, queryset, qe):
|
|
75
80
|
filters = None
|
|
76
81
|
for field in self.fields:
|
|
82
|
+
suffix = self.get_filter_suffix(field)
|
|
77
83
|
for q in qe:
|
|
78
84
|
if filters is None:
|
|
79
|
-
filters = Q(**{field +
|
|
85
|
+
filters = Q(**{field + suffix: q})
|
|
80
86
|
else:
|
|
81
|
-
filters |= Q(**{field +
|
|
87
|
+
filters |= Q(**{field + suffix: q})
|
|
82
88
|
return queryset.filter(filters)
|
|
83
89
|
|
|
84
90
|
def query_get(self, name, default, aslist=False):
|
djgentelella/widgets/core.py
CHANGED
|
@@ -18,6 +18,8 @@ from django.urls import reverse_lazy
|
|
|
18
18
|
from django.utils import formats
|
|
19
19
|
from django.utils.translation import gettext as _
|
|
20
20
|
|
|
21
|
+
from djgentelella.models import ChunkedUpload
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
def update_kwargs(attrs, widget, base_class='form-control '):
|
|
23
25
|
if attrs is not None:
|
|
@@ -117,6 +119,21 @@ class NumberInput(Input):
|
|
|
117
119
|
super().__init__(attrs, extraskwargs=extraskwargs)
|
|
118
120
|
|
|
119
121
|
|
|
122
|
+
class FloatInput(Input):
|
|
123
|
+
input_type = 'number'
|
|
124
|
+
template_name = 'gentelella/widgets/number.html'
|
|
125
|
+
|
|
126
|
+
# min_value y max_value
|
|
127
|
+
|
|
128
|
+
def __init__(self, attrs=None, extraskwargs=True):
|
|
129
|
+
if extraskwargs:
|
|
130
|
+
attrs = update_kwargs(attrs, self.__class__.__name__)
|
|
131
|
+
if 'step' not in attrs:
|
|
132
|
+
attrs['step'] = "0.1"
|
|
133
|
+
attrs['inputmode'] = "decimal"
|
|
134
|
+
super().__init__(attrs, extraskwargs=extraskwargs)
|
|
135
|
+
|
|
136
|
+
|
|
120
137
|
class EmailInput(Input):
|
|
121
138
|
input_type = 'email'
|
|
122
139
|
template_name = 'gentelella/widgets/email.html'
|
|
@@ -168,6 +185,22 @@ class FileInput(DJFileInput):
|
|
|
168
185
|
attrs['data-done'] = reverse_lazy('upload_file_done')
|
|
169
186
|
super().__init__(attrs)
|
|
170
187
|
|
|
188
|
+
def format_value(self, value):
|
|
189
|
+
"""File input never renders a value."""
|
|
190
|
+
return
|
|
191
|
+
|
|
192
|
+
def value_from_datadict(self, data, files, name):
|
|
193
|
+
dev = None
|
|
194
|
+
token = data.get(name)
|
|
195
|
+
tmpupload = ChunkedUpload.objects.filter(upload_id=token).first()
|
|
196
|
+
if tmpupload:
|
|
197
|
+
dev = tmpupload.get_uploaded_file()
|
|
198
|
+
tmpupload.delete()
|
|
199
|
+
return dev
|
|
200
|
+
|
|
201
|
+
def value_omitted_from_data(self, data, files, name):
|
|
202
|
+
return name not in data
|
|
203
|
+
|
|
171
204
|
|
|
172
205
|
class ImageRecordInput(DJFileInput):
|
|
173
206
|
"""
|
djgentelella/widgets/files.py
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from logging import getLogger
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
1
5
|
from django.forms import FileInput
|
|
2
6
|
from django.urls import reverse_lazy
|
|
7
|
+
from django.utils.safestring import mark_safe
|
|
3
8
|
|
|
4
9
|
from djgentelella.models import ChunkedUpload
|
|
5
10
|
from djgentelella.widgets.core import update_kwargs
|
|
6
11
|
|
|
12
|
+
logger = getLogger('djgentelella')
|
|
13
|
+
|
|
7
14
|
|
|
8
15
|
class FileChunkedUpload(FileInput):
|
|
9
16
|
input_type = 'file'
|
|
@@ -22,17 +29,39 @@ class FileChunkedUpload(FileInput):
|
|
|
22
29
|
|
|
23
30
|
def format_value(self, value):
|
|
24
31
|
"""File input never renders a value."""
|
|
25
|
-
|
|
32
|
+
if value:
|
|
33
|
+
name = Path(value.name).name
|
|
34
|
+
self.value = mark_safe(
|
|
35
|
+
'{"name": "%(name)s", "display_name": "%(display_name)s", "url": "%(url)s" }' % {
|
|
36
|
+
'name': value.name,
|
|
37
|
+
'display_name': name,
|
|
38
|
+
'url': value.url})
|
|
39
|
+
return self.value
|
|
40
|
+
return ''
|
|
41
|
+
|
|
42
|
+
def parse_value(self, value):
|
|
43
|
+
dev = None
|
|
44
|
+
try:
|
|
45
|
+
dev = json.loads(value)
|
|
46
|
+
if not ('url' in dev or 'token' in dev or 'actions' in dev):
|
|
47
|
+
dev = None
|
|
48
|
+
except json.JSONDecodeError as e:
|
|
49
|
+
logger.warning("Json error parsing: " + repr(value))
|
|
50
|
+
return dev
|
|
26
51
|
|
|
27
52
|
def value_from_datadict(self, data, files, name):
|
|
28
53
|
dev = None
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
54
|
+
|
|
55
|
+
token = self.parse_value(data.get(name))
|
|
56
|
+
if token:
|
|
57
|
+
if 'actions' in token and token['actions'] == 'delete':
|
|
58
|
+
return False
|
|
59
|
+
if 'token' in token:
|
|
60
|
+
tmpupload = ChunkedUpload.objects.filter(
|
|
61
|
+
upload_id=token['token']).first()
|
|
62
|
+
if tmpupload:
|
|
63
|
+
dev = tmpupload.get_uploaded_file()
|
|
64
|
+
tmpupload.delete()
|
|
36
65
|
return dev
|
|
37
66
|
|
|
38
67
|
def value_omitted_from_data(self, data, files, name):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: djgentelella
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.20
|
|
4
4
|
Summary: Help building extra widgets for forms and speciall methods to render forms in templates
|
|
5
5
|
Home-page: https://solvosoft.com
|
|
6
6
|
Author: Luis Zarate Montero
|
|
@@ -376,39 +376,54 @@ Requires-Python: >=3.8
|
|
|
376
376
|
Description-Content-Type: text/x-rst
|
|
377
377
|
License-File: LICENSE.txt
|
|
378
378
|
License-File: AUTHORS
|
|
379
|
-
Requires-Dist: django-tree-queries
|
|
380
|
-
Requires-Dist: djangoajax
|
|
381
|
-
Requires-Dist: django-markitup
|
|
379
|
+
Requires-Dist: django-tree-queries >=0.11.0
|
|
380
|
+
Requires-Dist: djangoajax >=3.3
|
|
381
|
+
Requires-Dist: django-markitup >=4.0.0
|
|
382
382
|
Requires-Dist: markdown
|
|
383
383
|
Requires-Dist: Pillow
|
|
384
|
-
Requires-Dist: djangorestframework
|
|
385
|
-
Requires-Dist: django
|
|
386
|
-
Requires-Dist: django-filter
|
|
384
|
+
Requires-Dist: djangorestframework >=3.13
|
|
385
|
+
Requires-Dist: django >=3.2
|
|
386
|
+
Requires-Dist: django-filter >=22.1
|
|
387
387
|
Provides-Extra: dev
|
|
388
388
|
Requires-Dist: pylp ; extra == 'dev'
|
|
389
389
|
Requires-Dist: pylpconcat ; extra == 'dev'
|
|
390
390
|
Requires-Dist: css-html-js-minify ; extra == 'dev'
|
|
391
391
|
Provides-Extra: test
|
|
392
|
-
Requires-Dist: selenium
|
|
393
|
-
Requires-Dist: selenium-screenshot
|
|
392
|
+
Requires-Dist: selenium ==4.5.0 ; extra == 'test'
|
|
393
|
+
Requires-Dist: selenium-screenshot ==2.0.0 ; extra == 'test'
|
|
394
394
|
|
|
395
395
|
Django Gentelella widgets
|
|
396
396
|
############################
|
|
397
397
|
|
|
398
|
+
.. image:: https://img.shields.io/readthedocs/django-gentelella-widgets?label=Read%20the%20Docs&logo=read%20the%20docs&logoColor=white
|
|
399
|
+
:alt: Gentelella documentation
|
|
400
|
+
|
|
401
|
+
.. image:: https://img.shields.io/pypi/pyversions/django
|
|
402
|
+
:alt: Gentelella supported python version
|
|
403
|
+
|
|
404
|
+
.. image:: https://github.com/Solvosoft/django-gentelella-widgets/actions/workflows/django.yml/badge.svg
|
|
405
|
+
:alt: Gentelella test status
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
This application is a set of utilities that will make developing applications with django and bootstrap 5 easier, as it provides a set of Javascript libraries such as select2, icheck, datatables and more nicely integrated as widgets or utilities that simplify application creation.
|
|
410
|
+
|
|
398
411
|
This app helps you to integrate Django apps with `Gentelella <https://colorlib.com/polygon/gentelella/index.html>`_ building extra widgets for forms and speciall methods to render forms in templates.
|
|
399
412
|
|
|
400
|
-
|
|
413
|
+
.. image:: docs/source/_static/readme/logo.png
|
|
414
|
+
:width: 200
|
|
415
|
+
:alt: Gentelella Logo
|
|
401
416
|
|
|
402
|
-
|
|
417
|
+
Documentation
|
|
403
418
|
________________
|
|
404
419
|
|
|
405
|
-
|
|
420
|
+
See `Documentation <https://django-gentelella-widgets.readthedocs.io/>`_
|
|
406
421
|
|
|
407
|
-
|
|
422
|
+
Installation
|
|
423
|
+
________________
|
|
408
424
|
|
|
409
|
-
|
|
425
|
+
Installing from pypi
|
|
410
426
|
|
|
411
|
-
An stable version on pip, but not all available widget are in this release (new release comming soon)
|
|
412
427
|
|
|
413
428
|
.. code:: bash
|
|
414
429
|
|