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,52 @@
|
|
|
1
|
+
from html.parser import HTMLParser
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class RTFFieldMixin(object):
|
|
5
|
+
def __init__(self, *args, show_as_plain_text=False, plain_text_lines=3, plain_text_line_length=40, **kwargs):
|
|
6
|
+
super().__init__(*args, **kwargs)
|
|
7
|
+
self.parse = show_as_plain_text or False
|
|
8
|
+
self.max_lines = plain_text_lines
|
|
9
|
+
self.max_line_length = plain_text_line_length
|
|
10
|
+
self.parser = RTFFieldHTMLParser(max_lines=self.max_lines, max_line_length=self.max_line_length)
|
|
11
|
+
|
|
12
|
+
def to_representation(self, instance, row_data=None):
|
|
13
|
+
if not self.parent.is_filter:
|
|
14
|
+
self.style.update({"base_template": "rtf_field.html"})
|
|
15
|
+
if self.is_rendering_to_list and not self.parent.is_filter and self.parse:
|
|
16
|
+
self.parser.feed(instance)
|
|
17
|
+
instance = self.parser.to_string()
|
|
18
|
+
self.parser.reset()
|
|
19
|
+
|
|
20
|
+
return super().to_representation(instance, row_data)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class RTFFieldHTMLParser(HTMLParser):
|
|
24
|
+
def __init__(self, max_lines, max_line_length):
|
|
25
|
+
self.text = []
|
|
26
|
+
self.curr_line_count = 1
|
|
27
|
+
self.curr_line = ""
|
|
28
|
+
self.max_lines = max_lines
|
|
29
|
+
self.max_line_length = max_line_length
|
|
30
|
+
super(RTFFieldHTMLParser, self).__init__()
|
|
31
|
+
|
|
32
|
+
def handle_data(self, data):
|
|
33
|
+
text = data.strip()
|
|
34
|
+
if self.curr_line_count <= self.max_lines:
|
|
35
|
+
if len(text) > 0:
|
|
36
|
+
self.curr_line += " " + text
|
|
37
|
+
line = self.curr_line[0 : self.max_line_length - 3]
|
|
38
|
+
if len(self.curr_line) >= self.max_line_length - 3:
|
|
39
|
+
line += "..."
|
|
40
|
+
line += "<br>"
|
|
41
|
+
self.text.append(line)
|
|
42
|
+
self.curr_line = ""
|
|
43
|
+
self.curr_line_count += 1
|
|
44
|
+
|
|
45
|
+
def reset(self):
|
|
46
|
+
self.text = []
|
|
47
|
+
self.curr_line_count = 1
|
|
48
|
+
self.curr_line = ""
|
|
49
|
+
super(RTFFieldHTMLParser, self).reset()
|
|
50
|
+
|
|
51
|
+
def to_string(self):
|
|
52
|
+
return "".join(self.text).strip()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .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)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
import rest_framework.pagination as drf_p
|
|
5
|
+
|
|
6
|
+
from django.db.models import DurationField, Q
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CursorPagination(drf_p.CursorPagination):
|
|
10
|
+
ordering = "pk"
|
|
11
|
+
NONE_VALUE = "{`None`}"
|
|
12
|
+
|
|
13
|
+
# noinspection PyAttributeOutsideInit
|
|
14
|
+
def paginate_queryset(self, queryset, request, view=None):
|
|
15
|
+
self.page_size = self.get_page_size(request)
|
|
16
|
+
if not self.page_size:
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
self.base_url = request.build_absolute_uri()
|
|
20
|
+
self.ordering = self.get_ordering(request, queryset, view)
|
|
21
|
+
if "id" not in self.ordering and "-id" not in self.ordering:
|
|
22
|
+
ordering = list(self.ordering)
|
|
23
|
+
ordering.append("id")
|
|
24
|
+
self.ordering = tuple(ordering)
|
|
25
|
+
|
|
26
|
+
self.cursor = self.decode_cursor(request)
|
|
27
|
+
if self.cursor is None:
|
|
28
|
+
(offset, reverse, current_position) = (0, False, None)
|
|
29
|
+
else:
|
|
30
|
+
(offset, reverse, current_position) = self.cursor
|
|
31
|
+
try:
|
|
32
|
+
if current_position:
|
|
33
|
+
current_position = json.loads(current_position)
|
|
34
|
+
except TypeError:
|
|
35
|
+
current_position = None
|
|
36
|
+
|
|
37
|
+
# Cursor pagination always enforces an ordering.
|
|
38
|
+
if reverse:
|
|
39
|
+
queryset = queryset.order_by(*drf_p._reverse_ordering(self.ordering))
|
|
40
|
+
else:
|
|
41
|
+
queryset = queryset.order_by(*self.ordering)
|
|
42
|
+
|
|
43
|
+
# If we have a cursor with a fixed position then filter by that.
|
|
44
|
+
if current_position is not None:
|
|
45
|
+
|
|
46
|
+
def filter_segment(segment_len):
|
|
47
|
+
kwargs = {}
|
|
48
|
+
for idx in range(segment_len):
|
|
49
|
+
order = self.ordering[idx]
|
|
50
|
+
is_reversed = order.startswith("-")
|
|
51
|
+
order_attr = order.lstrip("-")
|
|
52
|
+
attr_value = self.field_to_python(queryset, order_attr, current_position[order_attr])
|
|
53
|
+
|
|
54
|
+
# Test for: (cursor reversed) XOR (queryset reversed)
|
|
55
|
+
if idx < segment_len - 1:
|
|
56
|
+
# if this is the last field in this segment
|
|
57
|
+
if attr_value == self.NONE_VALUE:
|
|
58
|
+
kwargs[order_attr + "__isnull"] = True
|
|
59
|
+
else:
|
|
60
|
+
kwargs[order_attr] = attr_value
|
|
61
|
+
elif self.cursor.reverse != is_reversed:
|
|
62
|
+
if attr_value == self.NONE_VALUE:
|
|
63
|
+
kwargs[order_attr + "__isnull"] = False
|
|
64
|
+
else:
|
|
65
|
+
kwargs[order_attr + "__lt"] = attr_value
|
|
66
|
+
else:
|
|
67
|
+
if attr_value == self.NONE_VALUE:
|
|
68
|
+
# It just doesn't go higher than None... so we use some impossible to reach filter
|
|
69
|
+
kwargs["id"] = -1
|
|
70
|
+
else:
|
|
71
|
+
kwargs[order_attr + "__gt"] = attr_value
|
|
72
|
+
|
|
73
|
+
return Q(**kwargs)
|
|
74
|
+
|
|
75
|
+
fltr = Q()
|
|
76
|
+
for seg_len in range(len(self.ordering)):
|
|
77
|
+
fltr = fltr | filter_segment(seg_len + 1)
|
|
78
|
+
|
|
79
|
+
queryset = queryset.filter(fltr)
|
|
80
|
+
|
|
81
|
+
# If we have an offset cursor then offset the entire page by that amount.
|
|
82
|
+
# We also always fetch an extra item in order to determine if there is a
|
|
83
|
+
# page following on from this one.
|
|
84
|
+
results = list(queryset[offset : offset + self.page_size + 1])
|
|
85
|
+
self.page = list(results[: self.page_size])
|
|
86
|
+
if not self.page:
|
|
87
|
+
# In rest_framework/pagination.py/get_previous_link is expected that self.page is not empty
|
|
88
|
+
# if cursor offset != 0
|
|
89
|
+
self.cursor = drf_p.Cursor(offset=0, reverse=False, position=None)
|
|
90
|
+
|
|
91
|
+
# DF: contrary to DRF's implementation we always provide the "prev" and "next" links as there may appear
|
|
92
|
+
# new records before / after the ones we already read. Mechanism for detecting whether they actually appeared
|
|
93
|
+
# is another matter altogether :)
|
|
94
|
+
if current_position is None and results:
|
|
95
|
+
self.cursor = drf_p.Cursor(offset=0, reverse=False, position=None)
|
|
96
|
+
current_position = self._get_position_from_instance(results[0], self.ordering)
|
|
97
|
+
elif isinstance(current_position, dict):
|
|
98
|
+
current_position = json.dumps(current_position)
|
|
99
|
+
|
|
100
|
+
# Determine the position of the final item following the page.
|
|
101
|
+
has_following_position = True # len(results) > len(self.page)
|
|
102
|
+
|
|
103
|
+
# DF: contrary to DRF's implementation we always provide the "next" link as there may appear new records after
|
|
104
|
+
# the last one read
|
|
105
|
+
following_position = self._get_position_from_instance(results[-1], self.ordering) if results else None
|
|
106
|
+
|
|
107
|
+
if reverse:
|
|
108
|
+
# If we have a reverse queryset, then the query ordering was in reverse
|
|
109
|
+
# so we need to reverse the items again before returning them to the user.
|
|
110
|
+
self.page = list(reversed(self.page))
|
|
111
|
+
|
|
112
|
+
# Determine next and previous positions for reverse cursors.
|
|
113
|
+
self.has_next = (current_position is not None) or (offset > 0)
|
|
114
|
+
self.has_previous = has_following_position
|
|
115
|
+
if self.has_next:
|
|
116
|
+
self.next_position = current_position
|
|
117
|
+
if self.has_previous:
|
|
118
|
+
self.previous_position = following_position
|
|
119
|
+
else:
|
|
120
|
+
# Determine next and previous positions for forward cursors.
|
|
121
|
+
self.has_next = has_following_position
|
|
122
|
+
self.has_previous = (current_position is not None) or (offset > 0)
|
|
123
|
+
if self.has_next:
|
|
124
|
+
self.next_position = following_position
|
|
125
|
+
if self.has_previous:
|
|
126
|
+
self.previous_position = current_position
|
|
127
|
+
|
|
128
|
+
# Display page controls in the browsable API if there is more
|
|
129
|
+
# than one page.
|
|
130
|
+
if (self.has_previous or self.has_next) and self.template is not None:
|
|
131
|
+
self.display_page_controls = True
|
|
132
|
+
|
|
133
|
+
return self.page
|
|
134
|
+
|
|
135
|
+
def _get_position_from_instance(self, instance, ordering):
|
|
136
|
+
def process_field(idx):
|
|
137
|
+
field_name = ordering[idx].lstrip("-")
|
|
138
|
+
attr = None
|
|
139
|
+
if isinstance(instance, dict):
|
|
140
|
+
attr = instance[field_name]
|
|
141
|
+
else:
|
|
142
|
+
field_name_list = field_name.split("__")
|
|
143
|
+
for fn in field_name_list:
|
|
144
|
+
attr = getattr(instance if attr is None else attr, fn)
|
|
145
|
+
return field_name, self.field_to_representation(attr)
|
|
146
|
+
|
|
147
|
+
return json.dumps({k: v for k, v in map(lambda idx: process_field(idx), range(len(ordering)))})
|
|
148
|
+
|
|
149
|
+
def field_to_representation(self, value):
|
|
150
|
+
"""
|
|
151
|
+
Converts field value to something that will be later understood by QuerySet.filter()
|
|
152
|
+
Question: why does DRF not do this? is str(value) always enough?
|
|
153
|
+
"""
|
|
154
|
+
if isinstance(value, datetime.timedelta):
|
|
155
|
+
return str(value.total_seconds())
|
|
156
|
+
elif value is None:
|
|
157
|
+
return self.NONE_VALUE
|
|
158
|
+
return str(value)
|
|
159
|
+
|
|
160
|
+
def field_to_python(self, queryset, order_attr, value):
|
|
161
|
+
if order_attr in queryset.query.annotations:
|
|
162
|
+
field = queryset.query.annotations.get(order_attr).field
|
|
163
|
+
else:
|
|
164
|
+
# noinspection PyProtectedMember
|
|
165
|
+
field = queryset.model._meta.get_field(order_attr)
|
|
166
|
+
if isinstance(field, DurationField):
|
|
167
|
+
return datetime.timedelta(seconds=float(value))
|
|
168
|
+
return value
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
from django.core.cache import cache
|
|
2
|
+
from django.http import HttpResponse
|
|
3
|
+
from rest_framework.renderers import JSONRenderer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_progress_value(request):
|
|
7
|
+
"""
|
|
8
|
+
Returns operations progress to HTTP client
|
|
9
|
+
|
|
10
|
+
:param request:
|
|
11
|
+
:return: Progress in percentages (0 - 100) if progress is set else None
|
|
12
|
+
"""
|
|
13
|
+
progress_key = get_progress_key(request)
|
|
14
|
+
value = None
|
|
15
|
+
if progress_key is not None:
|
|
16
|
+
cache_value = cache.get("df_progress.%s" % progress_key)
|
|
17
|
+
if cache_value is not None:
|
|
18
|
+
value = "%.2f" % cache.get("df_progress.%s" % progress_key)
|
|
19
|
+
|
|
20
|
+
return HttpResponse(
|
|
21
|
+
JSONRenderer().render(dict(value=value, comment=cache.get("df_progress_comment.%s" % progress_key))),
|
|
22
|
+
content_type="application/json",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_progress_key(request):
|
|
27
|
+
"""
|
|
28
|
+
Gets progress/operation key under which operation progress will be stored in servers cache.
|
|
29
|
+
:param request:
|
|
30
|
+
:return: Progress key or None if there is no x_df_timestamp in request header
|
|
31
|
+
"""
|
|
32
|
+
timestamp = request.META.get("HTTP_X_DF_TIMESTAMP", request.GET.get("x_df_timestamp", None))
|
|
33
|
+
if timestamp is not None:
|
|
34
|
+
return "%s|%s" % (timestamp, request.session.session_key)
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def set_progress_value(progress_key, value):
|
|
39
|
+
"""
|
|
40
|
+
Updates operations progress
|
|
41
|
+
|
|
42
|
+
:param progress_key: Key under which operations progress is stored
|
|
43
|
+
:param value: Progress in percentages (0.00 - 100.00)
|
|
44
|
+
:return:
|
|
45
|
+
"""
|
|
46
|
+
if progress_key is not None:
|
|
47
|
+
cache.set("df_progress.%s" % progress_key, value)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def add_progress_value(progress_key, value):
|
|
51
|
+
"""
|
|
52
|
+
Updates operations progress by adding to existing progress value
|
|
53
|
+
|
|
54
|
+
:param progress_key: Key under which operations progress is stored
|
|
55
|
+
:param value: Progress in percentages (0.00 - 100.00)
|
|
56
|
+
:return:
|
|
57
|
+
"""
|
|
58
|
+
if progress_key is not None:
|
|
59
|
+
cache.set("df_progress.%s" % progress_key, cache.get("df_progress.%s" % progress_key, 0) + value)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def set_progress_comment(progress_key, value):
|
|
63
|
+
"""
|
|
64
|
+
Updates operations comment
|
|
65
|
+
|
|
66
|
+
:param progress_key: Key under which operations progress is stored
|
|
67
|
+
:param value: comment
|
|
68
|
+
:return:
|
|
69
|
+
"""
|
|
70
|
+
if progress_key is not None:
|
|
71
|
+
cache.set("df_progress_comment.%s" % progress_key, value)
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
import six
|
|
4
|
+
|
|
5
|
+
from django.template import loader
|
|
6
|
+
from django.utils.safestring import mark_safe
|
|
7
|
+
from rest_framework.renderers import HTMLFormRenderer, TemplateHTMLRenderer
|
|
8
|
+
from rest_framework.serializers import HiddenField, ListSerializer
|
|
9
|
+
from rest_framework.utils.serializer_helpers import ReturnDict, ReturnList
|
|
10
|
+
|
|
11
|
+
from dynamicforms_legacy.fields import BooleanField
|
|
12
|
+
|
|
13
|
+
from .settings import DYNAMICFORMS
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# noinspection PyRedeclaration
|
|
17
|
+
class TemplateHTMLRenderer(TemplateHTMLRenderer):
|
|
18
|
+
"""
|
|
19
|
+
Renderers serializer data into an HTML form.
|
|
20
|
+
|
|
21
|
+
If the serializer was instantiated without an object then this will
|
|
22
|
+
return an HTML form not bound to any object,
|
|
23
|
+
otherwise it will return an HTML form with the appropriate initial data
|
|
24
|
+
populated from the object.
|
|
25
|
+
|
|
26
|
+
Note that rendering of field and form errors is not currently supported.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def render(self, data, accepted_media_type=None, renderer_context=None):
|
|
30
|
+
link_next = link_prev = ""
|
|
31
|
+
|
|
32
|
+
if (
|
|
33
|
+
isinstance(data, dict)
|
|
34
|
+
and "next" in data
|
|
35
|
+
and "results" in data
|
|
36
|
+
and isinstance(data["results"], (ReturnList, ReturnDict))
|
|
37
|
+
):
|
|
38
|
+
# This is in case of Pagination
|
|
39
|
+
link_next = mark_safe(data.get("next", ""))
|
|
40
|
+
link_prev = mark_safe(data.get("previous", ""))
|
|
41
|
+
data = data["results"]
|
|
42
|
+
if isinstance(data, (ReturnList, ReturnDict)):
|
|
43
|
+
ser = data.serializer
|
|
44
|
+
data = dict(
|
|
45
|
+
data=data,
|
|
46
|
+
serializer=ser.child if isinstance(ser, ListSerializer) else ser,
|
|
47
|
+
link_next=link_next,
|
|
48
|
+
link_prev=link_prev,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
if getattr(ser, "_errors", {}):
|
|
52
|
+
# CAUTION: bad hacks start here. This should be removed at some point
|
|
53
|
+
|
|
54
|
+
# unmark exception from response because this was a validation error
|
|
55
|
+
# This will allow TemplateHTMLRenderer to still render the template as if it was without problems
|
|
56
|
+
# If this is not done, the only result user will see will be a 404 error without any details
|
|
57
|
+
response = renderer_context["response"]
|
|
58
|
+
response.exception = False
|
|
59
|
+
|
|
60
|
+
# result data should be object data otherwise nothing will render...
|
|
61
|
+
data["data"] = data["serializer"].data
|
|
62
|
+
|
|
63
|
+
return super().render(data, accepted_media_type, renderer_context)
|
|
64
|
+
|
|
65
|
+
def get_template_names(self, response, view):
|
|
66
|
+
if view.render_type == "page" and DYNAMICFORMS.page_template:
|
|
67
|
+
return [DYNAMICFORMS.page_template]
|
|
68
|
+
return super().get_template_names(response, view)
|
|
69
|
+
|
|
70
|
+
def get_template_context(self, data, renderer_context):
|
|
71
|
+
res = super().get_template_context(data, renderer_context)
|
|
72
|
+
view = renderer_context["view"]
|
|
73
|
+
if hasattr(view, "template_context"):
|
|
74
|
+
if callable(view.template_context):
|
|
75
|
+
res.update(view.template_context())
|
|
76
|
+
else:
|
|
77
|
+
res.update(view.template_context)
|
|
78
|
+
res["df_render_type"] = view.render_type # This one should not fail because it's set in initialize_request
|
|
79
|
+
res["DYNAMICFORMS"] = DYNAMICFORMS
|
|
80
|
+
return res
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
# noinspection PyRedeclaration
|
|
84
|
+
class HTMLFormRenderer(HTMLFormRenderer):
|
|
85
|
+
"""
|
|
86
|
+
An HTML renderer for use with templates.
|
|
87
|
+
|
|
88
|
+
The data supplied to the Response object should be a dictionary that will
|
|
89
|
+
be used as context for the template.
|
|
90
|
+
|
|
91
|
+
The template name is determined by (in order of preference):
|
|
92
|
+
|
|
93
|
+
1. An explicit `.template_name` attribute set on the response.
|
|
94
|
+
2. An explicit `.template_name` attribute set on this class.
|
|
95
|
+
3. The return result of calling `view.get_template_names()`.
|
|
96
|
+
|
|
97
|
+
For example:
|
|
98
|
+
data = {'users': User.objects.all()}
|
|
99
|
+
return Response(data, template_name='users.html')
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
def render_field(self, field, parent_style):
|
|
103
|
+
# noinspection PyProtectedMember
|
|
104
|
+
if isinstance(field._field, HiddenField):
|
|
105
|
+
return ""
|
|
106
|
+
|
|
107
|
+
if isinstance(field._field, BooleanField):
|
|
108
|
+
# allow also null to have max values available for determening the right value to render
|
|
109
|
+
allow_null = copy.copy(field._field.allow_null)
|
|
110
|
+
field._field.allow_null = True
|
|
111
|
+
field.value = field._field.to_internal_value(field.value)
|
|
112
|
+
field._field.allow_null = allow_null
|
|
113
|
+
|
|
114
|
+
style = dict(self.default_style[field])
|
|
115
|
+
style.update(field.style)
|
|
116
|
+
if "template_pack" not in style:
|
|
117
|
+
style["template_pack"] = parent_style.get("template_pack", self.template_pack)
|
|
118
|
+
style["serializer"] = parent_style.get("serializer", None)
|
|
119
|
+
style["renderer"] = self
|
|
120
|
+
|
|
121
|
+
# Get a clone of the field with text-only value representation.
|
|
122
|
+
field = field.as_form_field()
|
|
123
|
+
|
|
124
|
+
if style.get("input_type") == "datetime-local" and isinstance(field.value, six.text_type):
|
|
125
|
+
field.value = field.value.rstrip("Z")
|
|
126
|
+
|
|
127
|
+
if "template" in style:
|
|
128
|
+
template_name = style["template"]
|
|
129
|
+
else:
|
|
130
|
+
template_name = style["template_pack"].strip("/") + "/" + style["base_template"]
|
|
131
|
+
|
|
132
|
+
template = loader.get_template(template_name)
|
|
133
|
+
context = {
|
|
134
|
+
"field": field,
|
|
135
|
+
"style": style,
|
|
136
|
+
"DYNAMICFORMS": DYNAMICFORMS,
|
|
137
|
+
}
|
|
138
|
+
try:
|
|
139
|
+
context.update(style["serializer"].context["view"].template_context)
|
|
140
|
+
except:
|
|
141
|
+
pass
|
|
142
|
+
return template.render(context)
|
|
143
|
+
|
|
144
|
+
# Jure: had to copy this one over to support custom template as parameter + DF context variable
|
|
145
|
+
def render(self, data, accepted_media_type=None, renderer_context=None):
|
|
146
|
+
"""
|
|
147
|
+
Render serializer data and return an HTML form, as a string.
|
|
148
|
+
"""
|
|
149
|
+
renderer_context = renderer_context or {}
|
|
150
|
+
form = data.serializer
|
|
151
|
+
|
|
152
|
+
style = renderer_context.get("style", {})
|
|
153
|
+
style["template_pack"] = DYNAMICFORMS.template_root + "field"
|
|
154
|
+
style["renderer"] = self
|
|
155
|
+
|
|
156
|
+
template_pack = style["template_pack"].strip("/")
|
|
157
|
+
|
|
158
|
+
# getting the template to use
|
|
159
|
+
template_name = next(
|
|
160
|
+
(
|
|
161
|
+
x
|
|
162
|
+
for x in ( # Get the first specified template name as encountered
|
|
163
|
+
style.get("form_template", None), # template name from tag parameter
|
|
164
|
+
getattr(self, "form_template", None), # if ViewSet set the form_template member of this renderer
|
|
165
|
+
getattr(form, "form_template", None), # if Serializer has form_template member set
|
|
166
|
+
template_pack + "/" + self.base_template, # take default template from pack
|
|
167
|
+
)
|
|
168
|
+
if x
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
template = loader.get_template(template_name)
|
|
173
|
+
context = {
|
|
174
|
+
"form": form,
|
|
175
|
+
"style": style,
|
|
176
|
+
"DYNAMICFORMS": DYNAMICFORMS,
|
|
177
|
+
}
|
|
178
|
+
context.update(getattr(form, "template_context", {}))
|
|
179
|
+
try:
|
|
180
|
+
context.update(form.context["view"].template_context)
|
|
181
|
+
except:
|
|
182
|
+
pass
|
|
183
|
+
return template.render(context)
|