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
djgentelella/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.3.
|
|
1
|
+
__version__ = '0.3.20'
|
djgentelella/blog/forms.py
CHANGED
|
@@ -2,12 +2,12 @@ from django import forms
|
|
|
2
2
|
from markitup.widgets import MarkItUpWidget
|
|
3
3
|
from rest_framework.reverse import reverse_lazy
|
|
4
4
|
|
|
5
|
-
from djgentelella.forms.forms import
|
|
5
|
+
from djgentelella.forms.forms import GTForm
|
|
6
6
|
from djgentelella.widgets import core as genwidgets
|
|
7
7
|
from . import models
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
class EntryForm(
|
|
10
|
+
class EntryForm(GTForm, forms.ModelForm):
|
|
11
11
|
class Meta:
|
|
12
12
|
model = models.Entry
|
|
13
13
|
exclude = ('published_content', 'author')
|
|
@@ -22,7 +22,7 @@ class EntryForm(CustomForm, forms.ModelForm):
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class CategoryForm(
|
|
25
|
+
class CategoryForm(GTForm, forms.ModelForm):
|
|
26
26
|
class Meta:
|
|
27
27
|
model = models.Category
|
|
28
28
|
fields = '__all__'
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from django.core.files.base import ContentFile
|
|
6
|
+
from django.utils.text import slugify
|
|
7
|
+
from django.utils.translation import gettext_lazy as _
|
|
8
|
+
from rest_framework import serializers
|
|
9
|
+
|
|
10
|
+
from djgentelella.models import ChunkedUpload
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GTBase64FileField(serializers.FileField):
|
|
14
|
+
def __init__(self, *args, max_files=1, delete_if_empty=False,
|
|
15
|
+
allow_empty_file=False, **kwargs):
|
|
16
|
+
self.max_files = max_files
|
|
17
|
+
self.delete_if_empty = delete_if_empty
|
|
18
|
+
self.allow_empty_file = allow_empty_file
|
|
19
|
+
super().__init__(*args, **kwargs)
|
|
20
|
+
|
|
21
|
+
def to_internal_value(self, datalist):
|
|
22
|
+
result = []
|
|
23
|
+
if not isinstance(datalist, list):
|
|
24
|
+
raise serializers.ValidationError(
|
|
25
|
+
_("A list of elements is expected, ej: [{name: 'name of file', value:'base64 string representation'}]"))
|
|
26
|
+
if len(datalist) > self.max_files:
|
|
27
|
+
raise serializers.ValidationError(
|
|
28
|
+
_(f"Too many elements, max_file = {self.max_files}"))
|
|
29
|
+
|
|
30
|
+
for data in datalist:
|
|
31
|
+
required_fields = ["name", "value"]
|
|
32
|
+
for field in required_fields:
|
|
33
|
+
if field not in data:
|
|
34
|
+
raise serializers.ValidationError(
|
|
35
|
+
_("Invalid structure you need to provide {name: 'name of file', value:'base64 string representation'}"))
|
|
36
|
+
name = slugify(Path(data["name"]).stem)
|
|
37
|
+
suffix = Path(data["name"]).suffix
|
|
38
|
+
file_name = name + suffix
|
|
39
|
+
file_value = data["value"]
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
# Decodificar el contenido en base64
|
|
43
|
+
decoded_value = base64.b64decode(file_value)
|
|
44
|
+
except base64.binascii.Error:
|
|
45
|
+
self.fail('invalid')
|
|
46
|
+
# raise serializers.ValidationError(_(
|
|
47
|
+
# "The 'value' is not a valid base64 string"))
|
|
48
|
+
|
|
49
|
+
file_content = ContentFile(decoded_value, name=file_name)
|
|
50
|
+
result.append(file_content)
|
|
51
|
+
if result:
|
|
52
|
+
if self.max_files == 1:
|
|
53
|
+
return result[0]
|
|
54
|
+
|
|
55
|
+
return result
|
|
56
|
+
# here check for field of the instance
|
|
57
|
+
if not self.delete_if_empty and self.root.instance:
|
|
58
|
+
if hasattr(self.root.instance, self.source):
|
|
59
|
+
return getattr(self.root.instance, self.source)
|
|
60
|
+
if not self.allow_empty_file:
|
|
61
|
+
self.fail('required')
|
|
62
|
+
|
|
63
|
+
def to_representation(self, value):
|
|
64
|
+
data = super().to_representation(value)
|
|
65
|
+
if data and value.name and value.storage.exists(value.name):
|
|
66
|
+
name = Path(value.name).name
|
|
67
|
+
return {'name': name, 'url': data}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class ChunkedFileField(serializers.FileField):
|
|
71
|
+
|
|
72
|
+
def parse_value(self, value):
|
|
73
|
+
"""
|
|
74
|
+
Parses the given value and returns the parsed result.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
value (str): The value to be parsed.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
The parsed result if the value is valid and contains the required attributes,
|
|
81
|
+
one of url, token, or actions otherwise returns None.
|
|
82
|
+
"""
|
|
83
|
+
dev = None
|
|
84
|
+
try:
|
|
85
|
+
dev = json.loads(value)
|
|
86
|
+
if not ('url' in dev or 'token' in dev or 'actions' in dev):
|
|
87
|
+
dev = None
|
|
88
|
+
except Exception as e:
|
|
89
|
+
pass
|
|
90
|
+
return dev
|
|
91
|
+
|
|
92
|
+
def to_internal_value(self, data):
|
|
93
|
+
"""
|
|
94
|
+
Converts the given data to internal value representation.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
data (str): The data to be converted.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
The internal value representation of the data, or None if the data is invalid
|
|
101
|
+
or does not contain the required attributes.
|
|
102
|
+
"""
|
|
103
|
+
token = self.parse_value(data)
|
|
104
|
+
dev = None
|
|
105
|
+
if token:
|
|
106
|
+
if 'actions' in token and token['actions'] == 'delete':
|
|
107
|
+
return False
|
|
108
|
+
if 'token' in token:
|
|
109
|
+
tmpupload = ChunkedUpload.objects.filter(
|
|
110
|
+
upload_id=token['token']).first()
|
|
111
|
+
if tmpupload:
|
|
112
|
+
dev = tmpupload.get_uploaded_file()
|
|
113
|
+
# tmpupload.delete()
|
|
114
|
+
|
|
115
|
+
else:
|
|
116
|
+
if self.root.instance:
|
|
117
|
+
if hasattr(self.root.instance, self.source):
|
|
118
|
+
return getattr(self.root.instance, self.source)
|
|
119
|
+
return dev
|
|
120
|
+
|
|
121
|
+
def to_representation(self, value):
|
|
122
|
+
data = super().to_representation(value)
|
|
123
|
+
if data and value.name and value.storage.exists(value.name):
|
|
124
|
+
name = Path(value.name).name
|
|
125
|
+
return {'name': value.name, 'url': data, 'display_name': name}
|
djgentelella/forms/decorators.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from djgentelella.fields import tree
|
|
2
|
-
from djgentelella.forms.forms import
|
|
2
|
+
from djgentelella.forms.forms import GTForm
|
|
3
3
|
from djgentelella.widgets import core
|
|
4
4
|
from djgentelella.widgets import trees
|
|
5
5
|
|
|
@@ -55,8 +55,8 @@ def decore_form_instance(form_instance, exclude=()):
|
|
|
55
55
|
widget = get_field_widget(form_instance.fields[field])
|
|
56
56
|
if widget:
|
|
57
57
|
form_instance.fields[field].widget = widget
|
|
58
|
-
for method in
|
|
58
|
+
for method in GTForm.exposed_method:
|
|
59
59
|
setattr(form_instance, method,
|
|
60
|
-
_form_instance(getattr(
|
|
60
|
+
_form_instance(getattr(GTForm, method), form_instance))
|
|
61
61
|
form_instance.is_customized = True
|
|
62
62
|
return form_instance
|
djgentelella/forms/forms.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from django import forms
|
|
2
|
-
# "'<tr%(html_class_attr)s><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>'"
|
|
3
2
|
from django.forms import BaseFormSet, HiddenInput
|
|
4
3
|
from django.forms import BaseModelFormSet
|
|
5
4
|
from django.forms.formsets import DELETION_FIELD_NAME
|
|
@@ -8,46 +7,162 @@ from django.utils.safestring import mark_safe
|
|
|
8
7
|
|
|
9
8
|
class GTForm(forms.Form):
|
|
10
9
|
"""
|
|
11
|
-
|
|
10
|
+
GTForm is the basis of form management, it does the work of django `forms.Form`, including enhancements and boostrap rendering, so it should be inherited from this form, rather than `forms.Form`.
|
|
11
|
+
|
|
12
|
+
Example of use:
|
|
13
|
+
|
|
14
|
+
.. code:: python
|
|
15
|
+
|
|
16
|
+
from djgentelella.forms.forms import GTForm
|
|
17
|
+
class MyForm(GTForm):
|
|
18
|
+
myfield = forms.TextField()
|
|
19
|
+
|
|
20
|
+
Using with forms.ModelForm
|
|
21
|
+
|
|
22
|
+
.. code:: python
|
|
23
|
+
|
|
24
|
+
from djgentelella.forms.forms import GTForm
|
|
25
|
+
class MyForm(GTForm, forms.ModelForm):
|
|
26
|
+
myfield = forms.TextField()
|
|
27
|
+
class Meta:
|
|
28
|
+
model = MyModel
|
|
29
|
+
|
|
30
|
+
Creating an instance and specify how render it.
|
|
31
|
+
|
|
32
|
+
.. code:: python
|
|
33
|
+
|
|
34
|
+
myform = myGTForm(render_type='as_inline', ... )
|
|
35
|
+
|
|
12
36
|
"""
|
|
13
37
|
exposed_method = ('as_plain', 'as_inline', 'as_horizontal')
|
|
38
|
+
default_render_type = None
|
|
39
|
+
template_name_plain = 'forms/as_plain.html'
|
|
40
|
+
template_name_inline = 'forms/as_inline.html'
|
|
41
|
+
template_name_horizontal = 'forms/as_horizontal.html'
|
|
42
|
+
template_name_grid = 'forms/as_grid.html'
|
|
43
|
+
grid_representation = None
|
|
44
|
+
|
|
45
|
+
def __init__(self, *args, **kwargs):
|
|
46
|
+
render_type = self.default_render_type if self.default_render_type is not None else 'as_horizontal'
|
|
47
|
+
if 'render_type' in kwargs and hasattr(self, kwargs['render_type']):
|
|
48
|
+
render_type = kwargs.pop('render_type')
|
|
49
|
+
|
|
50
|
+
super().__init__(*args, **kwargs)
|
|
51
|
+
|
|
52
|
+
match render_type:
|
|
53
|
+
case 'as_table':
|
|
54
|
+
self.renderer.form_template_name = self.template_name_table
|
|
55
|
+
case 'as_ul':
|
|
56
|
+
self.renderer.form_template_name = self.template_name_ul
|
|
57
|
+
case 'as_p':
|
|
58
|
+
self.renderer.form_template_name = self.template_name_p
|
|
59
|
+
case 'as_div':
|
|
60
|
+
self.renderer.form_template_name = self.template_name_div
|
|
61
|
+
case 'as_horizontal':
|
|
62
|
+
self.renderer.form_template_name = self.template_name_horizontal
|
|
63
|
+
case 'as_inline':
|
|
64
|
+
self.renderer.form_template_name = self.template_name_inline
|
|
65
|
+
case 'as_plain':
|
|
66
|
+
self.renderer.form_template_name = self.template_name_plain
|
|
67
|
+
case 'as_grid':
|
|
68
|
+
self.renderer.form_template_name = self.template_name_grid
|
|
69
|
+
case _:
|
|
70
|
+
self.renderer.form_template_name = self.template_name_horizontal
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def grid(self):
|
|
74
|
+
"""
|
|
75
|
+
Example of return structure:
|
|
76
|
+
|
|
77
|
+
.. code:: python
|
|
78
|
+
|
|
79
|
+
[
|
|
80
|
+
[ [forms.Field],[], [] ],
|
|
81
|
+
[ [], [] ],
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
fields = []
|
|
86
|
+
dic_fields = {}
|
|
87
|
+
for name, bf in self._bound_items():
|
|
88
|
+
if not bf.is_hidden:
|
|
89
|
+
fields.append(bf)
|
|
90
|
+
dic_fields[name] = bf
|
|
91
|
+
|
|
92
|
+
if self.grid_representation is not None:
|
|
93
|
+
grid = [] # self.grid_representation
|
|
94
|
+
for row in self.grid_representation:
|
|
95
|
+
col_list = []
|
|
96
|
+
for col in row:
|
|
97
|
+
row_list = []
|
|
98
|
+
for field in col:
|
|
99
|
+
if field in dic_fields and dic_fields[field]:
|
|
100
|
+
row_list.append(dic_fields[field])
|
|
101
|
+
else:
|
|
102
|
+
if hasattr(self, field):
|
|
103
|
+
row_list.append(getattr(self, field)())
|
|
104
|
+
col_list.append(row_list)
|
|
105
|
+
grid.append(col_list)
|
|
106
|
+
return grid
|
|
107
|
+
return [[fields]]
|
|
14
108
|
|
|
15
109
|
def as_plain(self):
|
|
16
|
-
"Returns this form rendered as HTML
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
110
|
+
"Returns this form rendered as HTML using as_plain bootstrap approach."
|
|
111
|
+
if hasattr(self, '_html_output'):
|
|
112
|
+
return self._html_output(
|
|
113
|
+
normal_row='<div class="as_plain"><div %(html_class_attr)s ' +
|
|
114
|
+
'>%(label)s%(errors)s%(field)s%(help_text)s</div></div>',
|
|
115
|
+
error_row='%s',
|
|
116
|
+
row_ender=' ',
|
|
117
|
+
help_text_html='<br /><span class="helptext">%s</span>',
|
|
118
|
+
errors_on_separate_row=False)
|
|
119
|
+
return self.render(self.template_name_plain)
|
|
25
120
|
|
|
26
121
|
def as_inline(self):
|
|
27
|
-
"Return this form rendered as HTML
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
122
|
+
"Return this form rendered as HTML using as_inline bootstrap approach."
|
|
123
|
+
if hasattr(self, '_html_output'):
|
|
124
|
+
return self._html_output(
|
|
125
|
+
normal_row='<div class="mb-4"><span class="">%(label)s</span>' +
|
|
126
|
+
' %(errors)s%(field)s%(help_text)s</div>',
|
|
127
|
+
error_row='%s',
|
|
128
|
+
row_ender='</div>',
|
|
129
|
+
help_text_html=' <span class="helptext">%s</span>',
|
|
130
|
+
errors_on_separate_row=False,
|
|
131
|
+
)
|
|
132
|
+
return self.render(self.template_name_inline)
|
|
36
133
|
|
|
37
134
|
def as_horizontal(self):
|
|
38
|
-
"Return this form rendered as HTML
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
135
|
+
"Return this form rendered as HTML using as_horizontal bootstrap approach."
|
|
136
|
+
if hasattr(self, '_html_output'):
|
|
137
|
+
return self._html_output(
|
|
138
|
+
normal_row='<div class="form-group row"><span class="col-sm-3">' +
|
|
139
|
+
'%(label)s</span> <div class="col-sm-9 " ' +
|
|
140
|
+
'>%(errors)s%(field)s%(help_text)s</div></div>',
|
|
141
|
+
error_row='%s',
|
|
142
|
+
row_ender='</div>',
|
|
143
|
+
help_text_html=' <span class="helptext">%s</span>',
|
|
144
|
+
errors_on_separate_row=False,
|
|
145
|
+
)
|
|
146
|
+
return self.render(self.template_name_horizontal)
|
|
147
|
+
|
|
148
|
+
def as_grid(self):
|
|
149
|
+
"""
|
|
150
|
+
Allow you to arrange the form fields in rows and cols,
|
|
151
|
+
When you use this render needs to fill `grid_representation` attribute in your form
|
|
152
|
+
Return this form rendered as HTML using grid bootstrap approach.,
|
|
153
|
+
|
|
154
|
+
.. code:: python
|
|
155
|
+
|
|
156
|
+
grid_representation=[
|
|
157
|
+
[ ['key'],[], [] ],
|
|
158
|
+
[ [], [] ],
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
"""
|
|
162
|
+
return self.render(self.template_name_grid)
|
|
163
|
+
|
|
164
|
+
def closediv(self):
|
|
165
|
+
return "</div>"
|
|
51
166
|
|
|
52
167
|
|
|
53
168
|
class BaseFormset:
|
|
@@ -65,6 +180,11 @@ class BaseFormset:
|
|
|
65
180
|
|
|
66
181
|
|
|
67
182
|
class GTFormSet(BaseFormSet, BaseFormset):
|
|
183
|
+
"""
|
|
184
|
+
This class Allow to manage FormSet using GTForm and Widgets,
|
|
185
|
+
provide an implementation to integrate with django formset system.
|
|
186
|
+
"""
|
|
187
|
+
|
|
68
188
|
ordering_widget = HiddenInput
|
|
69
189
|
|
|
70
190
|
def add_fields(self, form, index):
|
djgentelella/forms/models.py
CHANGED
|
@@ -2,10 +2,10 @@ from django import forms
|
|
|
2
2
|
|
|
3
3
|
from djgentelella.models import Help
|
|
4
4
|
from djgentelella.widgets import core as genwidgets
|
|
5
|
-
from .forms import
|
|
5
|
+
from .forms import GTForm
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class HelpForm(
|
|
8
|
+
class HelpForm(GTForm, forms.ModelForm):
|
|
9
9
|
class Meta:
|
|
10
10
|
model = Help
|
|
11
11
|
fields = ['help_title', 'help_text']
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class GTS2SerializerBase(serializers.Serializer):
|
|
5
|
+
id_field = 'pk'
|
|
6
|
+
display_fields = '__str__'
|
|
7
|
+
default_selected = True
|
|
8
|
+
default_disable = False
|
|
9
|
+
|
|
10
|
+
def get_id(self, obj):
|
|
11
|
+
return getattr(obj, self.id_field)
|
|
12
|
+
|
|
13
|
+
def get_text(self, obj):
|
|
14
|
+
if isinstance(self.display_fields, str):
|
|
15
|
+
if self.display_fields == '__str__':
|
|
16
|
+
return str(obj)
|
|
17
|
+
return getattr(obj, self.display_fields)
|
|
18
|
+
if isinstance(self.display_fields, (list, tuple)):
|
|
19
|
+
lwords = [getattr(obj, key) for key in self.display_fields]
|
|
20
|
+
return " ".join(lwords)
|
|
21
|
+
return repr(obj)
|
|
22
|
+
|
|
23
|
+
def get_selected(self, obj):
|
|
24
|
+
return self.default_selected
|
|
25
|
+
|
|
26
|
+
def get_disabled(self, obj):
|
|
27
|
+
return self.default_disable
|
|
28
|
+
|
|
29
|
+
id = serializers.SerializerMethodField()
|
|
30
|
+
text = serializers.SerializerMethodField()
|
|
31
|
+
disabled = serializers.SerializerMethodField()
|
|
32
|
+
selected = serializers.SerializerMethodField()
|
djgentelella/settings.py
CHANGED
|
@@ -44,7 +44,7 @@ except Exception as e:
|
|
|
44
44
|
from django.contrib.auth.models import User
|
|
45
45
|
|
|
46
46
|
#####################################################
|
|
47
|
-
#
|
|
47
|
+
# Chunked Upload
|
|
48
48
|
############################################
|
|
49
49
|
|
|
50
50
|
# How long after creation the upload will expire
|