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.
Files changed (287) hide show
  1. dynamicforms/__init__.py +8 -0
  2. dynamicforms/action.py +521 -0
  3. dynamicforms/apps.py +5 -0
  4. dynamicforms/fields.py +1570 -0
  5. dynamicforms/filters.py +44 -0
  6. dynamicforms/locale/en/LC_MESSAGES/django.po +67 -0
  7. dynamicforms/locale/en/LC_MESSAGES/djangojs.po +31 -0
  8. dynamicforms/locale/sl/LC_MESSAGES/django.po +71 -0
  9. dynamicforms/locale/sl/LC_MESSAGES/djangojs.po +36 -0
  10. dynamicforms/management/__init__.py +0 -0
  11. dynamicforms/management/commands/__init__.py +0 -0
  12. dynamicforms/management/commands/clean_dfpreuploaded_files.py +26 -0
  13. dynamicforms/migrations/__init__.py +0 -0
  14. dynamicforms/mixins/__init__.py +27 -0
  15. dynamicforms/mixins/action.py +14 -0
  16. dynamicforms/mixins/choice/__init__.py +94 -0
  17. dynamicforms/mixins/choice/allow_tags.py +79 -0
  18. dynamicforms/mixins/choice/null_choice.py +26 -0
  19. dynamicforms/mixins/choice/single_choice.py +21 -0
  20. dynamicforms/mixins/color_field.py +4 -0
  21. dynamicforms/mixins/conditional_visibility.py +193 -0
  22. dynamicforms/mixins/enable_copy.py +4 -0
  23. dynamicforms/mixins/field_render.py +209 -0
  24. dynamicforms/mixins/file_field.py +5 -0
  25. dynamicforms/mixins/help_text.py +46 -0
  26. dynamicforms/mixins/implicit_hidden.py +7 -0
  27. dynamicforms/mixins/implicit_natural_date.py +88 -0
  28. dynamicforms/mixins/null_value.py +15 -0
  29. dynamicforms/mixins/password_field.py +23 -0
  30. dynamicforms/mixins/related_field_ajax.py +142 -0
  31. dynamicforms/mixins/rtf_field.py +58 -0
  32. dynamicforms/models.py +5 -0
  33. dynamicforms/models_utils.py +33 -0
  34. dynamicforms/pagination.py +175 -0
  35. dynamicforms/preupload_files.py +42 -0
  36. dynamicforms/progress.py +71 -0
  37. dynamicforms/renderers.py +1 -0
  38. dynamicforms/routers.py +36 -0
  39. dynamicforms/serializers.py +486 -0
  40. dynamicforms/struct.py +40 -0
  41. dynamicforms/template_render/__init__.py +10 -0
  42. dynamicforms/template_render/layout.py +178 -0
  43. dynamicforms/template_render/mixins/__init__.py +0 -0
  44. dynamicforms/template_render/mixins/base.py +39 -0
  45. dynamicforms/template_render/mixins/field.py +74 -0
  46. dynamicforms/template_render/mixins/listserializer.py +100 -0
  47. dynamicforms/template_render/mixins/render_mode_enum.py +8 -0
  48. dynamicforms/template_render/mixins/serializer.py +301 -0
  49. dynamicforms/template_render/mixins/serializer_filter.py +19 -0
  50. dynamicforms/template_render/mixins/serializer_render_actions.py +21 -0
  51. dynamicforms/template_render/mixins/serializer_render_fields.py +57 -0
  52. dynamicforms/template_render/mixins/util.py +9 -0
  53. dynamicforms/template_render/renderer.py +38 -0
  54. dynamicforms/template_render/responsive_table_layout.py +64 -0
  55. dynamicforms/urls.py +9 -0
  56. dynamicforms/utils.py +32 -0
  57. dynamicforms/views.py +1 -0
  58. dynamicforms/viewsets.py +421 -0
  59. dynamicforms-0.76.14.dist-info/METADATA +129 -0
  60. dynamicforms-0.76.14.dist-info/RECORD +287 -0
  61. dynamicforms-0.76.14.dist-info/WHEEL +4 -0
  62. dynamicforms-0.76.14.dist-info/licenses/LICENSE +21 -0
  63. dynamicforms_legacy/__init__.py +8 -0
  64. dynamicforms_legacy/action.py +561 -0
  65. dynamicforms_legacy/apps.py +5 -0
  66. dynamicforms_legacy/context_processors.py +27 -0
  67. dynamicforms_legacy/dynamicforms_migration_mixin.py +42 -0
  68. dynamicforms_legacy/fields.py +1108 -0
  69. dynamicforms_legacy/filters.py +44 -0
  70. dynamicforms_legacy/migrations/__init__.py +0 -0
  71. dynamicforms_legacy/mixins/__init__.py +16 -0
  72. dynamicforms_legacy/mixins/action.py +14 -0
  73. dynamicforms_legacy/mixins/allow_tags.py +85 -0
  74. dynamicforms_legacy/mixins/enable_copy.py +4 -0
  75. dynamicforms_legacy/mixins/file_field.py +5 -0
  76. dynamicforms_legacy/mixins/help_text.py +38 -0
  77. dynamicforms_legacy/mixins/implicit_hidden.py +7 -0
  78. dynamicforms_legacy/mixins/implicit_natural_date.py +86 -0
  79. dynamicforms_legacy/mixins/null_choice.py +26 -0
  80. dynamicforms_legacy/mixins/null_value.py +15 -0
  81. dynamicforms_legacy/mixins/password_field.py +19 -0
  82. dynamicforms_legacy/mixins/related_field_ajax.py +58 -0
  83. dynamicforms_legacy/mixins/render.py +203 -0
  84. dynamicforms_legacy/mixins/rtf_field.py +52 -0
  85. dynamicforms_legacy/mixins/single_choice.py +21 -0
  86. dynamicforms_legacy/models.py +5 -0
  87. dynamicforms_legacy/pagination.py +168 -0
  88. dynamicforms_legacy/progress.py +71 -0
  89. dynamicforms_legacy/renderers.py +183 -0
  90. dynamicforms_legacy/serializers.py +335 -0
  91. dynamicforms_legacy/settings.py +196 -0
  92. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css +587 -0
  93. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.css.map +1 -0
  94. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css +6 -0
  95. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap-theme.min.css.map +1 -0
  96. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css +6834 -0
  97. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.css.map +1 -0
  98. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css +6 -0
  99. dynamicforms_legacy/static/bootstrap-3.4.1-dist/css/bootstrap.min.css.map +1 -0
  100. dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.eot +0 -0
  101. dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.svg +288 -0
  102. dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.ttf +0 -0
  103. dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff +0 -0
  104. dynamicforms_legacy/static/bootstrap-3.4.1-dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
  105. dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.js +2580 -0
  106. dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/bootstrap.min.js +6 -0
  107. dynamicforms_legacy/static/bootstrap-3.4.1-dist/js/npm.js +13 -0
  108. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css +3719 -0
  109. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.css.map +1 -0
  110. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css +7 -0
  111. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-grid.min.css.map +1 -0
  112. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css +331 -0
  113. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.css.map +1 -0
  114. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css +8 -0
  115. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap-reboot.min.css.map +1 -0
  116. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css +10038 -0
  117. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.css.map +1 -0
  118. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css +7 -0
  119. dynamicforms_legacy/static/bootstrap-4.3.1-dist/css/bootstrap.min.css.map +1 -0
  120. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js +7013 -0
  121. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.js.map +1 -0
  122. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js +7 -0
  123. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.bundle.min.js.map +1 -0
  124. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js +4435 -0
  125. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.js.map +1 -0
  126. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js +7 -0
  127. dynamicforms_legacy/static/bootstrap-4.3.1-dist/js/bootstrap.min.js.map +1 -0
  128. dynamicforms_legacy/static/ckeditor-df/ckEditorCustomBuildReadMe.txt +255 -0
  129. dynamicforms_legacy/static/ckeditor-df/ckeditor.js +6 -0
  130. dynamicforms_legacy/static/dynamicforms/dynamicforms.js +1883 -0
  131. dynamicforms_legacy/static/dynamicforms/icons/copy.svg +7 -0
  132. dynamicforms_legacy/static/dynamicforms/icons/eye-off-outline.svg +10 -0
  133. dynamicforms_legacy/static/dynamicforms/icons/eye-outline.svg +7 -0
  134. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  135. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  136. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  137. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  138. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  139. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  140. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  141. dynamicforms_legacy/static/jquery_ui/css/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  142. dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_222222_256x240.png +0 -0
  143. dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_228ef1_256x240.png +0 -0
  144. dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ef8c08_256x240.png +0 -0
  145. dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffd27a_256x240.png +0 -0
  146. dynamicforms_legacy/static/jquery_ui/css/images/ui-icons_ffffff_256x240.png +0 -0
  147. dynamicforms_legacy/static/jquery_ui/css/jquery-ui.min.css +7 -0
  148. dynamicforms_legacy/static/jquery_ui/css/jquery-ui.structure.min.css +5 -0
  149. dynamicforms_legacy/static/jquery_ui/css/jquery-ui.theme.min.css +5 -0
  150. dynamicforms_legacy/static/jquery_ui/js/jquery-3.3.1.min.js +2 -0
  151. dynamicforms_legacy/static/jquery_ui/js/jquery-ui.min.js +13 -0
  152. dynamicforms_legacy/static/select2/css/select2-bootstrap3.min.css +7 -0
  153. dynamicforms_legacy/static/select2/css/select2-bootstrap4.min.css +578 -0
  154. dynamicforms_legacy/static/select2/select2-4.0.5/css/select2.min.css +1 -0
  155. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/af.js +3 -0
  156. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ar.js +3 -0
  157. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/az.js +3 -0
  158. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bg.js +3 -0
  159. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/bs.js +3 -0
  160. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ca.js +3 -0
  161. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/cs.js +3 -0
  162. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/da.js +3 -0
  163. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/de.js +3 -0
  164. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/dsb.js +3 -0
  165. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/el.js +3 -0
  166. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/en.js +3 -0
  167. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/es.js +3 -0
  168. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/et.js +3 -0
  169. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/eu.js +3 -0
  170. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fa.js +3 -0
  171. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fi.js +3 -0
  172. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/fr.js +3 -0
  173. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/gl.js +3 -0
  174. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/he.js +3 -0
  175. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hi.js +3 -0
  176. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hr.js +3 -0
  177. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hsb.js +3 -0
  178. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hu.js +3 -0
  179. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/hy.js +3 -0
  180. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/id.js +3 -0
  181. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/is.js +3 -0
  182. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/it.js +3 -0
  183. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ja.js +3 -0
  184. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/km.js +3 -0
  185. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ko.js +3 -0
  186. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lt.js +3 -0
  187. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/lv.js +3 -0
  188. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/mk.js +3 -0
  189. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ms.js +3 -0
  190. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nb.js +3 -0
  191. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/nl.js +3 -0
  192. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pl.js +3 -0
  193. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ps.js +3 -0
  194. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt-BR.js +3 -0
  195. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/pt.js +3 -0
  196. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ro.js +3 -0
  197. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/ru.js +3 -0
  198. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sk.js +3 -0
  199. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sl.js +3 -0
  200. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr-Cyrl.js +3 -0
  201. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sr.js +3 -0
  202. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/sv.js +3 -0
  203. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/th.js +3 -0
  204. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/tr.js +3 -0
  205. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/uk.js +3 -0
  206. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/vi.js +3 -0
  207. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-CN.js +3 -0
  208. dynamicforms_legacy/static/select2/select2-4.0.5/js/i18n/zh-TW.js +3 -0
  209. dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.js +6457 -0
  210. dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.full.min.js +1 -0
  211. dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.js +5746 -0
  212. dynamicforms_legacy/static/select2/select2-4.0.5/js/select2.min.js +1 -0
  213. dynamicforms_legacy/struct.py +40 -0
  214. dynamicforms_legacy/templates/dynamicforms/base.html +12 -0
  215. dynamicforms_legacy/templates/dynamicforms/base_form.html +44 -0
  216. dynamicforms_legacy/templates/dynamicforms/base_includes.html +51 -0
  217. dynamicforms_legacy/templates/dynamicforms/base_includes_select2.html +6 -0
  218. dynamicforms_legacy/templates/dynamicforms/base_list.html +47 -0
  219. dynamicforms_legacy/templates/dynamicforms/base_table_body.html +46 -0
  220. dynamicforms_legacy/templates/dynamicforms/base_table_filter.html +44 -0
  221. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_form.html +10 -0
  222. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes.html +46 -0
  223. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v3.html +90 -0
  224. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_includes_v4.html +77 -0
  225. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_list.html +9 -0
  226. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_body.html +4 -0
  227. dynamicforms_legacy/templates/dynamicforms/bootstrap/base_table_filter.html +5 -0
  228. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field.html +41 -0
  229. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v3.html +11 -0
  230. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/base_field_v4.html +11 -0
  231. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox.html +7 -0
  232. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/checkbox_multiple.html +7 -0
  233. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/fieldset.html +21 -0
  234. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/form.html +4 -0
  235. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/input.html +31 -0
  236. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/list_fieldset.html +18 -0
  237. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/radio.html +8 -0
  238. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/rtf_field.html +4 -0
  239. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select.html +46 -0
  240. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/select_multiple.html +17 -0
  241. dynamicforms_legacy/templates/dynamicforms/bootstrap/field/textarea.html +4 -0
  242. dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog.html +13 -0
  243. dynamicforms_legacy/templates/dynamicforms/bootstrap/modal_dialog_rest.html +23 -0
  244. dynamicforms_legacy/templates/dynamicforms/bootstrap/page.html +11 -0
  245. dynamicforms_legacy/templates/dynamicforms/field/base_field.html +55 -0
  246. dynamicforms_legacy/templates/dynamicforms/field/checkbox.html +28 -0
  247. dynamicforms_legacy/templates/dynamicforms/field/checkbox_multiple.html +16 -0
  248. dynamicforms_legacy/templates/dynamicforms/field/dict_field.html +4 -0
  249. dynamicforms_legacy/templates/dynamicforms/field/fieldset.html +4 -0
  250. dynamicforms_legacy/templates/dynamicforms/field/form.html +18 -0
  251. dynamicforms_legacy/templates/dynamicforms/field/input.html +31 -0
  252. dynamicforms_legacy/templates/dynamicforms/field/list_field.html +4 -0
  253. dynamicforms_legacy/templates/dynamicforms/field/list_fieldset.html +4 -0
  254. dynamicforms_legacy/templates/dynamicforms/field/radio.html +24 -0
  255. dynamicforms_legacy/templates/dynamicforms/field/rtf_field.html +14 -0
  256. dynamicforms_legacy/templates/dynamicforms/field/select.html +97 -0
  257. dynamicforms_legacy/templates/dynamicforms/field/select_multiple.html +67 -0
  258. dynamicforms_legacy/templates/dynamicforms/field/textarea.html +13 -0
  259. dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_form.html +13 -0
  260. dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_includes.html +225 -0
  261. dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_list.html +9 -0
  262. dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_body.html +4 -0
  263. dynamicforms_legacy/templates/dynamicforms/jquery_ui/base_table_filter.html +5 -0
  264. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/base_field.html +16 -0
  265. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox.html +7 -0
  266. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/checkbox_multiple.html +9 -0
  267. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/fieldset.html +11 -0
  268. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/form.html +4 -0
  269. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/input.html +17 -0
  270. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/list_fieldset.html +6 -0
  271. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/radio.html +8 -0
  272. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/rtf_field.html +4 -0
  273. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select.html +37 -0
  274. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/select_multiple.html +18 -0
  275. dynamicforms_legacy/templates/dynamicforms/jquery_ui/field/textarea.html +4 -0
  276. dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog.html +2 -0
  277. dynamicforms_legacy/templates/dynamicforms/jquery_ui/modal_dialog_rest.html +27 -0
  278. dynamicforms_legacy/templates/dynamicforms/jquery_ui/page.html +20 -0
  279. dynamicforms_legacy/templates/dynamicforms/modal_dialog.html +4 -0
  280. dynamicforms_legacy/templates/dynamicforms/modal_dialog_rest.html +18 -0
  281. dynamicforms_legacy/templates/dynamicforms/page.html +25 -0
  282. dynamicforms_legacy/templates/dynamicforms/rtf_field_style.html +41 -0
  283. dynamicforms_legacy/templatetags/__init__.py +0 -0
  284. dynamicforms_legacy/templatetags/dynamicforms.py +475 -0
  285. dynamicforms_legacy/urls.py +8 -0
  286. dynamicforms_legacy/views.py +1 -0
  287. 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)