dynamicforms 0.76.14__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.
- dynamicforms/__init__.py +8 -0
- dynamicforms/action.py +521 -0
- dynamicforms/apps.py +5 -0
- dynamicforms/fields.py +1570 -0
- dynamicforms/filters.py +44 -0
- dynamicforms/locale/en/LC_MESSAGES/django.po +67 -0
- dynamicforms/locale/en/LC_MESSAGES/djangojs.po +31 -0
- dynamicforms/locale/sl/LC_MESSAGES/django.po +71 -0
- dynamicforms/locale/sl/LC_MESSAGES/djangojs.po +36 -0
- dynamicforms/management/__init__.py +0 -0
- dynamicforms/management/commands/__init__.py +0 -0
- dynamicforms/management/commands/clean_dfpreuploaded_files.py +26 -0
- dynamicforms/migrations/__init__.py +0 -0
- dynamicforms/mixins/__init__.py +27 -0
- dynamicforms/mixins/action.py +14 -0
- dynamicforms/mixins/choice/__init__.py +94 -0
- dynamicforms/mixins/choice/allow_tags.py +79 -0
- dynamicforms/mixins/choice/null_choice.py +26 -0
- dynamicforms/mixins/choice/single_choice.py +21 -0
- dynamicforms/mixins/color_field.py +4 -0
- dynamicforms/mixins/conditional_visibility.py +193 -0
- dynamicforms/mixins/enable_copy.py +4 -0
- dynamicforms/mixins/field_render.py +209 -0
- dynamicforms/mixins/file_field.py +5 -0
- dynamicforms/mixins/help_text.py +46 -0
- dynamicforms/mixins/implicit_hidden.py +7 -0
- dynamicforms/mixins/implicit_natural_date.py +88 -0
- dynamicforms/mixins/null_value.py +15 -0
- dynamicforms/mixins/password_field.py +23 -0
- dynamicforms/mixins/related_field_ajax.py +142 -0
- dynamicforms/mixins/rtf_field.py +58 -0
- dynamicforms/models.py +5 -0
- dynamicforms/models_utils.py +33 -0
- dynamicforms/pagination.py +175 -0
- dynamicforms/preupload_files.py +42 -0
- dynamicforms/progress.py +71 -0
- dynamicforms/renderers.py +1 -0
- dynamicforms/routers.py +36 -0
- dynamicforms/serializers.py +486 -0
- dynamicforms/struct.py +40 -0
- dynamicforms/template_render/__init__.py +10 -0
- dynamicforms/template_render/layout.py +178 -0
- dynamicforms/template_render/mixins/__init__.py +0 -0
- dynamicforms/template_render/mixins/base.py +39 -0
- dynamicforms/template_render/mixins/field.py +74 -0
- dynamicforms/template_render/mixins/listserializer.py +100 -0
- dynamicforms/template_render/mixins/render_mode_enum.py +8 -0
- dynamicforms/template_render/mixins/serializer.py +301 -0
- dynamicforms/template_render/mixins/serializer_filter.py +19 -0
- dynamicforms/template_render/mixins/serializer_render_actions.py +21 -0
- dynamicforms/template_render/mixins/serializer_render_fields.py +57 -0
- dynamicforms/template_render/mixins/util.py +9 -0
- dynamicforms/template_render/renderer.py +38 -0
- dynamicforms/template_render/responsive_table_layout.py +64 -0
- dynamicforms/urls.py +9 -0
- dynamicforms/utils.py +32 -0
- dynamicforms/views.py +1 -0
- dynamicforms/viewsets.py +421 -0
- dynamicforms-0.76.14.dist-info/METADATA +129 -0
- dynamicforms-0.76.14.dist-info/RECORD +287 -0
- dynamicforms-0.76.14.dist-info/WHEEL +4 -0
- dynamicforms-0.76.14.dist-info/licenses/LICENSE +21 -0
- dynamicforms_legacy/__init__.py +8 -0
- dynamicforms_legacy/action.py +561 -0
- dynamicforms_legacy/apps.py +5 -0
- dynamicforms_legacy/context_processors.py +27 -0
- dynamicforms_legacy/dynamicforms_migration_mixin.py +42 -0
- dynamicforms_legacy/fields.py +1108 -0
- dynamicforms_legacy/filters.py +44 -0
- dynamicforms_legacy/migrations/__init__.py +0 -0
- dynamicforms_legacy/mixins/__init__.py +16 -0
- dynamicforms_legacy/mixins/action.py +14 -0
- dynamicforms_legacy/mixins/allow_tags.py +85 -0
- dynamicforms_legacy/mixins/enable_copy.py +4 -0
- dynamicforms_legacy/mixins/file_field.py +5 -0
- dynamicforms_legacy/mixins/help_text.py +38 -0
- dynamicforms_legacy/mixins/implicit_hidden.py +7 -0
- dynamicforms_legacy/mixins/implicit_natural_date.py +86 -0
- dynamicforms_legacy/mixins/null_choice.py +26 -0
- dynamicforms_legacy/mixins/null_value.py +15 -0
- dynamicforms_legacy/mixins/password_field.py +19 -0
- dynamicforms_legacy/mixins/related_field_ajax.py +58 -0
- dynamicforms_legacy/mixins/render.py +203 -0
- dynamicforms_legacy/mixins/rtf_field.py +52 -0
- dynamicforms_legacy/mixins/single_choice.py +21 -0
- dynamicforms_legacy/models.py +5 -0
- dynamicforms_legacy/pagination.py +168 -0
- dynamicforms_legacy/progress.py +71 -0
- dynamicforms_legacy/renderers.py +183 -0
- dynamicforms_legacy/serializers.py +335 -0
- dynamicforms_legacy/settings.py +196 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +587 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css +6834 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.eot +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.svg +288 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.js +2580 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.min.js +6 -0
- dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/npm.js +13 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css +3719 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css +331 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css +8 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css +10038 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js +7013 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js +4435 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js.map +1 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js +7 -0
- dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js.map +1 -0
- dynamicforms_legacy/static/ckeditor-df/ckEditorCustomBuildReadMe.txt +255 -0
- dynamicforms_legacy/static/ckeditor-df/ckeditor.js +6 -0
- dynamicforms_legacy/static/dynamicforms/dynamicforms.js +1883 -0
- dynamicforms_legacy/static/dynamicforms/icons/copy.svg +7 -0
- dynamicforms_legacy/static/dynamicforms/icons/eye-off-outline.svg +10 -0
- dynamicforms_legacy/static/dynamicforms/icons/eye-outline.svg +7 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_222222_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_228ef1_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ef8c08_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffd27a_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffffff_256x240.png +0 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.min.css +7 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.structure.min.css +5 -0
- dynamicforms_legacy/static/jquery_ui/css/jquery-ui.theme.min.css +5 -0
- dynamicforms_legacy/static/jquery_ui/js/jquery-3.3.1.min.js +2 -0
- dynamicforms_legacy/static/jquery_ui/js/jquery-ui.min.js +13 -0
- dynamicforms_legacy/static/select2/css/select2-bootstrap3.min.css +7 -0
- dynamicforms_legacy/static/select2/css/select2-bootstrap4.min.css +578 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/css/select2.min.css +1 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/af.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ar.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/az.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bg.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bs.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ca.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/cs.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/da.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/de.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/dsb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/el.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/en.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/es.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/et.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/eu.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fa.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/gl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/he.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hsb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hu.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hy.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/id.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/is.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/it.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ja.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/km.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ko.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lt.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lv.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/mk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ms.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nb.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ps.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt-BR.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ro.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ru.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr-Cyrl.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sv.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/th.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/tr.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/uk.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/vi.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-CN.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-TW.js +3 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.js +6457 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.min.js +1 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.js +5746 -0
- dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.min.js +1 -0
- dynamicforms_legacy/struct.py +40 -0
- dynamicforms_legacy/templates/dynamicforms/base.html +12 -0
- dynamicforms_legacy/templates/dynamicforms/base_form.html +44 -0
- dynamicforms_legacy/templates/dynamicforms/base_includes.html +51 -0
- dynamicforms_legacy/templates/dynamicforms/base_includes_select2.html +6 -0
- dynamicforms_legacy/templates/dynamicforms/base_list.html +47 -0
- dynamicforms_legacy/templates/dynamicforms/base_table_body.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/base_table_filter.html +44 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_form.html +10 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v3.html +90 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v4.html +77 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_list.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_body.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_filter.html +5 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field.html +41 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v3.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v4.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox_multiple.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/fieldset.html +21 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/form.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/input.html +31 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/list_fieldset.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/radio.html +8 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/rtf_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select.html +46 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select_multiple.html +17 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/field/textarea.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog_rest.html +23 -0
- dynamicforms_legacy/templates/dynamicforms/bootstrap/page.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/field/base_field.html +55 -0
- dynamicforms_legacy/templates/dynamicforms/field/checkbox.html +28 -0
- dynamicforms_legacy/templates/dynamicforms/field/checkbox_multiple.html +16 -0
- dynamicforms_legacy/templates/dynamicforms/field/dict_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/fieldset.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/form.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/field/input.html +31 -0
- dynamicforms_legacy/templates/dynamicforms/field/list_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/list_fieldset.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/field/radio.html +24 -0
- dynamicforms_legacy/templates/dynamicforms/field/rtf_field.html +14 -0
- dynamicforms_legacy/templates/dynamicforms/field/select.html +97 -0
- dynamicforms_legacy/templates/dynamicforms/field/select_multiple.html +67 -0
- dynamicforms_legacy/templates/dynamicforms/field/textarea.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_form.html +13 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_includes.html +225 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_list.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_body.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_filter.html +5 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/base_field.html +16 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox.html +7 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox_multiple.html +9 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/fieldset.html +11 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/form.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/input.html +17 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/list_fieldset.html +6 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/radio.html +8 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/rtf_field.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select.html +37 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select_multiple.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/textarea.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog.html +2 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog_rest.html +27 -0
- dynamicforms_legacy/templates/dynamicforms/jquery_ui/page.html +20 -0
- dynamicforms_legacy/templates/dynamicforms/modal_dialog.html +4 -0
- dynamicforms_legacy/templates/dynamicforms/modal_dialog_rest.html +18 -0
- dynamicforms_legacy/templates/dynamicforms/page.html +25 -0
- dynamicforms_legacy/templates/dynamicforms/rtf_field_style.html +41 -0
- dynamicforms_legacy/templatetags/__init__.py +0 -0
- dynamicforms_legacy/templatetags/dynamicforms.py +475 -0
- dynamicforms_legacy/urls.py +8 -0
- dynamicforms_legacy/views.py +1 -0
- dynamicforms_legacy/viewsets.py +366 -0
dynamicforms/filters.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import django_filters.rest_framework as filters
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ListWithFields(list):
|
|
5
|
+
def __init__(self, fields, lst) -> None:
|
|
6
|
+
super().__init__()
|
|
7
|
+
self.fields = fields
|
|
8
|
+
self.extend(lst)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FilterBackend(filters.DjangoFilterBackend):
|
|
12
|
+
"""
|
|
13
|
+
Our own FilterBackend that also tries to read order from the pagination class's ordering field
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def get_filterset_class(self, view, queryset=None):
|
|
17
|
+
# here we look for any pagination class and its ordering attribute. if there is none, we sort by id
|
|
18
|
+
__paginator_ordering = getattr(getattr(view, "pagination_class", 0), "ordering", ["id"])
|
|
19
|
+
if isinstance(__paginator_ordering, str):
|
|
20
|
+
__paginator_ordering = [__paginator_ordering]
|
|
21
|
+
|
|
22
|
+
ordering_excluded_fields = getattr(view, "filterset_ordering_exclude", [])
|
|
23
|
+
ordering_default = getattr(view, "filterset_ordering_default", __paginator_ordering)
|
|
24
|
+
|
|
25
|
+
class MyOrderingFilter(filters.OrderingFilter):
|
|
26
|
+
def get_ordering(self, value):
|
|
27
|
+
if not value:
|
|
28
|
+
return ListWithFields(list(self.param_map.keys()), ordering_default)
|
|
29
|
+
return ListWithFields(list(self.param_map.keys()), [self.get_ordering_value(param) for param in value])
|
|
30
|
+
|
|
31
|
+
class FilterSetApplied(filters.FilterSet):
|
|
32
|
+
locals()[view.ordering_parameter] = MyOrderingFilter(
|
|
33
|
+
fields=[f.name for f in queryset.model._meta.fields if f.name not in ordering_excluded_fields]
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return FilterSetApplied
|
|
37
|
+
|
|
38
|
+
def get_ordering(self, request, queryset, view):
|
|
39
|
+
filterset = self.get_filterset(request, queryset, view)
|
|
40
|
+
filterset.is_valid()
|
|
41
|
+
ordering_filters = {k: v for k, v in filterset.filters.items() if isinstance(v, filters.OrderingFilter)}
|
|
42
|
+
for name, value in filterset.form.cleaned_data.items():
|
|
43
|
+
if name in ordering_filters:
|
|
44
|
+
return ordering_filters[name].get_ordering(value)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2024-02-27 08:03+0000\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"Language: \n"
|
|
16
|
+
"MIME-Version: 1.0\n"
|
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
19
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
20
|
+
|
|
21
|
+
#: dynamicforms/action.py:287
|
|
22
|
+
msgid "Cancel"
|
|
23
|
+
msgstr ""
|
|
24
|
+
|
|
25
|
+
#: dynamicforms/action.py:288
|
|
26
|
+
msgid "Save changes"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#: dynamicforms/action.py:359
|
|
30
|
+
msgid "Add"
|
|
31
|
+
msgstr ""
|
|
32
|
+
|
|
33
|
+
#: dynamicforms/action.py:359
|
|
34
|
+
msgid "Add new record"
|
|
35
|
+
msgstr ""
|
|
36
|
+
|
|
37
|
+
#: dynamicforms/action.py:364
|
|
38
|
+
msgid "Edit"
|
|
39
|
+
msgstr ""
|
|
40
|
+
|
|
41
|
+
#: dynamicforms/action.py:364
|
|
42
|
+
msgid "Edit record"
|
|
43
|
+
msgstr ""
|
|
44
|
+
|
|
45
|
+
#: dynamicforms/action.py:370
|
|
46
|
+
msgid "Delete"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#: dynamicforms/action.py:371
|
|
50
|
+
msgid "Delete record"
|
|
51
|
+
msgstr ""
|
|
52
|
+
|
|
53
|
+
#: dynamicforms/action.py:376
|
|
54
|
+
msgid "Sort"
|
|
55
|
+
msgstr ""
|
|
56
|
+
|
|
57
|
+
#: dynamicforms/action.py:376
|
|
58
|
+
msgid "Sort by column"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#: dynamicforms/action.py:380
|
|
62
|
+
msgid "Filter"
|
|
63
|
+
msgstr ""
|
|
64
|
+
|
|
65
|
+
#: dynamicforms/template_render/mixins/serializer_render_fields.py:34
|
|
66
|
+
msgid "Actions"
|
|
67
|
+
msgstr ""
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2023-07-20 13:48+0000\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"Language: \n"
|
|
16
|
+
"MIME-Version: 1.0\n"
|
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
19
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
20
|
+
|
|
21
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:8
|
|
22
|
+
msgid "Ok"
|
|
23
|
+
msgstr ""
|
|
24
|
+
|
|
25
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:8
|
|
26
|
+
msgid "Cancel"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:48
|
|
30
|
+
msgid "No data"
|
|
31
|
+
msgstr ""
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2024-02-27 08:03+0000\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"Language: \n"
|
|
16
|
+
"MIME-Version: 1.0\n"
|
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
19
|
+
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
|
|
20
|
+
"n%100==4 ? 2 : 3);\n"
|
|
21
|
+
|
|
22
|
+
#: dynamicforms/action.py:287
|
|
23
|
+
msgid "Cancel"
|
|
24
|
+
msgstr "Prekliči"
|
|
25
|
+
|
|
26
|
+
#: dynamicforms/action.py:288
|
|
27
|
+
msgid "Save changes"
|
|
28
|
+
msgstr "Shrani"
|
|
29
|
+
|
|
30
|
+
#: dynamicforms/action.py:359
|
|
31
|
+
msgid "Add"
|
|
32
|
+
msgstr "Dodaj"
|
|
33
|
+
|
|
34
|
+
#: dynamicforms/action.py:359
|
|
35
|
+
msgid "Add new record"
|
|
36
|
+
msgstr "Dodaj nov zapis"
|
|
37
|
+
|
|
38
|
+
#: dynamicforms/action.py:364
|
|
39
|
+
msgid "Edit"
|
|
40
|
+
msgstr "Uredi"
|
|
41
|
+
|
|
42
|
+
#: dynamicforms/action.py:364
|
|
43
|
+
msgid "Edit record"
|
|
44
|
+
msgstr "Uredi zapis"
|
|
45
|
+
|
|
46
|
+
#: dynamicforms/action.py:370
|
|
47
|
+
msgid "Delete"
|
|
48
|
+
msgstr "Briši"
|
|
49
|
+
|
|
50
|
+
#: dynamicforms/action.py:371
|
|
51
|
+
msgid "Delete record"
|
|
52
|
+
msgstr "Briši zapis"
|
|
53
|
+
|
|
54
|
+
#: dynamicforms/action.py:376
|
|
55
|
+
msgid "Sort"
|
|
56
|
+
msgstr "Sortiraj"
|
|
57
|
+
|
|
58
|
+
#: dynamicforms/action.py:376
|
|
59
|
+
msgid "Sort by column"
|
|
60
|
+
msgstr "Uredi po stolpcu"
|
|
61
|
+
|
|
62
|
+
#: dynamicforms/action.py:380
|
|
63
|
+
msgid "Filter"
|
|
64
|
+
msgstr "Filtriraj"
|
|
65
|
+
|
|
66
|
+
#: dynamicforms/template_render/mixins/serializer_render_fields.py:34
|
|
67
|
+
msgid "Actions"
|
|
68
|
+
msgstr "Akcije"
|
|
69
|
+
|
|
70
|
+
#~ msgid "Performing operation..."
|
|
71
|
+
#~ msgstr "Izvajam obdelavo..."
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# SOME DESCRIPTIVE TITLE.
|
|
2
|
+
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
3
|
+
# This file is distributed under the same license as the PACKAGE package.
|
|
4
|
+
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
5
|
+
#
|
|
6
|
+
#, fuzzy
|
|
7
|
+
msgid ""
|
|
8
|
+
msgstr ""
|
|
9
|
+
"Project-Id-Version: PACKAGE VERSION\n"
|
|
10
|
+
"Report-Msgid-Bugs-To: \n"
|
|
11
|
+
"POT-Creation-Date: 2023-07-20 13:48+0000\n"
|
|
12
|
+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
|
13
|
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
14
|
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
15
|
+
"Language: \n"
|
|
16
|
+
"MIME-Version: 1.0\n"
|
|
17
|
+
"Content-Type: text/plain; charset=UTF-8\n"
|
|
18
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
19
|
+
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || "
|
|
20
|
+
"n%100==4 ? 2 : 3);\n"
|
|
21
|
+
|
|
22
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:8
|
|
23
|
+
msgid "Ok"
|
|
24
|
+
msgstr "V redu"
|
|
25
|
+
|
|
26
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:8
|
|
27
|
+
msgid "Cancel"
|
|
28
|
+
msgstr "Prekliči"
|
|
29
|
+
|
|
30
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:48
|
|
31
|
+
msgid "No data"
|
|
32
|
+
msgstr "Ni podatkov"
|
|
33
|
+
|
|
34
|
+
#: vue/dynamicforms/dist/dynamicforms.umd.js:48
|
|
35
|
+
msgid "Performing operation..."
|
|
36
|
+
msgstr "Izvajam obdelavo..."
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
import os
|
|
3
|
+
import pathlib
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
from django.core.management.base import BaseCommand
|
|
7
|
+
|
|
8
|
+
from dynamicforms.preupload_files import preuploaded_fs, UPLOADED_FILE_NAME_TIMESTAMP_SEPARATOR
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Command(BaseCommand):
|
|
12
|
+
# TODO: this is redundant: the files should not be uploaded to any persistent storage, but instead to cache
|
|
13
|
+
# with a really short timeout, max a few hours. After that, they're gone automatically. No need for a clean up
|
|
14
|
+
# script nobody ever thought to setup to run in the first place. Task DF:#873
|
|
15
|
+
help = "Clean old temporary files which are generated when preloading files for df preloaded file field"
|
|
16
|
+
|
|
17
|
+
def handle(self, *args, **options):
|
|
18
|
+
current_timestamp: int = int(time.time())
|
|
19
|
+
margins_for_file_deletion: int = 86400 # one day od uploaded file retention
|
|
20
|
+
for file in glob.glob(f"{preuploaded_fs.location}/*"):
|
|
21
|
+
file_components: list = file.split(UPLOADED_FILE_NAME_TIMESTAMP_SEPARATOR)
|
|
22
|
+
if len(file_components) > 1:
|
|
23
|
+
file_path: pathlib.Path = pathlib.Path(file_components[1])
|
|
24
|
+
timestamp: int = int(file_path.stem)
|
|
25
|
+
if current_timestamp - timestamp > margins_for_file_deletion:
|
|
26
|
+
os.remove(file)
|
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# flake8: noqa
|
|
2
|
+
import abc
|
|
3
|
+
|
|
4
|
+
from rest_framework.fields import Field as DRFField
|
|
5
|
+
|
|
6
|
+
from .action import ActionMixin
|
|
7
|
+
from .choice import ChoiceMixin
|
|
8
|
+
from .color_field import ColorFieldMixin
|
|
9
|
+
from .conditional_visibility import ConditionalVisibilityMixin, F, FieldType, S, Statement
|
|
10
|
+
from .enable_copy import EnableCopyMixin
|
|
11
|
+
from .field_render import DisplayMode, FieldAlignment, FieldRenderMixin
|
|
12
|
+
from .file_field import FileFieldMixin
|
|
13
|
+
from .help_text import FieldHelpTextMixin
|
|
14
|
+
from .implicit_hidden import HiddenFieldMixin
|
|
15
|
+
from .implicit_natural_date import DateFieldMixin, DateTimeFieldMixin, TimeFieldMixin
|
|
16
|
+
from .null_value import NullValueMixin
|
|
17
|
+
from .password_field import PasswordFieldMixin
|
|
18
|
+
from .related_field_ajax import RelatedFieldAJAXMixin
|
|
19
|
+
from .rtf_field import RTFFieldMixin
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DFField(FieldRenderMixin, ActionMixin, FieldHelpTextMixin, ConditionalVisibilityMixin, DRFField, abc.ABC):
|
|
23
|
+
"""
|
|
24
|
+
Class only for type hinting
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from dynamicforms.action import Actions
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ActionMixin(object):
|
|
5
|
+
"""
|
|
6
|
+
Used in fields allowing declaration of actions that happen when field values change
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
def __init__(self, *args, actions: Actions = None, **kwargs):
|
|
10
|
+
super().__init__(*args, **kwargs)
|
|
11
|
+
act = actions or Actions(None)
|
|
12
|
+
act.actions.extend(getattr(self, "actions", Actions()).actions)
|
|
13
|
+
# Obtain a personalised list of actions
|
|
14
|
+
self.actions = act.get_resolved_copy(self)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from typing import Hashable
|
|
2
|
+
|
|
3
|
+
from rest_framework.fields import MultipleChoiceField
|
|
4
|
+
from rest_framework.relations import ManyRelatedField, PKOnlyObject, RelatedField
|
|
5
|
+
from rest_framework.serializers import ListSerializer
|
|
6
|
+
|
|
7
|
+
from .allow_tags import AllowTagsMixin, DenormalisedArray
|
|
8
|
+
from .null_choice import NullChoiceMixin
|
|
9
|
+
from .single_choice import SingleChoiceMixin
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ChoiceMixin(AllowTagsMixin, NullChoiceMixin, SingleChoiceMixin):
|
|
13
|
+
def __init__(self, *args, **kwargs):
|
|
14
|
+
choices = kwargs.get("choices", [])
|
|
15
|
+
kwargs["choices"] = [choice[:2] for choice in choices]
|
|
16
|
+
self.choice_icons = {choice[0]: choice[2] for choice in choices if len(choice) > 2}
|
|
17
|
+
super().__init__(*args, **kwargs)
|
|
18
|
+
if len(choices) > 100:
|
|
19
|
+
from dynamicforms.utils import print_field_declaration_line
|
|
20
|
+
print_field_declaration_line()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def as_component_def(self) -> dict:
|
|
24
|
+
try:
|
|
25
|
+
res = super().as_component_def() # noqa
|
|
26
|
+
except AttributeError:
|
|
27
|
+
res = dict()
|
|
28
|
+
|
|
29
|
+
res.update(
|
|
30
|
+
dict(
|
|
31
|
+
choices=self.__to_list_of_dicts(self.choices),
|
|
32
|
+
allow_tags=self.allow_tags, # noqa
|
|
33
|
+
allow_null=self.allow_null or self.allow_blank or self.allow_tags, # noqa
|
|
34
|
+
)
|
|
35
|
+
)
|
|
36
|
+
return res
|
|
37
|
+
|
|
38
|
+
def __to_list_of_dicts(self, choices_dict: dict) -> list:
|
|
39
|
+
return [dict(id=k, text=v, icon=self.choice_icons.get(k, None)) for k, v in choices_dict.items()]
|
|
40
|
+
|
|
41
|
+
# noinspection PyUnusedLocal, PyUnresolvedReferences
|
|
42
|
+
def render_to_table(self, value, row_data):
|
|
43
|
+
"""
|
|
44
|
+
Renders field value for table view :if rendering to html table, let's try to resolve any lookups
|
|
45
|
+
hidden fields will render to tr data-field_name attributes, so we maybe want to have ids, not text there,
|
|
46
|
+
but that's up to front end to decide
|
|
47
|
+
|
|
48
|
+
:param value: field value
|
|
49
|
+
:param row_data: data for entire row (for more complex renderers)
|
|
50
|
+
:return: rendered value for table view
|
|
51
|
+
"""
|
|
52
|
+
if isinstance(self, MultipleChoiceField):
|
|
53
|
+
res = DenormalisedArray(value, self)
|
|
54
|
+
return str(res)
|
|
55
|
+
|
|
56
|
+
get_queryset = getattr(self, "get_queryset", None)
|
|
57
|
+
|
|
58
|
+
if isinstance(self, ManyRelatedField):
|
|
59
|
+
# Hm, not sure if this is the final thing to do: an example of this field is in
|
|
60
|
+
# ALC plane editor (modes of takeoff). However, value is a queryset here. There seem to still be DB queries
|
|
61
|
+
# However, in the example I have, the problem is solved by doing prefetch_related on the m2m relation
|
|
62
|
+
cr = self.child_relation
|
|
63
|
+
return ", ".join((cr.display_value(item) for item in value))
|
|
64
|
+
# return ', '.join((cr.display_value(item) for item in cr.get_queryset().filter(pk__in=value)))
|
|
65
|
+
elif isinstance(self, RelatedField) or get_queryset:
|
|
66
|
+
return self.display_value(value)
|
|
67
|
+
else:
|
|
68
|
+
choices = getattr(self, "choices", {})
|
|
69
|
+
|
|
70
|
+
# Now that we got our choices for related & choice fields, let's first get the value as it would be by DRF
|
|
71
|
+
check_for_none = value.pk if isinstance(value, PKOnlyObject) else value
|
|
72
|
+
if check_for_none is None:
|
|
73
|
+
value = None
|
|
74
|
+
|
|
75
|
+
if isinstance(value, Hashable) and value in choices:
|
|
76
|
+
# choice field: let's render display names, not values
|
|
77
|
+
value = choices[value]
|
|
78
|
+
|
|
79
|
+
return value
|
|
80
|
+
|
|
81
|
+
# noinspection PyUnresolvedReferences
|
|
82
|
+
def to_internal_value(self, data):
|
|
83
|
+
"""
|
|
84
|
+
Reverse of to_representation: if data coming in is a tuple, use just the "id/code/key" part, not entire tuple
|
|
85
|
+
"""
|
|
86
|
+
if (
|
|
87
|
+
self.field_name not in ("df_control_data", "df_prev_id", "row_css_style")
|
|
88
|
+
and not isinstance(self, (ListSerializer, MultipleChoiceField))
|
|
89
|
+
and isinstance(data, list)
|
|
90
|
+
and len(data)
|
|
91
|
+
):
|
|
92
|
+
data = data[0]
|
|
93
|
+
|
|
94
|
+
return super().to_internal_value(data)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# TODO: Implementation of this mixin is wrong for ChoiceField (single choice variant):
|
|
2
|
+
# The ChoiceField will return data in an array even for (Single)ChoiceField. Select2 handles this, maybe even requires
|
|
3
|
+
# this, but some other component might not
|
|
4
|
+
import ast
|
|
5
|
+
|
|
6
|
+
from rest_framework.fields import ChoiceField, MultipleChoiceField
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DenormalisedArray(list):
|
|
10
|
+
def __init__(self, lst, field):
|
|
11
|
+
self.field = field
|
|
12
|
+
if lst is not None and isinstance(lst, str) and isinstance(field, MultipleChoiceField):
|
|
13
|
+
for itm in ast.literal_eval(lst):
|
|
14
|
+
self.append(itm)
|
|
15
|
+
|
|
16
|
+
elif lst is not None and isinstance(lst, list):
|
|
17
|
+
for itm in lst:
|
|
18
|
+
self.append(itm)
|
|
19
|
+
|
|
20
|
+
elif lst is not None:
|
|
21
|
+
self.append(lst)
|
|
22
|
+
|
|
23
|
+
def __str__(self):
|
|
24
|
+
choices = self.field.choices
|
|
25
|
+
ret = ""
|
|
26
|
+
count = 0
|
|
27
|
+
for item in self:
|
|
28
|
+
ret += ", " if count else ""
|
|
29
|
+
if item in choices:
|
|
30
|
+
ret += choices[item]
|
|
31
|
+
else:
|
|
32
|
+
ret += item
|
|
33
|
+
count += 1
|
|
34
|
+
return ret
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AllowTagsMixin(object):
|
|
38
|
+
def __init__(self, *args, allow_tags=False, **kwargs):
|
|
39
|
+
super().__init__(*args, **kwargs)
|
|
40
|
+
self.allow_tags = allow_tags or False
|
|
41
|
+
|
|
42
|
+
def to_internal_value(self, data):
|
|
43
|
+
"""
|
|
44
|
+
Validator is taken directly from DRF and updated, to check for allow_tags.
|
|
45
|
+
Option allow_tags enables adding value that is not on the options list.
|
|
46
|
+
"""
|
|
47
|
+
if not self.allow_tags:
|
|
48
|
+
data = super().to_internal_value(data)
|
|
49
|
+
|
|
50
|
+
if isinstance(self, MultipleChoiceField):
|
|
51
|
+
if isinstance(data, str) or not hasattr(data, "__iter__"):
|
|
52
|
+
self.fail("not_a_list", input_type=type(data).__name__)
|
|
53
|
+
if not self.allow_empty and len(data) == 0:
|
|
54
|
+
self.fail("empty")
|
|
55
|
+
|
|
56
|
+
return data
|
|
57
|
+
|
|
58
|
+
elif isinstance(self, ChoiceField) and not isinstance(self, MultipleChoiceField):
|
|
59
|
+
if data == "" and self.allow_blank:
|
|
60
|
+
return ""
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
if not self.allow_tags:
|
|
64
|
+
return self.choice_strings_to_values[str(data)]
|
|
65
|
+
|
|
66
|
+
return data
|
|
67
|
+
except KeyError:
|
|
68
|
+
self.fail("invalid_choice", input=data)
|
|
69
|
+
|
|
70
|
+
def iter_options_bound(self, value):
|
|
71
|
+
# noinspection PyUnresolvedReferences
|
|
72
|
+
if isinstance(value, list):
|
|
73
|
+
for item in value:
|
|
74
|
+
if item not in self.choices.keys():
|
|
75
|
+
self.grouped_choices[item] = item
|
|
76
|
+
elif isinstance(value, str) and self.allow_tags and value not in self.choices.keys():
|
|
77
|
+
self.grouped_choices[value] = value
|
|
78
|
+
|
|
79
|
+
return super().iter_options_bound(value)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from rest_framework.fields import ChoiceField
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class NullChoiceMixin(object):
|
|
5
|
+
"""
|
|
6
|
+
Declaring ChoiceField's null_choice_text
|
|
7
|
+
(what should be rendered for "no selection"; DRF's default is ---------)
|
|
8
|
+
We also support user declaring a choice with None value and a different text (see hidden fields example)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
@property
|
|
12
|
+
def null_choice_text(self):
|
|
13
|
+
res = "--------"
|
|
14
|
+
if isinstance(self, ChoiceField) and not getattr(self, "get_queryset", None):
|
|
15
|
+
# Only do this for true ChoiceFields. RelatedFields would run a query here
|
|
16
|
+
# Possibly we will at some point have to enable this for relatedfields too
|
|
17
|
+
for opt in self.iter_options():
|
|
18
|
+
if opt.start_option_group or opt.end_option_group:
|
|
19
|
+
pass
|
|
20
|
+
elif opt.value is None:
|
|
21
|
+
res = opt.display_text
|
|
22
|
+
return res
|
|
23
|
+
|
|
24
|
+
def iter_options_bound(self, value):
|
|
25
|
+
# noinspection PyUnresolvedReferences
|
|
26
|
+
return super().iter_options()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from ..field_render import DisplayMode
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SingleChoiceMixin:
|
|
5
|
+
def __init__(self, *args, single_choice_hide=False, **kwargs):
|
|
6
|
+
super().__init__(*args, **kwargs)
|
|
7
|
+
self.single_choice_hide = single_choice_hide
|
|
8
|
+
|
|
9
|
+
def to_internal_value(self, data):
|
|
10
|
+
if self.single_choice_hide and len(self.choices) == 1:
|
|
11
|
+
data = list(self.choices)[0]
|
|
12
|
+
elif self.single_choice_hide and len(self.choices) < 1:
|
|
13
|
+
data = None
|
|
14
|
+
return super().to_internal_value(data)
|
|
15
|
+
|
|
16
|
+
def set_single_choice_hide(self, value):
|
|
17
|
+
self._single_choice_hide = value
|
|
18
|
+
if value and len(self.choices) <= 1:
|
|
19
|
+
self.display_form = DisplayMode.HIDDEN
|
|
20
|
+
|
|
21
|
+
single_choice_hide = property(lambda self: self._single_choice_hide, set_single_choice_hide)
|