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,301 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from enum import auto
|
|
4
|
+
from typing import Any, Dict
|
|
5
|
+
|
|
6
|
+
from django.template import loader
|
|
7
|
+
from rest_framework.reverse import reverse
|
|
8
|
+
from rest_framework.serializers import Serializer, SerializerMetaclass
|
|
9
|
+
|
|
10
|
+
from dynamicforms import fields
|
|
11
|
+
from dynamicforms.action import TableAction, TablePosition
|
|
12
|
+
from dynamicforms.mixins import ActionMixin, DisplayMode, FieldRenderMixin
|
|
13
|
+
|
|
14
|
+
from .base import ViewModeBase
|
|
15
|
+
from .render_mode_enum import ViewModeEnum
|
|
16
|
+
from .serializer_filter import SerializerFilter
|
|
17
|
+
from .serializer_render_actions import SerializerRenderActions
|
|
18
|
+
from .serializer_render_fields import SerializerRenderFields
|
|
19
|
+
from .util import convert_to_json_if
|
|
20
|
+
|
|
21
|
+
# noinspection PyUnreachableCode
|
|
22
|
+
if False:
|
|
23
|
+
from .listserializer import ViewModeListSerializer
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ViewModeSerializer(ViewModeBase, SerializerFilter, metaclass=SerializerMetaclass):
|
|
27
|
+
"""
|
|
28
|
+
This one is actually a mixin, not a monkey-patch like the other two
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
bound_value = None
|
|
32
|
+
|
|
33
|
+
class ViewMode(ViewModeEnum):
|
|
34
|
+
FORM = auto() # Render to form field
|
|
35
|
+
TABLE_ROW = auto() # Render to table tr
|
|
36
|
+
TABLE_HEAD = auto() # Render to table header
|
|
37
|
+
|
|
38
|
+
df_control_data = fields.SerializerMethodField(display=DisplayMode.HIDDEN, read_only=True)
|
|
39
|
+
show_filter = True
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def component_name(self):
|
|
43
|
+
"""
|
|
44
|
+
component_name returns name of Vue component to use for rendering this serializer's form
|
|
45
|
+
by default it will take the HTML template's form_template parameter and replace all non-compliant
|
|
46
|
+
characters with '-'.
|
|
47
|
+
|
|
48
|
+
Usually, though, you will replace this property with one of your own declaring your Vue component name to
|
|
49
|
+
instantiate. The component is expected to behave like DFFormLayout does
|
|
50
|
+
:return: name of component to use when rendering the layout in VDOM
|
|
51
|
+
"""
|
|
52
|
+
res = getattr(self, "form_template", "df-form-layout")
|
|
53
|
+
res = re.sub(r"[^a-zA-Z0-9._-]", "-", res)
|
|
54
|
+
return res
|
|
55
|
+
|
|
56
|
+
"""
|
|
57
|
+
we're currently using two additional headers for axios:
|
|
58
|
+
'x-viewmode': 'TABLE_ROW' - tells DF what viewMode to use for rendering the response
|
|
59
|
+
'x-pagination': 1 - tells DRF to paginate (or not) the result
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
*args,
|
|
65
|
+
view_mode: "ViewModeSerializer.ViewMode" = None,
|
|
66
|
+
view_mode_list: "ViewModeListSerializer.ViewMode" = None,
|
|
67
|
+
**kwds,
|
|
68
|
+
):
|
|
69
|
+
super().__init__(*args, **kwds)
|
|
70
|
+
if not view_mode and self.request and "HTTP_X_VIEWMODE" in self.request.META:
|
|
71
|
+
view_mode = self.ViewMode[self.request.META["HTTP_X_VIEWMODE"]]
|
|
72
|
+
self.set_view_mode(view_mode)
|
|
73
|
+
self.view_mode_list = view_mode_list
|
|
74
|
+
|
|
75
|
+
def __new__(cls, *args, **kwargs):
|
|
76
|
+
from .listserializer import ViewModeListSerializer
|
|
77
|
+
|
|
78
|
+
view_mode_list = kwargs.pop("view_mode_list", None)
|
|
79
|
+
|
|
80
|
+
# Set list_serializer_class of class Meta
|
|
81
|
+
meta = getattr(cls, "Meta", None)
|
|
82
|
+
if meta is None:
|
|
83
|
+
meta = type("Meta", (object,), {})
|
|
84
|
+
cls.Meta = meta
|
|
85
|
+
if not hasattr(meta, "list_serializer_class"):
|
|
86
|
+
meta.list_serializer_class = ViewModeListSerializer
|
|
87
|
+
|
|
88
|
+
res = super().__new__(cls, *args, **kwargs)
|
|
89
|
+
if isinstance(res, ViewModeListSerializer):
|
|
90
|
+
if not view_mode_list and res.child.view_mode == ViewModeSerializer.ViewMode.TABLE_ROW:
|
|
91
|
+
view_mode_list = ViewModeListSerializer.ViewMode.TABLE
|
|
92
|
+
|
|
93
|
+
res.set_view_mode(view_mode_list)
|
|
94
|
+
res.display_table = res.child.display_table
|
|
95
|
+
res.display_form = res.child.display_form
|
|
96
|
+
|
|
97
|
+
return res
|
|
98
|
+
|
|
99
|
+
def set_bound_value(self, value: Dict[Any, Any]):
|
|
100
|
+
self.bound_value = value
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def request(self: "_ViewModeBoundSerializer"):
|
|
104
|
+
if self.context and "view" in self.context and self.context["view"].request:
|
|
105
|
+
return self.context["view"].request
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
def render_form(self: "_ViewModeBoundSerializer"):
|
|
109
|
+
template = loader.get_template("template_render/full_form.html")
|
|
110
|
+
context = dict(serializer=self, columns=self.render_fields)
|
|
111
|
+
return template.render(context)
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def render_fields(self: "_ViewModeBoundSerializer"):
|
|
115
|
+
this = self
|
|
116
|
+
|
|
117
|
+
class BoundSerializerRenderFields(SerializerRenderFields):
|
|
118
|
+
@property
|
|
119
|
+
def fields(self):
|
|
120
|
+
actions = [a for a in this.actions.renderable_actions(this) if isinstance(a, TableAction)]
|
|
121
|
+
if any(getattr(action, "position", None) == TablePosition.ROW_START for action in actions):
|
|
122
|
+
yield SerializerRenderFields.ActionField(actions, TablePosition.ROW_START)
|
|
123
|
+
|
|
124
|
+
for f in this.fields.values():
|
|
125
|
+
if f.display_table != DisplayMode.SUPPRESS:
|
|
126
|
+
yield f
|
|
127
|
+
|
|
128
|
+
if any(getattr(action, "position", None) == TablePosition.ROW_END for action in actions):
|
|
129
|
+
yield SerializerRenderFields.ActionField(actions, TablePosition.ROW_END)
|
|
130
|
+
|
|
131
|
+
return BoundSerializerRenderFields()
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def render_actions(self: "_ViewModeBoundSerializer"):
|
|
135
|
+
this = self
|
|
136
|
+
|
|
137
|
+
class BoundSerializerRenderActions(SerializerRenderActions):
|
|
138
|
+
@property
|
|
139
|
+
def actions(self):
|
|
140
|
+
return this.actions.renderable_actions(this)
|
|
141
|
+
|
|
142
|
+
return BoundSerializerRenderActions()
|
|
143
|
+
|
|
144
|
+
def component_params(self: "_ViewModeBoundSerializer", output_json: bool = True):
|
|
145
|
+
params = {
|
|
146
|
+
"uuid": self.uuid,
|
|
147
|
+
"primary_key_name": (
|
|
148
|
+
self.Meta.model._meta.pk.name
|
|
149
|
+
if not self.Meta.model._meta.get_parent_list()
|
|
150
|
+
else self.Meta.model._meta.get_parent_list()[0]._meta.pk.name
|
|
151
|
+
)
|
|
152
|
+
if getattr(self, "Meta", None) and getattr(self.Meta, "model", None)
|
|
153
|
+
else "id",
|
|
154
|
+
"titles": self.form_titles,
|
|
155
|
+
"columns": [c.as_component_def() for c in self.render_fields.fields],
|
|
156
|
+
"responsive_table_layouts": self.get_responsive_table_layouts_def(),
|
|
157
|
+
"actions": self.render_actions.as_action_def(),
|
|
158
|
+
"record": None if self.parent else self.data,
|
|
159
|
+
"filter": self.filter_serializer_component_params() if self.show_filter else None,
|
|
160
|
+
"row_select": bool(getattr(self, "row_select", False)),
|
|
161
|
+
"dialog": self.get_dialog_def(),
|
|
162
|
+
"detail_url": self.reverse_url if not self.is_filter else None,
|
|
163
|
+
"ordering_parameter": getattr(self.context["view"], "ordering_parameter", "ordering"),
|
|
164
|
+
"ordering_style": getattr(self.context["view"], "ordering_style", None),
|
|
165
|
+
}
|
|
166
|
+
return convert_to_json_if(params, output_json)
|
|
167
|
+
|
|
168
|
+
def get_df_control_data(self: "_ViewModeBoundSerializer", row):
|
|
169
|
+
"""
|
|
170
|
+
Returns any additional data needed for rendering or operating the serializer on the client, such as presence of
|
|
171
|
+
action buttons, their parameters, CSS, etc.
|
|
172
|
+
|
|
173
|
+
deprecates row_css_style and df_prev_link
|
|
174
|
+
|
|
175
|
+
:param row: row data to consider when presenting the return data
|
|
176
|
+
:return: dict of settings for actions and row-related data
|
|
177
|
+
"""
|
|
178
|
+
return dict(
|
|
179
|
+
row_css_style=self.get_row_css_style(row),
|
|
180
|
+
actions=dict(
|
|
181
|
+
filter(
|
|
182
|
+
lambda x: x[1] is not None,
|
|
183
|
+
(action.to_component_params(row, self) for action in self.render_actions.actions),
|
|
184
|
+
)
|
|
185
|
+
),
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
@property
|
|
189
|
+
def layout(self):
|
|
190
|
+
template_context = getattr(self, "template_context", {})
|
|
191
|
+
if hasattr(self, "Meta") and hasattr(self.Meta, "layout"):
|
|
192
|
+
return self.Meta.layout
|
|
193
|
+
else:
|
|
194
|
+
from dynamicforms.template_render.layout import Layout
|
|
195
|
+
|
|
196
|
+
return Layout(
|
|
197
|
+
size=template_context.get("dialog_classes", ""),
|
|
198
|
+
header_classes=template_context.get("dialog_header_classes", ""),
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
def get_dialog_def(self):
|
|
202
|
+
return self.layout.as_component_def(self)
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def responsive_table_layouts(self):
|
|
206
|
+
if hasattr(self, "Meta") and hasattr(self.Meta, "responsive_columns"):
|
|
207
|
+
return self.Meta.responsive_columns
|
|
208
|
+
return None
|
|
209
|
+
|
|
210
|
+
def get_responsive_table_layouts_def(self):
|
|
211
|
+
return self.responsive_table_layouts and self.responsive_table_layouts.as_component_def(self)
|
|
212
|
+
|
|
213
|
+
@classmethod
|
|
214
|
+
def get_reverse_url(cls, view_name, request, kwargs=None):
|
|
215
|
+
return reverse(view_name + "-detail", format="json", request=request, kwargs=kwargs)
|
|
216
|
+
|
|
217
|
+
@classmethod
|
|
218
|
+
def get_component_context(cls, request, queryset):
|
|
219
|
+
from rest_framework.request import Request
|
|
220
|
+
|
|
221
|
+
from dynamicforms.filters import FilterBackend
|
|
222
|
+
from dynamicforms.template_render import ViewModeListSerializer, ViewModeSerializer
|
|
223
|
+
from dynamicforms.viewsets import ModelViewSet
|
|
224
|
+
|
|
225
|
+
class FakeViewSet(object):
|
|
226
|
+
"""
|
|
227
|
+
We fake a DRF ViewSet here to get ordering and pagination to work
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
def __init__(self, request, queryset):
|
|
231
|
+
self.filter_backend = FilterBackend()
|
|
232
|
+
self.request = request
|
|
233
|
+
self.queryset = queryset
|
|
234
|
+
|
|
235
|
+
@property
|
|
236
|
+
def ordering(self):
|
|
237
|
+
return self.filter_backend.get_ordering(self.request, self.queryset, None)
|
|
238
|
+
|
|
239
|
+
paginator = ModelViewSet.generate_paged_loader()()
|
|
240
|
+
|
|
241
|
+
# first we try to paginate the queryset, together with some sort ordering & stuff
|
|
242
|
+
req = Request(request)
|
|
243
|
+
req.accepted_renderer = None # viewsets.py->MyCursorPagination.encode_cursor
|
|
244
|
+
viewset = FakeViewSet(req, queryset)
|
|
245
|
+
page = paginator.paginate_queryset(queryset, req)
|
|
246
|
+
if page is None:
|
|
247
|
+
# if unsuccessful, just resume with the entire queryset
|
|
248
|
+
page = queryset
|
|
249
|
+
|
|
250
|
+
ser = cls(
|
|
251
|
+
page,
|
|
252
|
+
view_mode=ViewModeSerializer.ViewMode.TABLE_ROW,
|
|
253
|
+
view_mode_list=ViewModeListSerializer.ViewMode.TABLE,
|
|
254
|
+
context=dict(view=viewset),
|
|
255
|
+
many=True,
|
|
256
|
+
)
|
|
257
|
+
base_url = paginator.base_url.split("?", 1)
|
|
258
|
+
ser.reverse_url = ser.get_reverse_url(cls.template_context["url_reverse"], request)
|
|
259
|
+
ser.child.reverse_url = ser.child.get_reverse_url(
|
|
260
|
+
cls.template_context["url_reverse"], request, kwargs=dict(pk="--record_id--")
|
|
261
|
+
)
|
|
262
|
+
paginator.base_url = ser.reverse_url + (("?" + base_url[1]) if len(base_url) == 2 else "")
|
|
263
|
+
ser.paginator = paginator
|
|
264
|
+
return ser
|
|
265
|
+
|
|
266
|
+
def apply_component_context(self, request=None, paginator=None):
|
|
267
|
+
# Different to ViewModeSerializer.get_component_context - which is a class method creating the instances
|
|
268
|
+
# this one will decorate existing instance with the appropriate values needed for rendering
|
|
269
|
+
# in all other respects, they are the same
|
|
270
|
+
|
|
271
|
+
request = request or self.request
|
|
272
|
+
paginator = paginator or self.context.get("view", type("NoView", (object,), dict(paginator=None))).paginator
|
|
273
|
+
|
|
274
|
+
if not self.view_mode:
|
|
275
|
+
self.view_mode = (
|
|
276
|
+
ViewModeSerializer.ViewMode.TABLE_ROW
|
|
277
|
+
if self.master and isinstance(self.master, ViewModeListSerializer)
|
|
278
|
+
else ViewModeSerializer.ViewMode.FORM
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
if not self.parent and "id" not in self.data:
|
|
282
|
+
def_kwargs = dict(pk=None)
|
|
283
|
+
else:
|
|
284
|
+
def_kwargs = dict(pk=self.data["id"] if not getattr(self, "parent", None) else "--record_id--")
|
|
285
|
+
|
|
286
|
+
self.reverse_url = self.get_reverse_url(
|
|
287
|
+
self.template_context["url_reverse"], request, self.template_context.get("url_reverse_kwargs", def_kwargs)
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# noinspection PyAbstractClass
|
|
292
|
+
class _ViewModeBoundSerializer(ViewModeSerializer, FieldRenderMixin, ActionMixin, Serializer):
|
|
293
|
+
"""
|
|
294
|
+
Dummy class just for type hinting
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
class FakeActionsList(list):
|
|
298
|
+
def renderable_actions(self, _unused):
|
|
299
|
+
return self
|
|
300
|
+
|
|
301
|
+
actions = FakeActionsList()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from typing import Optional, TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING:
|
|
6
|
+
from dynamicforms.serializers import DynamicFormsSerializer
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SerializerFilter(object):
|
|
10
|
+
def get_filter_serializer(self) -> Optional["DynamicFormsSerializer"]:
|
|
11
|
+
return self.filter_data if not self.is_filter else None
|
|
12
|
+
|
|
13
|
+
def filter_serializer_component_params(self) -> Optional[dict]:
|
|
14
|
+
filter_serializer: Optional["DynamicFormsSerializer"] = self.get_filter_serializer()
|
|
15
|
+
params: Optional[dict] = json.loads(filter_serializer.component_params()) if filter_serializer else None
|
|
16
|
+
if not params:
|
|
17
|
+
return None
|
|
18
|
+
params["uuid"] = self.uuid
|
|
19
|
+
return params
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Class that contains renderable fields for the templates.
|
|
3
|
+
The class provides transformation functionality
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Iterable
|
|
7
|
+
|
|
8
|
+
from dynamicforms.action import TableAction
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SerializerRenderActions(object):
|
|
12
|
+
@property
|
|
13
|
+
def actions(self) -> Iterable[TableAction]:
|
|
14
|
+
raise NotImplementedError("You must implement the actions property in your serializer render_actions method")
|
|
15
|
+
|
|
16
|
+
def as_action_def(self):
|
|
17
|
+
res = {action.name: action.as_component_def() for action in self.actions}
|
|
18
|
+
return res
|
|
19
|
+
|
|
20
|
+
def __aiter__(self):
|
|
21
|
+
return self.actions
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Class that contains renderable fields for the templates.
|
|
3
|
+
The class provides transformation functionality
|
|
4
|
+
"""
|
|
5
|
+
import uuid
|
|
6
|
+
|
|
7
|
+
from typing import Iterable
|
|
8
|
+
|
|
9
|
+
from django.utils.translation import gettext_lazy as _
|
|
10
|
+
|
|
11
|
+
from dynamicforms.action import TableAction, TablePosition
|
|
12
|
+
from dynamicforms.mixins import DisplayMode, FieldAlignment
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SerializerRenderFields(object):
|
|
16
|
+
@property
|
|
17
|
+
def fields(self):
|
|
18
|
+
raise NotImplementedError("You must implement the fields property in your serializer render_fields method")
|
|
19
|
+
|
|
20
|
+
def __aiter__(self):
|
|
21
|
+
return self.fields
|
|
22
|
+
|
|
23
|
+
class ActionField(object):
|
|
24
|
+
def __init__(self, actions: Iterable[TableAction], pos: TablePosition):
|
|
25
|
+
from collections.abc import Iterable as Itr
|
|
26
|
+
|
|
27
|
+
if not isinstance(actions, Itr) or not all(isinstance(action, TableAction) for action in actions):
|
|
28
|
+
raise AssertionError("Actions should be an iterable of TableAction")
|
|
29
|
+
actions = [action for action in actions if action.position == pos]
|
|
30
|
+
self.uuid = uuid.uuid1()
|
|
31
|
+
self.position = pos
|
|
32
|
+
self.actions = actions
|
|
33
|
+
self.field_name = "#actions-" + pos.name.lower()
|
|
34
|
+
self.label = _("Actions")
|
|
35
|
+
self.table_classes = ""
|
|
36
|
+
self.display_table = DisplayMode.FULL
|
|
37
|
+
self.alignment = FieldAlignment.LEFT
|
|
38
|
+
self.render_params = {}
|
|
39
|
+
|
|
40
|
+
# noinspection PyMethodMayBeStatic
|
|
41
|
+
def ordering(self):
|
|
42
|
+
return ""
|
|
43
|
+
|
|
44
|
+
def as_component_def(self) -> dict:
|
|
45
|
+
return dict(
|
|
46
|
+
uuid=self.uuid,
|
|
47
|
+
name=str(self.field_name),
|
|
48
|
+
label=str(self.label),
|
|
49
|
+
read_only=False,
|
|
50
|
+
alignment="right" if self.alignment == FieldAlignment.DECIMAL else self.alignment.name.lower(),
|
|
51
|
+
table_classes=self.table_classes,
|
|
52
|
+
ordering=self.ordering(),
|
|
53
|
+
render_params=self.render_params,
|
|
54
|
+
help_text="",
|
|
55
|
+
visibility=dict(table=self.display_table.value),
|
|
56
|
+
allow_null=False,
|
|
57
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
from rest_framework.renderers import JSONRenderer
|
|
4
|
+
from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def data_is_paginated(data):
|
|
8
|
+
return (
|
|
9
|
+
isinstance(data, dict)
|
|
10
|
+
and "next" in data
|
|
11
|
+
and "results" in data
|
|
12
|
+
and isinstance(data["results"], (ReturnList, ReturnDict))
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_serializer(data) -> Optional[Any]:
|
|
17
|
+
if data_is_paginated(data):
|
|
18
|
+
return data["results"].serializer
|
|
19
|
+
if isinstance(data, (ReturnList, ReturnDict)):
|
|
20
|
+
return data.serializer
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ComponentDefRenderer(JSONRenderer):
|
|
25
|
+
format = "componentdef"
|
|
26
|
+
|
|
27
|
+
def render(self, data, accepted_media_type=None, renderer_context=None):
|
|
28
|
+
serializer = get_serializer(data)
|
|
29
|
+
|
|
30
|
+
if serializer is None and isinstance(data, dict) and "detail" in data:
|
|
31
|
+
return super().render(data, accepted_media_type, renderer_context)
|
|
32
|
+
|
|
33
|
+
assert serializer is not None
|
|
34
|
+
|
|
35
|
+
serializer.apply_component_context()
|
|
36
|
+
component_params = serializer.component_params(output_json=False)
|
|
37
|
+
|
|
38
|
+
return super().render(component_params, accepted_media_type, renderer_context)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Responsive Table Layouts
|
|
3
|
+
|
|
4
|
+
Allows for declaring ever narrower row layouts that will be used when target viewPort is too narrow to display
|
|
5
|
+
all columns in one row. When this is detected, a layout will be selected that can still fit in the given width.
|
|
6
|
+
|
|
7
|
+
when all layouts are too wide, the most narrow one will be chosen.
|
|
8
|
+
|
|
9
|
+
This file has a counterpart in responsive-layout.js
|
|
10
|
+
"""
|
|
11
|
+
from typing import List, Optional, TYPE_CHECKING, Union
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from dynamicforms.serializers import Serializer
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class ColumnRow:
|
|
18
|
+
def __init__(self, columns: List[str]):
|
|
19
|
+
assert all((isinstance(column, str) for column in columns))
|
|
20
|
+
self.columns = columns
|
|
21
|
+
|
|
22
|
+
def as_component_def(self, serializer: "Serializer"):
|
|
23
|
+
return self.columns
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ColumnGroup:
|
|
27
|
+
def __init__(self, rows: Union[str, List[Union[str, List[str]]]]):
|
|
28
|
+
rows_list = [rows] if isinstance(rows, str) else rows
|
|
29
|
+
self.rows = [ColumnRow(row) for row in rows_list]
|
|
30
|
+
|
|
31
|
+
def as_component_def(self, serializer: "Serializer"):
|
|
32
|
+
return [row.as_component_def(serializer) for row in self.rows]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ResponsiveTableLayout:
|
|
36
|
+
def __init__(self, *columns: Union[str, List], auto_add_non_listed_columns: bool = True):
|
|
37
|
+
self.columns = [ColumnGroup(column) for column in columns]
|
|
38
|
+
self.auto_add_non_listed_columns = auto_add_non_listed_columns
|
|
39
|
+
|
|
40
|
+
def as_component_def(self, serializer: "Serializer"):
|
|
41
|
+
return dict(
|
|
42
|
+
columns=[column.as_component_def(serializer) for column in self.columns],
|
|
43
|
+
auto_add_non_listed_columns=self.auto_add_non_listed_columns,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ResponsiveTableLayouts:
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
auto_generate_single_row_layout: bool = True,
|
|
51
|
+
layouts: Optional[List[ResponsiveTableLayout]] = None,
|
|
52
|
+
auto_generate_single_column_layout: bool = True,
|
|
53
|
+
):
|
|
54
|
+
self.auto_generate_single_row_layout = auto_generate_single_row_layout
|
|
55
|
+
self.layouts = layouts or [] # type: List[ResponsiveTableLayout]
|
|
56
|
+
assert all((isinstance(layout, ResponsiveTableLayout) for layout in self.layouts))
|
|
57
|
+
self.auto_generate_single_column_layout = auto_generate_single_column_layout
|
|
58
|
+
|
|
59
|
+
def as_component_def(self, serializer: "Serializer"):
|
|
60
|
+
return dict(
|
|
61
|
+
auto_generate_single_row_layout=self.auto_generate_single_row_layout,
|
|
62
|
+
layouts=[layout.as_component_def(serializer) for layout in self.layouts],
|
|
63
|
+
auto_generate_single_column_layout=self.auto_generate_single_column_layout,
|
|
64
|
+
)
|
dynamicforms/urls.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from django.urls import re_path
|
|
2
|
+
|
|
3
|
+
from dynamicforms import preupload_files, progress
|
|
4
|
+
|
|
5
|
+
urlpatterns = [
|
|
6
|
+
# Progress is used for checking on progress of operation on server
|
|
7
|
+
re_path(r"^progress/$", progress.get_progress_value, name="progress"),
|
|
8
|
+
re_path(r"^preupload-file/$", preupload_files.preupload_file, name="preupload-file"),
|
|
9
|
+
]
|
dynamicforms/utils.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import traceback
|
|
3
|
+
|
|
4
|
+
from typing import Union
|
|
5
|
+
|
|
6
|
+
from django.db.models import Model, QuerySet
|
|
7
|
+
from rest_framework.utils.model_meta import get_field_info
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def get_pk_name(obj: Union[Model, QuerySet]):
|
|
11
|
+
if isinstance(obj, QuerySet):
|
|
12
|
+
return get_field_info(obj.model).pk.name
|
|
13
|
+
return get_field_info(obj).pk.name
|
|
14
|
+
|
|
15
|
+
def print_field_declaration_line():
|
|
16
|
+
"""
|
|
17
|
+
This method prints the line where the field has been declared
|
|
18
|
+
Must be called from field __init__
|
|
19
|
+
"""
|
|
20
|
+
print("WARNING: This field should be converted to AJAX.", file=sys.stderr)
|
|
21
|
+
# Iterate over the stack in reverse to find the first occurrence of "Serializer"
|
|
22
|
+
stack = traceback.extract_stack()
|
|
23
|
+
end_index = len(stack)
|
|
24
|
+
for i, frame in enumerate(stack, 0):
|
|
25
|
+
if "Serializer" in frame.name or "Serializer" in frame.line:
|
|
26
|
+
end_index = i
|
|
27
|
+
for frame in stack[end_index:end_index + 1]:
|
|
28
|
+
print(
|
|
29
|
+
f'File "{frame.filename}", line {frame.lineno}, in {frame.name}\n {frame.line.strip()}',
|
|
30
|
+
file=sys.stderr
|
|
31
|
+
)
|
|
32
|
+
|
dynamicforms/views.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# from django.shortcuts import render
|