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
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
from collections import OrderedDict
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from django.db import models
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
from rest_framework.fields import SkipField
|
|
7
|
+
|
|
8
|
+
from dynamicforms_legacy.action import Actions
|
|
9
|
+
from dynamicforms_legacy.settings import DYNAMICFORMS
|
|
10
|
+
|
|
11
|
+
from . import fields
|
|
12
|
+
from .mixins import ActionMixin, DisplayMode, RenderMixin
|
|
13
|
+
from .struct import StructDefault
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DynamicFormsSerializer(RenderMixin, ActionMixin):
|
|
17
|
+
template_context = {} # see ViewSet.template_context
|
|
18
|
+
template_name = DYNAMICFORMS.form_base_template #: template filename for single record view (HTMLFormRenderer)
|
|
19
|
+
actions = Actions(add_default_crud=True, add_form_buttons=True)
|
|
20
|
+
form_titles = {
|
|
21
|
+
"table": "",
|
|
22
|
+
"new": "",
|
|
23
|
+
"edit": "",
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
show_filter = False # When true, filter row is shown for list view
|
|
27
|
+
|
|
28
|
+
def __init__(self, *args, is_filter: bool = False, **kwds):
|
|
29
|
+
self.master = None
|
|
30
|
+
self.is_filter = is_filter
|
|
31
|
+
if self.is_filter:
|
|
32
|
+
try:
|
|
33
|
+
instance = self.Meta.model()
|
|
34
|
+
for fld in instance._meta.fields:
|
|
35
|
+
setattr(instance, fld.name, None)
|
|
36
|
+
except:
|
|
37
|
+
instance = StructDefault(_default_=None)
|
|
38
|
+
kwds.setdefault("instance", instance)
|
|
39
|
+
super().__init__(*args, **kwds)
|
|
40
|
+
try:
|
|
41
|
+
# hide the primary key field (DRF only marks it as R/O)
|
|
42
|
+
field_name = self.Meta.model._meta.pk.name
|
|
43
|
+
if field_name not in self._declared_fields:
|
|
44
|
+
pk_field = self.fields[field_name]
|
|
45
|
+
pk_field.display_form = fields.DisplayMode.HIDDEN
|
|
46
|
+
pk_field.display_table = fields.DisplayMode.FULL
|
|
47
|
+
except:
|
|
48
|
+
pass
|
|
49
|
+
if self.is_filter:
|
|
50
|
+
for field in self.fields.values():
|
|
51
|
+
field.default = None
|
|
52
|
+
field.allow_blank = True
|
|
53
|
+
field.allow_null = True
|
|
54
|
+
field.read_only = False
|
|
55
|
+
field.display_form = field.display_table # filter's form is same as non-filter's table
|
|
56
|
+
field.allow_tags = False
|
|
57
|
+
field.password_field = False
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def has_non_field_errors(self):
|
|
61
|
+
"""
|
|
62
|
+
Reports whether validation turned up any form-wide validation errors. Used in templates to render the form-wide
|
|
63
|
+
error message
|
|
64
|
+
|
|
65
|
+
:return: True | False depending on whether form validation failed
|
|
66
|
+
"""
|
|
67
|
+
if hasattr(self, "_errors"):
|
|
68
|
+
return "non_field_errors" in self.errors
|
|
69
|
+
return False
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def page_title(self):
|
|
73
|
+
"""
|
|
74
|
+
Returns page title from form_titles based on the rendered data
|
|
75
|
+
:return string: page title
|
|
76
|
+
"""
|
|
77
|
+
if self.render_type == "table":
|
|
78
|
+
return self.form_titles.get("table", "")
|
|
79
|
+
elif self.data.get("id", None):
|
|
80
|
+
return self.form_titles.get("edit", "")
|
|
81
|
+
else:
|
|
82
|
+
return self.form_titles.get("new", "")
|
|
83
|
+
|
|
84
|
+
# noinspection PyProtectedMember
|
|
85
|
+
@property
|
|
86
|
+
def filter_data(self):
|
|
87
|
+
"""
|
|
88
|
+
Returns serializer for filter row in table
|
|
89
|
+
:return: Serializer
|
|
90
|
+
"""
|
|
91
|
+
if getattr(self, "_filter_ser", None) is None:
|
|
92
|
+
# noinspection PyAttributeOutsideInit
|
|
93
|
+
self._filter_ser = type(self)(is_filter=True, context=getattr(self, "context", {}))
|
|
94
|
+
self._filter_ser.master = self
|
|
95
|
+
return self._filter_ser # Just create the same serializer in filter mode (None values, allow_nulls)
|
|
96
|
+
|
|
97
|
+
# noinspection PyUnusedLocal
|
|
98
|
+
def suppress_action(self, action, request, viewset):
|
|
99
|
+
"""
|
|
100
|
+
Determines whether rendering an action into the DOM should be suppressed. Use when some users don't have access
|
|
101
|
+
to some of the functionality, e.g. when CRUD functionality is only enabled for administrative users
|
|
102
|
+
:param action: action to be checked
|
|
103
|
+
:param request: request that triggered the render (may be None)
|
|
104
|
+
:param viewset: viewset that provided the serialized data (may be None)
|
|
105
|
+
:return: boolean whether action should render (False) or not (True)
|
|
106
|
+
"""
|
|
107
|
+
return False
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def renderable_actions(self: "serializers.Serializer"):
|
|
111
|
+
"""
|
|
112
|
+
Returns those actions that are not suppressed
|
|
113
|
+
:return: List[Action]
|
|
114
|
+
"""
|
|
115
|
+
# TODO: Ta funkcija po mojem mora odletet (self.*controls*.actions). Sam zakaj ne? Ali se sploh ne uporablja?
|
|
116
|
+
request = self.context.get("request", None)
|
|
117
|
+
viewset = self.context.get("view", None)
|
|
118
|
+
return [action for action in self.controls.actions if not self.suppress_action(action, request, viewset)]
|
|
119
|
+
|
|
120
|
+
# noinspection PyUnresolvedReferences
|
|
121
|
+
def get_initial(self) -> Any:
|
|
122
|
+
if getattr(self, "_errors", None):
|
|
123
|
+
# This basically reproduces BaseSerializer.data property except that it disregards the _errors member
|
|
124
|
+
if self.instance:
|
|
125
|
+
res = self.to_representation(self.instance)
|
|
126
|
+
# elif hasattr(self, '_validated_data'):
|
|
127
|
+
# res = self.to_representation(self.validated_data)
|
|
128
|
+
else:
|
|
129
|
+
res = {}
|
|
130
|
+
res.update(super().get_initial())
|
|
131
|
+
|
|
132
|
+
return res
|
|
133
|
+
|
|
134
|
+
return super().get_initial()
|
|
135
|
+
|
|
136
|
+
# noinspection PyUnresolvedReferences
|
|
137
|
+
@property
|
|
138
|
+
def _writable_fields(self):
|
|
139
|
+
"""
|
|
140
|
+
Overrides DRF.serializers.Serializer._writable_fields
|
|
141
|
+
This one in particular should return exactly the same list as DRF's version (as of 17.4.2020, DRF version 3.11
|
|
142
|
+
"""
|
|
143
|
+
return (field for field in self.fields.values() if not field.read_only)
|
|
144
|
+
|
|
145
|
+
# noinspection PyUnresolvedReferences
|
|
146
|
+
@property
|
|
147
|
+
def _readable_fields(self):
|
|
148
|
+
"""
|
|
149
|
+
Overrides DRF.serializers.Serializer._readable_fields
|
|
150
|
+
This one adds additional checks on top of DRF's ones - checking if the field is renderable to table or form
|
|
151
|
+
"""
|
|
152
|
+
return (
|
|
153
|
+
field
|
|
154
|
+
for field in self.fields.values()
|
|
155
|
+
if not (
|
|
156
|
+
field.write_only
|
|
157
|
+
or (self.is_rendering_to_list and self.display_table == DisplayMode.SUPPRESS)
|
|
158
|
+
or (not self.is_rendering_to_list and self.display_form == DisplayMode.SUPPRESS)
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
def to_representation(self, instance, row_data=None):
|
|
163
|
+
"""
|
|
164
|
+
Object instance -> Dict of primitive datatypes.
|
|
165
|
+
"""
|
|
166
|
+
ret = OrderedDict()
|
|
167
|
+
for field in self._readable_fields:
|
|
168
|
+
try:
|
|
169
|
+
attribute = field.get_attribute(instance)
|
|
170
|
+
if not isinstance(field, RenderMixin):
|
|
171
|
+
ret[field.field_name] = field.to_representation(attribute)
|
|
172
|
+
else:
|
|
173
|
+
try:
|
|
174
|
+
ret[field.field_name] = field.to_representation(attribute, instance)
|
|
175
|
+
except:
|
|
176
|
+
if attribute is None and not field.required:
|
|
177
|
+
# DRF makes a special check for none and then always returns None if the check is None.
|
|
178
|
+
# We still want to process custom field to_representation, even if value is None.
|
|
179
|
+
# But when field is a sub-serializer and it (it's FK reference) is none, it's OK
|
|
180
|
+
# to pass None as result of serialization of such field
|
|
181
|
+
raise SkipField()
|
|
182
|
+
else:
|
|
183
|
+
raise
|
|
184
|
+
except SkipField:
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
return ret
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class ModelSerializer(DynamicFormsSerializer, serializers.ModelSerializer):
|
|
191
|
+
"""
|
|
192
|
+
DynamicForms' ModelSerializer overrides the following behaviour over DRF's implementation:
|
|
193
|
+
|
|
194
|
+
* Uses own field types for construction
|
|
195
|
+
* Adds form UUID (rendered in html too)
|
|
196
|
+
* Adds processing for form-wide errors
|
|
197
|
+
|
|
198
|
+
DRF's docstring copied verbatim:
|
|
199
|
+
|
|
200
|
+
A `ModelSerializer` is just a regular `Serializer`, except that:
|
|
201
|
+
|
|
202
|
+
* A set of default fields are automatically populated.
|
|
203
|
+
* A set of default validators are automatically populated.
|
|
204
|
+
* Default `.create()` and `.update()` implementations are provided.
|
|
205
|
+
|
|
206
|
+
The process of automatically determining a set of serializer fields
|
|
207
|
+
based on the model fields is reasonably complex, but you almost certainly
|
|
208
|
+
don't need to dig into the implementation.
|
|
209
|
+
|
|
210
|
+
If the `ModelSerializer` class *doesn't* generate the set of fields that
|
|
211
|
+
you need you should either declare the extra/differing fields explicitly on
|
|
212
|
+
the serializer class, or simply use a `Serializer` class.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
def __init__(self, *args, is_filter: bool = False, **kwds):
|
|
216
|
+
if hasattr(self, "Meta") and hasattr(self.Meta, "fields"):
|
|
217
|
+
self._make_df_special_fields_present_in_fields(["df_prev_id", "row_css_style"])
|
|
218
|
+
super().__init__(*args, is_filter=is_filter, **kwds)
|
|
219
|
+
self.manage_changed_flds()
|
|
220
|
+
|
|
221
|
+
def _make_df_special_fields_present_in_fields(self, fields):
|
|
222
|
+
for f in fields:
|
|
223
|
+
if self.Meta.fields != "__all__" and f not in self.Meta.fields:
|
|
224
|
+
self.Meta.fields += (f,)
|
|
225
|
+
|
|
226
|
+
serializer_field_mapping = {
|
|
227
|
+
models.AutoField: fields.IntegerField,
|
|
228
|
+
models.BigIntegerField: fields.IntegerField,
|
|
229
|
+
models.BooleanField: fields.BooleanField,
|
|
230
|
+
models.CharField: fields.CharField,
|
|
231
|
+
models.CommaSeparatedIntegerField: fields.CharField,
|
|
232
|
+
models.DateField: fields.DateField,
|
|
233
|
+
models.DateTimeField: fields.DateTimeField,
|
|
234
|
+
models.DecimalField: fields.DecimalField,
|
|
235
|
+
models.EmailField: fields.EmailField,
|
|
236
|
+
models.Field: fields.ModelField,
|
|
237
|
+
models.FileField: fields.FileField,
|
|
238
|
+
models.FloatField: fields.FloatField,
|
|
239
|
+
models.ImageField: fields.ImageField,
|
|
240
|
+
models.IntegerField: fields.IntegerField,
|
|
241
|
+
models.NullBooleanField: fields.BooleanField,
|
|
242
|
+
models.PositiveIntegerField: fields.IntegerField,
|
|
243
|
+
models.PositiveSmallIntegerField: fields.IntegerField,
|
|
244
|
+
models.SlugField: fields.SlugField,
|
|
245
|
+
models.SmallIntegerField: fields.IntegerField,
|
|
246
|
+
models.TextField: fields.CharField,
|
|
247
|
+
models.TimeField: fields.TimeField,
|
|
248
|
+
models.URLField: fields.URLField,
|
|
249
|
+
models.GenericIPAddressField: fields.IPAddressField,
|
|
250
|
+
models.FilePathField: fields.FilePathField,
|
|
251
|
+
}
|
|
252
|
+
if models.DurationField is not None:
|
|
253
|
+
serializer_field_mapping[models.DurationField] = fields.DurationField
|
|
254
|
+
|
|
255
|
+
serializer_related_field = fields.PrimaryKeyRelatedField
|
|
256
|
+
serializer_related_to_field = fields.SlugRelatedField
|
|
257
|
+
serializer_url_field = fields.HyperlinkedIdentityField
|
|
258
|
+
serializer_choice_field = fields.ChoiceField
|
|
259
|
+
|
|
260
|
+
def manage_changed_flds(self):
|
|
261
|
+
"""
|
|
262
|
+
When there is a need to only change few parameters of a field put those fields and changed parameters in
|
|
263
|
+
serializers Meta class in parameter changed_flds.
|
|
264
|
+
|
|
265
|
+
Example:
|
|
266
|
+
|
|
267
|
+
.. code-block:: python
|
|
268
|
+
|
|
269
|
+
changed_flds = {
|
|
270
|
+
'id': dict(display=DisplayMode.HIDDEN),
|
|
271
|
+
'comment': dict(label='Comm', help_text='Help text for comment field')
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
:return:
|
|
275
|
+
|
|
276
|
+
"""
|
|
277
|
+
if hasattr(self.Meta, "changed_flds"):
|
|
278
|
+
for field, params in self.Meta.changed_flds.items():
|
|
279
|
+
field_def = self.fields.get(field, None)
|
|
280
|
+
if field_def:
|
|
281
|
+
for key, val in params.items():
|
|
282
|
+
setattr(field_def, key, val)
|
|
283
|
+
|
|
284
|
+
# Dynamic forms default field that is used to contain data for positioning (id of previous record)
|
|
285
|
+
df_prev_id = fields.SerializerMethodField(display=DisplayMode.HIDDEN)
|
|
286
|
+
|
|
287
|
+
# this is a calculated field that returns css style for table row
|
|
288
|
+
row_css_style = fields.SerializerMethodField(display=DisplayMode.HIDDEN)
|
|
289
|
+
|
|
290
|
+
def fetch_prev_id(self, obj, view):
|
|
291
|
+
ordering = "id"
|
|
292
|
+
try:
|
|
293
|
+
ordering = view.pagination_class.ordering
|
|
294
|
+
except:
|
|
295
|
+
pass
|
|
296
|
+
if ordering != "id":
|
|
297
|
+
query_params = self.context["request"].query_params
|
|
298
|
+
query_params._mutable = True
|
|
299
|
+
query_params.pop("id", "")
|
|
300
|
+
queryset = view.filter_queryset(queryset=view.get_queryset(), query_params=query_params)
|
|
301
|
+
records = list(queryset.order_by(ordering))
|
|
302
|
+
curr_index = records.index(obj)
|
|
303
|
+
prev_id = None
|
|
304
|
+
if curr_index > 0:
|
|
305
|
+
prev_id = records[curr_index - 1].id
|
|
306
|
+
|
|
307
|
+
return prev_id
|
|
308
|
+
|
|
309
|
+
return ""
|
|
310
|
+
|
|
311
|
+
# noinspection PyMethodMayBeStatic
|
|
312
|
+
def get_df_prev_id(self, obj):
|
|
313
|
+
try:
|
|
314
|
+
if self.context["request"].META.get("HTTP_X_DF_CALLTYPE", "") == "refresh_record":
|
|
315
|
+
view = self.context.get("view", None)
|
|
316
|
+
if view:
|
|
317
|
+
return self.fetch_prev_id(obj, view)
|
|
318
|
+
except:
|
|
319
|
+
pass
|
|
320
|
+
|
|
321
|
+
return ""
|
|
322
|
+
|
|
323
|
+
# noinspection PyMethodMayBeStatic
|
|
324
|
+
def get_row_css_style(self, obj):
|
|
325
|
+
return ""
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class Serializer(DynamicFormsSerializer, serializers.Serializer):
|
|
329
|
+
def update(self, instance, validated_data):
|
|
330
|
+
# Implemented just so IDE doesn't complain. Normally this will be handled in SingleRecordViewSet
|
|
331
|
+
pass
|
|
332
|
+
|
|
333
|
+
def create(self, validated_data):
|
|
334
|
+
# Implemented just so IDE doesn't complain. Normally this will be handled in SingleRecordViewSet
|
|
335
|
+
pass
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
from django.conf import settings as s
|
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
|
+
|
|
4
|
+
from .struct import Struct
|
|
5
|
+
|
|
6
|
+
DYNAMICFORMS_ROOT = "dynamicforms/"
|
|
7
|
+
DYNAMICFORMS_BOOTSTRAP = DYNAMICFORMS_ROOT + "bootstrap/"
|
|
8
|
+
DYNAMICFORMS_JQUERY_UI = DYNAMICFORMS_ROOT + "jquery_ui/"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Settings(Struct):
|
|
12
|
+
# Support for jQueryUI (this will be queried in dynamicforms.js)
|
|
13
|
+
jquery_ui = False
|
|
14
|
+
|
|
15
|
+
# if True, base_list template will render the HTML such that it will display dialog
|
|
16
|
+
# Make sure you {% include DYNAMICFORMS.modal_dialog_rest_template %} somewhere top-level in your html body
|
|
17
|
+
# if False, the record will be displayed in a new page
|
|
18
|
+
edit_in_dialog = True
|
|
19
|
+
|
|
20
|
+
# Support for select2
|
|
21
|
+
use_select2 = True
|
|
22
|
+
|
|
23
|
+
# specifies the basepage template to be used for TemplateHTMLRenderer
|
|
24
|
+
page_template = ""
|
|
25
|
+
|
|
26
|
+
# specifies text to be displayed in grid when field's value is null
|
|
27
|
+
null_text_table = "null"
|
|
28
|
+
|
|
29
|
+
def __init__(self, data=None, **kwds):
|
|
30
|
+
kwds.setdefault("page_template", DYNAMICFORMS_ROOT + "page.html")
|
|
31
|
+
super().__init__(data, **kwds)
|
|
32
|
+
self.template = DYNAMICFORMS_BOOTSTRAP
|
|
33
|
+
self.template_root = DYNAMICFORMS_ROOT
|
|
34
|
+
self.login_url = s.LOGIN_URL
|
|
35
|
+
|
|
36
|
+
def __to_dict__(self):
|
|
37
|
+
res = {}
|
|
38
|
+
res.update(super().__to_dict__())
|
|
39
|
+
for p in dir(self):
|
|
40
|
+
if not (p == "clone" or p.startswith("_")):
|
|
41
|
+
res[p] = getattr(self, p)
|
|
42
|
+
return res
|
|
43
|
+
|
|
44
|
+
# noinspection PyPep8Naming
|
|
45
|
+
@property
|
|
46
|
+
def DisplayMode(self):
|
|
47
|
+
from .mixins import DisplayMode
|
|
48
|
+
|
|
49
|
+
return {e.name: e.value for e in DisplayMode} # A copy to be accessible in the templates
|
|
50
|
+
|
|
51
|
+
# ****************************************************************************
|
|
52
|
+
# These are constants, generated from settings. They are shortcuts for quick use in templates and are specific
|
|
53
|
+
# to the chosen template pack.
|
|
54
|
+
# ****************************************************************************
|
|
55
|
+
|
|
56
|
+
select2_form_field_class = property(lambda self: "select2-field" if self.use_select2 else "")
|
|
57
|
+
|
|
58
|
+
# Path to template for :samp:`<html><head>` tag JS & CSS includes, necessary for the chosen template pack.
|
|
59
|
+
page_includes = property(lambda self: DYNAMICFORMS_ROOT + "base_includes.html")
|
|
60
|
+
|
|
61
|
+
# Path to base template for fields.
|
|
62
|
+
field_base_template = property(lambda self: DYNAMICFORMS_ROOT + "field/base_field.html")
|
|
63
|
+
|
|
64
|
+
# Path to base template for forms.
|
|
65
|
+
form_base_template = property(lambda self: DYNAMICFORMS_ROOT + "base_form.html")
|
|
66
|
+
|
|
67
|
+
# Path to base template for forms.
|
|
68
|
+
table_base_template = property(lambda self: DYNAMICFORMS_ROOT + "base_list.html")
|
|
69
|
+
|
|
70
|
+
# Path to base template for forms.
|
|
71
|
+
table_filter_base_template = property(lambda self: DYNAMICFORMS_ROOT + "base_table_filter.html")
|
|
72
|
+
|
|
73
|
+
# Path to base template for table body.
|
|
74
|
+
table_body_base_template = property(lambda self: DYNAMICFORMS_ROOT + "base_table_body.html")
|
|
75
|
+
|
|
76
|
+
# Path to template for modal dialog
|
|
77
|
+
modal_dialog_rest_template = property(lambda self: DYNAMICFORMS_ROOT + "modal_dialog_rest.html")
|
|
78
|
+
|
|
79
|
+
# classes to use on form buttons
|
|
80
|
+
form_button_classes = property(lambda self: "")
|
|
81
|
+
form_button_classes_cancel = property(lambda self: "")
|
|
82
|
+
form_button_classes_primary = property(lambda self: "")
|
|
83
|
+
form_button_classes_secondary = property(lambda self: "")
|
|
84
|
+
|
|
85
|
+
select2_include = property(lambda self: DYNAMICFORMS_ROOT + "base_includes_select2.html")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def if3_4(if3, if4):
|
|
89
|
+
def inner(self):
|
|
90
|
+
if self.bootstrap_version == "v4":
|
|
91
|
+
return if4
|
|
92
|
+
return if3
|
|
93
|
+
|
|
94
|
+
return inner
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class SettingsBootstrap(Settings):
|
|
98
|
+
# Supported Bootstrap versions are v3 and v4
|
|
99
|
+
bootstrap_version = "v4"
|
|
100
|
+
|
|
101
|
+
def __init__(self, data=None, **kwds):
|
|
102
|
+
super().__init__(data, **kwds)
|
|
103
|
+
self.template = DYNAMICFORMS_BOOTSTRAP
|
|
104
|
+
|
|
105
|
+
# select2 helper variables
|
|
106
|
+
select2_theme = property(if3_4("bootstrap", "bootstrap4"))
|
|
107
|
+
select2_add_include = property(
|
|
108
|
+
if3_4("select2/css/select2-bootstrap3.min.css", "select2/css/select2-bootstrap4.min.css")
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# classes for card divs
|
|
112
|
+
bs_card_class = property(if3_4("panel panel-default", "card"))
|
|
113
|
+
bs_card_header = property(if3_4("panel-heading df-card-header", "card-header df-card-header"))
|
|
114
|
+
bs_card_body = property(if3_4("panel-body df-card-body", "card-body df-card-body"))
|
|
115
|
+
|
|
116
|
+
progress_dialog_title = _("Performing operation...")
|
|
117
|
+
|
|
118
|
+
# classes to use on form buttons
|
|
119
|
+
form_button_classes = property(lambda self: "btn ml-1")
|
|
120
|
+
form_button_classes_cancel = property(lambda self: "")
|
|
121
|
+
form_button_classes_primary = property(lambda self: "btn-primary")
|
|
122
|
+
form_button_classes_secondary = property(lambda self: "btn-secondary")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class SettingsJqueryUI(Settings):
|
|
126
|
+
jquery_ui = True
|
|
127
|
+
|
|
128
|
+
def __init__(self, data=None, **kwds):
|
|
129
|
+
super().__init__(data, **kwds)
|
|
130
|
+
self.template = DYNAMICFORMS_JQUERY_UI
|
|
131
|
+
|
|
132
|
+
progress_dialog_title = _("Performing operation...")
|
|
133
|
+
|
|
134
|
+
# classes to use on form buttons
|
|
135
|
+
form_button_classes = property(lambda self: "ui-button ui-corner-all ui-widget")
|
|
136
|
+
form_button_classes_cancel = property(lambda self: "close-btn")
|
|
137
|
+
form_button_classes_primary = property(lambda self: "ui-state-highlight")
|
|
138
|
+
form_button_classes_secondary = property(lambda self: "")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_settings():
|
|
142
|
+
"""
|
|
143
|
+
Let's parse settings from settings.py
|
|
144
|
+
|
|
145
|
+
:return: Settings class
|
|
146
|
+
"""
|
|
147
|
+
df = Struct(
|
|
148
|
+
template=DYNAMICFORMS_BOOTSTRAP,
|
|
149
|
+
)
|
|
150
|
+
df = df.clone(**getattr(s, "DYNAMICFORMS", {}))
|
|
151
|
+
template = df.template
|
|
152
|
+
if template == DYNAMICFORMS_BOOTSTRAP:
|
|
153
|
+
return SettingsBootstrap(**df.__to_dict__())
|
|
154
|
+
return SettingsJqueryUI(**df.__to_dict__())
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
DYNAMICFORMS = get_settings()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def version_check(checked_version, min_version):
|
|
161
|
+
"""
|
|
162
|
+
Checks whether checked version is higher or equal to given min version
|
|
163
|
+
:param checked_version: version being checked
|
|
164
|
+
:param min_version: minimum allowed version
|
|
165
|
+
:return: True when checked version is high enough
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
def version_transform(ver):
|
|
169
|
+
version = ""
|
|
170
|
+
vn = va = ""
|
|
171
|
+
stage = 0
|
|
172
|
+
ver = "." + (ver or "")
|
|
173
|
+
for c in ver:
|
|
174
|
+
if c == ".":
|
|
175
|
+
if vn or va:
|
|
176
|
+
version += "{0:0>3}{1: <2}.".format(vn, va)
|
|
177
|
+
vn = va = ""
|
|
178
|
+
stage = 0
|
|
179
|
+
continue
|
|
180
|
+
if c.isdigit():
|
|
181
|
+
pass
|
|
182
|
+
elif c.isalpha():
|
|
183
|
+
stage = max(1, stage)
|
|
184
|
+
else:
|
|
185
|
+
stage = max(2, stage)
|
|
186
|
+
if stage == 0:
|
|
187
|
+
vn += c
|
|
188
|
+
elif stage == 1:
|
|
189
|
+
va += c
|
|
190
|
+
if vn or va:
|
|
191
|
+
version += "{0:0>3}{1: <2}.".format(vn, va)
|
|
192
|
+
return version[:-1]
|
|
193
|
+
|
|
194
|
+
if not checked_version:
|
|
195
|
+
return False
|
|
196
|
+
return version_transform(checked_version) >= version_transform(min_version)
|