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,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,9 @@
1
+ import json
2
+
3
+ from rest_framework.utils.encoders import JSONEncoder
4
+
5
+
6
+ def convert_to_json_if(data, output_json: bool = True):
7
+ if output_json:
8
+ return json.dumps(data, cls=JSONEncoder)
9
+ return data
@@ -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