├── example ├── example │ ├── __init__.py │ ├── asgi.py │ ├── wsgi.py │ ├── urls.py │ └── settings.py ├── form │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── admin.py │ ├── apps.py │ ├── urls.py │ ├── templates │ │ └── form.html │ └── views.py ├── django_form_builder ├── .coverage ├── .coveragerc └── manage.py ├── django_form_builder ├── __init__.py ├── data │ ├── __init__.py │ └── audio_captcha │ │ ├── __init__.py │ │ ├── en │ │ ├── 0 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 1 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 2 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 3 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 4 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 5 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 6 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 7 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 8 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── 9 │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── __init__.py │ │ ├── A │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── B │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── C │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── D │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── E │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── F │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── G │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── H │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── I │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── J │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── K │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── L │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── M │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── N │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── O │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── P │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── Q │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── R │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── S │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── T │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── U │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── V │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── W │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── X │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── Y │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── Z │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── a │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── b │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── c │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── d │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── e │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── f │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── g │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── h │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── i │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── j │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── k │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── l │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── m │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── n │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── o │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── p │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── q │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── r │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── s │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── t │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── u │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── v │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── w │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── x │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ ├── y │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ └── z │ │ │ ├── __init__.py │ │ │ └── default.wav │ │ └── it │ │ ├── 0 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 1 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 2 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 3 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 4 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 5 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 6 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 7 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 8 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── 9 │ │ ├── __init__.py │ │ └── default.wav │ │ ├── __init__.py │ │ ├── A │ │ ├── __init__.py │ │ └── default.wav │ │ ├── B │ │ ├── __init__.py │ │ └── default.wav │ │ ├── C │ │ ├── __init__.py │ │ └── default.wav │ │ ├── D │ │ ├── __init__.py │ │ └── default.wav │ │ ├── E │ │ ├── __init__.py │ │ └── default.wav │ │ ├── F │ │ ├── __init__.py │ │ └── default.wav │ │ ├── G │ │ ├── __init__.py │ │ └── default.wav │ │ ├── H │ │ ├── __init__.py │ │ └── default.wav │ │ ├── I │ │ ├── __init__.py │ │ └── default.wav │ │ ├── J │ │ ├── __init__.py │ │ └── default.wav │ │ ├── K │ │ ├── __init__.py │ │ └── default.wav │ │ ├── L │ │ ├── __init__.py │ │ └── default.wav │ │ ├── M │ │ ├── __init__.py │ │ └── default.wav │ │ ├── N │ │ ├── __init__.py │ │ └── default.wav │ │ ├── O │ │ ├── __init__.py │ │ └── default.wav │ │ ├── P │ │ ├── __init__.py │ │ └── default.wav │ │ ├── Q │ │ ├── __init__.py │ │ └── default.wav │ │ ├── R │ │ ├── __init__.py │ │ └── default.wav │ │ ├── S │ │ ├── __init__.py │ │ └── default.wav │ │ ├── T │ │ ├── __init__.py │ │ └── default.wav │ │ ├── U │ │ ├── __init__.py │ │ └── default.wav │ │ ├── V │ │ ├── __init__.py │ │ └── default.wav │ │ ├── W │ │ ├── __init__.py │ │ └── default.wav │ │ ├── X │ │ ├── __init__.py │ │ └── default.wav │ │ ├── Y │ │ ├── __init__.py │ │ └── default.wav │ │ ├── Z │ │ ├── __init__.py │ │ └── default.wav │ │ ├── a │ │ ├── __init__.py │ │ └── default.wav │ │ ├── b │ │ ├── __init__.py │ │ └── default.wav │ │ ├── c │ │ ├── __init__.py │ │ └── default.wav │ │ ├── d │ │ ├── __init__.py │ │ └── default.wav │ │ ├── e │ │ ├── __init__.py │ │ └── default.wav │ │ ├── f │ │ ├── __init__.py │ │ └── default.wav │ │ ├── g │ │ ├── __init__.py │ │ └── default.wav │ │ ├── h │ │ ├── __init__.py │ │ └── default.wav │ │ ├── i │ │ ├── __init__.py │ │ └── default.wav │ │ ├── j │ │ ├── __init__.py │ │ └── default.wav │ │ ├── k │ │ ├── __init__.py │ │ └── default.wav │ │ ├── l │ │ ├── __init__.py │ │ └── default.wav │ │ ├── m │ │ ├── __init__.py │ │ └── default.wav │ │ ├── n │ │ ├── __init__.py │ │ └── default.wav │ │ ├── o │ │ ├── __init__.py │ │ └── default.wav │ │ ├── p │ │ ├── __init__.py │ │ └── default.wav │ │ ├── q │ │ ├── __init__.py │ │ └── default.wav │ │ ├── r │ │ ├── __init__.py │ │ └── default.wav │ │ ├── s │ │ ├── __init__.py │ │ └── default.wav │ │ ├── t │ │ ├── __init__.py │ │ └── default.wav │ │ ├── u │ │ ├── __init__.py │ │ └── default.wav │ │ ├── v │ │ ├── __init__.py │ │ └── default.wav │ │ ├── w │ │ ├── __init__.py │ │ └── default.wav │ │ ├── x │ │ ├── __init__.py │ │ └── default.wav │ │ ├── y │ │ ├── __init__.py │ │ └── default.wav │ │ └── z │ │ ├── __init__.py │ │ └── default.wav ├── tests │ ├── __init__.py │ ├── files │ │ ├── test.txt │ │ ├── test.pdf │ │ ├── test_signed.pdf │ │ └── test_signed.pdf.p7m │ ├── base.py │ └── test_02_formset.py ├── migrations │ └── __init__.py ├── admin.py ├── views.py ├── apps.py ├── exceptions.py ├── templates │ ├── widgets │ │ ├── formset_exception.html │ │ ├── formset.html │ │ └── captcha.html │ └── examples │ │ ├── base_form_example.html │ │ └── edit_form_example.html ├── templatetags │ └── django_form_builder_tags.py ├── enc.py ├── captcha.py ├── formsets.py ├── settings.py ├── locale │ └── en │ │ └── django.po ├── static │ └── js │ │ └── formset_js.js └── models.py ├── docs ├── build │ ├── html │ │ ├── objects.inv │ │ ├── _static │ │ │ ├── file.png │ │ │ ├── plus.png │ │ │ ├── minus.png │ │ │ ├── favicon.ico │ │ │ ├── logo_unical.png │ │ │ ├── fonts │ │ │ │ ├── Lato-Bold.ttf │ │ │ │ ├── Inconsolata.ttf │ │ │ │ ├── Lato-Regular.ttf │ │ │ │ ├── Lato │ │ │ │ │ ├── lato-bold.eot │ │ │ │ │ ├── lato-bold.ttf │ │ │ │ │ ├── lato-bold.woff │ │ │ │ │ ├── lato-bold.woff2 │ │ │ │ │ ├── lato-italic.eot │ │ │ │ │ ├── lato-italic.ttf │ │ │ │ │ ├── lato-italic.woff │ │ │ │ │ ├── lato-italic.woff2 │ │ │ │ │ ├── lato-regular.eot │ │ │ │ │ ├── lato-regular.ttf │ │ │ │ │ ├── lato-regular.woff │ │ │ │ │ ├── lato-bolditalic.eot │ │ │ │ │ ├── lato-bolditalic.ttf │ │ │ │ │ ├── lato-regular.woff2 │ │ │ │ │ ├── lato-bolditalic.woff │ │ │ │ │ └── lato-bolditalic.woff2 │ │ │ │ ├── RobotoSlab-Bold.ttf │ │ │ │ ├── Inconsolata-Bold.ttf │ │ │ │ ├── RobotoSlab-Regular.ttf │ │ │ │ ├── Inconsolata-Regular.ttf │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ ├── fontawesome-webfont.woff2 │ │ │ │ └── RobotoSlab │ │ │ │ │ ├── roboto-slab-v7-bold.eot │ │ │ │ │ ├── roboto-slab-v7-bold.ttf │ │ │ │ │ ├── roboto-slab-v7-bold.woff │ │ │ │ │ ├── roboto-slab-v7-bold.woff2 │ │ │ │ │ ├── roboto-slab-v7-regular.eot │ │ │ │ │ ├── roboto-slab-v7-regular.ttf │ │ │ │ │ ├── roboto-slab-v7-regular.woff │ │ │ │ │ └── roboto-slab-v7-regular.woff2 │ │ │ ├── documentation_options.js │ │ │ ├── custom.css │ │ │ ├── css │ │ │ │ └── badge_only.css │ │ │ ├── js │ │ │ │ └── theme.js │ │ │ └── pygments.css │ │ ├── .buildinfo │ │ ├── _sources │ │ │ ├── usage │ │ │ │ ├── dynamic-forms │ │ │ │ │ ├── description.rst.txt │ │ │ │ │ ├── customization.rst.txt │ │ │ │ │ └── configuration.rst.txt │ │ │ │ └── single-fields │ │ │ │ │ ├── description.rst.txt │ │ │ │ │ ├── customization.rst.txt │ │ │ │ │ └── methods.rst.txt │ │ │ ├── features │ │ │ │ ├── signed-files.rst.txt │ │ │ │ └── formset.rst.txt │ │ │ └── index.rst.txt │ │ └── searchindex.js │ └── doctrees │ │ ├── index.doctree │ │ ├── environment.pickle │ │ ├── features │ │ ├── formset.doctree │ │ └── signed-files.doctree │ │ └── usage │ │ ├── single-fields │ │ ├── methods.doctree │ │ ├── description.doctree │ │ └── customization.doctree │ │ └── dynamic-forms │ │ ├── description.doctree │ │ ├── configuration.doctree │ │ └── customization.doctree ├── source │ ├── _static │ │ ├── favicon.ico │ │ ├── logo_unical.png │ │ └── custom.css │ ├── images │ │ ├── formset.png │ │ ├── dyn_form_preview.png │ │ └── dyn_form_building.png │ ├── usage │ │ ├── single-fields │ │ │ ├── description.rst │ │ │ ├── customization.rst │ │ │ └── methods.rst │ │ └── dynamic-forms │ │ │ ├── customization.rst │ │ │ ├── description.rst │ │ │ └── configuration.rst │ ├── features │ │ ├── signed-files.rst │ │ └── formset.rst │ ├── install │ │ └── requirements-setup.rst │ ├── _templates │ │ └── unical_template │ │ │ ├── layout.html │ │ │ └── footer.html │ ├── index.rst │ └── conf.py ├── requirements.txt ├── Makefile └── make.bat ├── AUTHORS ├── .gitignore ├── requirements.txt ├── MANIFEST.in ├── readthedocs.yaml ├── requirements-dev.txt ├── .github └── workflows │ ├── pypi.yml │ └── python-app.yml ├── setup.py ├── README-dev.md └── README.md /example/example/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/form/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/form/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/tests/files/test.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/django_form_builder: -------------------------------------------------------------------------------- 1 | ../django_form_builder -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/0/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/4/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/5/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/6/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/7/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/8/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/9/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/B/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/C/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/D/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/E/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/F/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/G/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/H/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/I/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/J/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/K/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/L/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/M/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/N/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/O/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/P/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Q/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/R/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/S/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/T/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/U/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/V/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/W/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/X/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Y/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Z/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/a/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/b/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/c/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/d/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/e/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/f/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/g/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/h/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/i/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/j/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/k/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/l/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/m/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/n/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/o/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/p/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/q/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/r/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/s/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/t/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/u/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/v/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/w/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/x/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/y/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/z/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/0/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/1/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/2/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/4/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/5/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/6/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/7/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/8/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/9/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/A/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/B/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/C/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/D/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/E/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/F/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/G/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/H/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/I/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/J/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/K/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/L/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/M/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/N/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/O/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/P/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Q/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/R/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/S/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/T/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/U/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/V/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/W/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/X/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Y/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Z/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/a/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/b/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/c/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/d/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/e/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/f/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/g/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/h/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/i/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/j/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/k/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/l/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/m/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/n/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/o/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/p/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/q/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/r/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/s/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/t/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/u/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/v/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/w/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/x/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/y/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/z/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/form/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /example/form/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /example/form/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /django_form_builder/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /django_form_builder/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /example/.coverage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/example/.coverage -------------------------------------------------------------------------------- /example/form/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class FormConfig(AppConfig): 5 | name = 'form' 6 | -------------------------------------------------------------------------------- /docs/build/html/objects.inv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/objects.inv -------------------------------------------------------------------------------- /docs/build/html/_static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/file.png -------------------------------------------------------------------------------- /docs/build/html/_static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/plus.png -------------------------------------------------------------------------------- /docs/source/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/source/_static/favicon.ico -------------------------------------------------------------------------------- /docs/source/images/formset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/source/images/formset.png -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Università della Calabria 2 | Giuseppe De Marco 3 | Francesco Filicetti 4 | -------------------------------------------------------------------------------- /docs/build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/index.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/minus.png -------------------------------------------------------------------------------- /docs/build/html/_static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/favicon.ico -------------------------------------------------------------------------------- /docs/source/_static/logo_unical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/source/_static/logo_unical.png -------------------------------------------------------------------------------- /django_form_builder/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class DjangoFormBuilderConfig(AppConfig): 5 | name = 'django_form_builder' 6 | -------------------------------------------------------------------------------- /docs/build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/environment.pickle -------------------------------------------------------------------------------- /docs/build/html/_static/logo_unical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/logo_unical.png -------------------------------------------------------------------------------- /docs/source/images/dyn_form_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/source/images/dyn_form_preview.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | *__pycache__ 4 | */.~lock* 5 | /dist/* 6 | /docs/build/* 7 | build/* 8 | *.egg-info/ 9 | example/db.sqlite3 10 | .tox/* 11 | -------------------------------------------------------------------------------- /django_form_builder/tests/files/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/tests/files/test.pdf -------------------------------------------------------------------------------- /docs/source/images/dyn_form_building.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/source/images/dyn_form_building.png -------------------------------------------------------------------------------- /docs/build/doctrees/features/formset.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/features/formset.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato-Bold.ttf -------------------------------------------------------------------------------- /django_form_builder/tests/files/test_signed.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/tests/files/test_signed.pdf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Inconsolata.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato-Regular.ttf -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=2.0 2 | sphinx_rtd_theme 3 | sphinxcontrib-images 4 | setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability 5 | -------------------------------------------------------------------------------- /docs/build/doctrees/features/signed-files.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/features/signed-files.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bold.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bold.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab-Bold.ttf -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | django>=3.0,<6.0 2 | filesig>=0.3 3 | captcha>=0.3 4 | cryptography>=2.8 5 | pillow>=10.0.1 # not directly required, pinned by Snyk to avoid a vulnerability 6 | -------------------------------------------------------------------------------- /django_form_builder/tests/files/test_signed.pdf.p7m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/tests/files/test_signed.pdf.p7m -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Inconsolata-Bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bold.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-italic.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-italic.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-italic.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-italic.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-regular.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-regular.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Inconsolata-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Inconsolata-Regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bolditalic.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bolditalic.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-regular.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/0/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/0/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/1/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/1/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/2/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/2/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/3/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/3/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/4/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/4/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/5/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/5/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/6/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/6/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/7/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/7/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/8/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/8/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/9/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/9/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/A/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/A/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/B/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/B/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/C/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/C/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/D/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/D/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/E/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/E/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/F/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/F/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/G/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/G/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/H/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/H/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/I/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/I/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/J/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/J/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/K/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/K/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/L/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/L/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/M/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/M/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/N/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/N/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/O/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/O/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/P/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/P/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Q/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/Q/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/R/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/R/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/S/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/S/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/T/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/T/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/U/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/U/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/V/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/V/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/W/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/W/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/X/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/X/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Y/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/Y/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/Z/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/Z/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/a/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/a/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/b/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/b/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/c/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/c/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/d/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/d/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/e/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/e/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/f/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/f/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/g/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/g/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/h/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/h/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/i/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/i/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/j/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/j/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/k/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/k/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/l/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/l/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/m/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/m/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/n/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/n/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/o/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/o/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/p/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/p/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/q/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/q/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/r/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/r/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/s/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/s/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/t/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/t/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/u/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/u/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/v/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/v/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/w/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/w/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/x/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/x/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/y/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/y/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/en/z/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/en/z/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/0/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/0/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/1/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/1/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/2/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/2/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/3/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/3/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/4/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/4/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/5/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/5/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/6/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/6/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/7/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/7/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/8/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/8/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/9/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/9/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/A/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/A/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/B/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/B/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/C/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/C/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/D/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/D/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/E/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/E/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/F/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/F/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/G/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/G/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/H/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/H/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/I/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/I/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/J/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/J/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/K/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/K/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/L/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/L/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/M/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/M/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/N/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/N/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/O/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/O/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/P/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/P/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Q/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/Q/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/R/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/R/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/S/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/S/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/T/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/T/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/U/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/U/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/V/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/V/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/W/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/W/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/X/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/X/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Y/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/Y/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/Z/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/Z/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/a/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/a/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/b/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/b/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/c/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/c/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/d/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/d/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/e/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/e/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/f/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/f/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/g/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/g/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/h/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/h/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/i/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/i/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/j/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/j/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/k/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/k/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/l/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/l/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/m/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/m/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/n/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/n/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/o/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/o/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/p/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/p/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/q/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/q/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/r/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/r/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/s/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/s/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/t/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/t/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/u/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/u/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/v/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/v/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/w/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/w/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/x/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/x/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/y/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/y/default.wav -------------------------------------------------------------------------------- /django_form_builder/data/audio_captcha/it/z/default.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/django_form_builder/data/audio_captcha/it/z/default.wav -------------------------------------------------------------------------------- /docs/build/doctrees/usage/single-fields/methods.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/single-fields/methods.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bolditalic.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/Lato/lato-bolditalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/Lato/lato-bolditalic.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /docs/build/doctrees/usage/dynamic-forms/description.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/dynamic-forms/description.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/usage/single-fields/description.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/single-fields/description.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/usage/dynamic-forms/configuration.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/dynamic-forms/configuration.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/usage/dynamic-forms/customization.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/dynamic-forms/customization.doctree -------------------------------------------------------------------------------- /docs/build/doctrees/usage/single-fields/customization.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/doctrees/usage/single-fields/customization.doctree -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff -------------------------------------------------------------------------------- /docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UniversitaDellaCalabria/django-form-builder/HEAD/docs/build/html/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 -------------------------------------------------------------------------------- /example/.coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc to control coverage.py 2 | [run] 3 | omit = 4 | */site-packages/* 5 | */distutils/* 6 | */tests/* 7 | */example/* 8 | */apps/* 9 | */migrations/* 10 | */src/* 11 | -------------------------------------------------------------------------------- /example/form/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | 4 | from .views import * 5 | 6 | app_name="form" 7 | 8 | urlpatterns = [ 9 | path('', dynform, name='dynform'), 10 | ] 11 | -------------------------------------------------------------------------------- /docs/build/html/.buildinfo: -------------------------------------------------------------------------------- 1 | # Sphinx build info version 1 2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. 3 | config: a226362424f88c034ad87038cd28f364 4 | tags: 645f666f9bcd5a90fca523b33c5a78b7 5 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS 2 | include LICENSE 3 | include README.md 4 | include django_form_builder/static/js/* 5 | include django_form_builder/templates/examples/* 6 | include django_form_builder/templates/widgets/* 7 | include django_form_builder/templatetags/* 8 | include django_form_builder/data/audio_captcha/*/*/default.wav 9 | -------------------------------------------------------------------------------- /docs/build/html/_static/documentation_options.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_OPTIONS = { 2 | URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), 3 | VERSION: '0.1', 4 | LANGUAGE: 'None', 5 | COLLAPSE_INDEX: false, 6 | FILE_SUFFIX: '.html', 7 | HAS_SOURCE: true, 8 | SOURCELINK_SUFFIX: '.txt', 9 | NAVIGATION_WITH_KEYS: false, 10 | }; -------------------------------------------------------------------------------- /example/example/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for example project. 3 | 4 | It exposes the ASGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /example/example/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for example project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /django_form_builder/exceptions.py: -------------------------------------------------------------------------------- 1 | class ChoicesNotDefined(Exception): 2 | """ 3 | if 'choices' not found in constructor kwargs 4 | """ 5 | pass 6 | 7 | 8 | class AudioCaptchaLangPackNotFound(Exception): 9 | """ 10 | the language pack for Audio CaPTCHA cannot be found 11 | """ 12 | def __init__(self, 13 | msg='the language pack for Audio CaPTCHA cannot be found', 14 | *args, **kwargs): 15 | super().__init__(msg, *args, **kwargs) 16 | -------------------------------------------------------------------------------- /django_form_builder/templates/widgets/formset_exception.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | 3 | 17 | -------------------------------------------------------------------------------- /readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # .readthedocs.yml 2 | # Read the Docs configuration file 3 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 4 | 5 | # Required 6 | version: 2 7 | 8 | # Build documentation in the docs/ directory with Sphinx 9 | sphinx: 10 | configuration: docs/source/conf.py 11 | 12 | # Build documentation with MkDocs 13 | #mkdocs: 14 | # configuration: mkdocs.yml 15 | 16 | # Optionally build your docs in additional formats such as PDF and ePub 17 | formats: all 18 | 19 | # Optionally set the version of Python and requirements required to build your docs 20 | python: 21 | version: 3.7 22 | install: 23 | - requirements: docs/requirements.txt 24 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /example/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | pytest==5.4.1 2 | pytest-django==3.8.0 3 | pytest-pythonpath==0.7.3 4 | python-dateutil==2.7.5 5 | pytest-cov 6 | pylama 7 | codecov 8 | 9 | sphinx>=3.3.0 10 | sphinx_rtd_theme 11 | sphinxcontrib-images 12 | 13 | autoflake 14 | autopep8 15 | coverage 16 | black 17 | flake8 18 | isort 19 | bandit 20 | certifi>=2023.7.22 # not directly required, pinned by Snyk to avoid a vulnerability 21 | jinja2>=3.1.3 # not directly required, pinned by Snyk to avoid a vulnerability 22 | pygments>=2.15.0 # not directly required, pinned by Snyk to avoid a vulnerability 23 | requests>=2.31.0 # not directly required, pinned by Snyk to avoid a vulnerability 24 | setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability 25 | -------------------------------------------------------------------------------- /django_form_builder/templatetags/django_form_builder_tags.py: -------------------------------------------------------------------------------- 1 | import inspect 2 | 3 | from django import template 4 | 5 | from django_form_builder import dynamic_fields 6 | 7 | register = template.Library() 8 | 9 | @register.filter 10 | def get_dyn_field_name(value): 11 | for m in inspect.getmembers(dynamic_fields, inspect.isclass): 12 | if m[0]==value: return getattr(m[1], 'field_type') 13 | return value 14 | 15 | @register.simple_tag 16 | def get_attachment_sign_details(form, field_path, field_name, field_value): 17 | field = form.fields.get(field_name, None) 18 | if field and isinstance(field, dynamic_fields.CustomSignedFileField): 19 | return field.get_cleaned_signature_params('{}/{}'.format(field_path, field_value)) 20 | return False 21 | -------------------------------------------------------------------------------- /django_form_builder/templates/examples/base_form_example.html: -------------------------------------------------------------------------------- 1 |
2 | {% for field in form %} 3 |
4 | {{ field.label_tag }} 5 | {{ field.errors }} 6 | {{ field }} 7 | {% if field.help_text %} 8 |
9 |

10 | {{ field.help_text|safe }} 11 |

12 |
13 | {% endif %} 14 |
15 | {% endfor %} 16 | 17 | {% block allegati %}{% endblock allegati %} 18 | 19 | {% block formbuttons %} 20 | 21 | {% endblock formbuttons%} 22 | 23 | {% csrf_token %} 24 |
25 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/dynamic-forms/description.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Build dynamic forms 7 | =================== 8 | 9 | Now you can build your own form dynamically both in Django backend and frontend, just selecting the fields that you want, 10 | in total flexibility and easiness. 11 | 12 | Every form can be saved in a configurable storage, in JSON format. 13 | 14 | -------------------------------- 15 | 16 | *Example of Dynamic Form built via frontend:* 17 | 18 | .. thumbnail:: ../../images/dyn_form_building.png 19 | 20 | *Preview of the builded form:* 21 | 22 | .. thumbnail:: ../../images/dyn_form_preview.png 23 | -------------------------------------------------------------------------------- /docs/source/usage/single-fields/description.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Use single fields in your form 7 | ============================== 8 | 9 | | You can simply take single fields from this app and use them in you own form. 10 | | Just in your project include 11 | 12 | .. code-block:: python 13 | 14 | from django_form_builder import dynamic_fields 15 | 16 | and use every field as a normal form field 17 | 18 | .. code-block:: python 19 | 20 | my_field = dynamic_fields.DynamicFieldClassName(params) 21 | 22 | 23 | Every field has (or inherit) a ``raise_error()`` method that can be overrided to implement cleaning features and 24 | validation functions. 25 | -------------------------------------------------------------------------------- /docs/source/usage/single-fields/customization.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Create your own fields 7 | ====================== 8 | 9 | If you need to define your own fields inheriting an existing one, 10 | you can fastly create them by importing ``dynamic_fields`` 11 | 12 | .. code-block:: python 13 | 14 | from django_form_builder import dynamic_fields 15 | 16 | make an inheritance declaration 17 | 18 | .. code-block:: python 19 | 20 | class MyCustomField(dynamic_fields.DynamicFieldClassName): 21 | # e.g. MyCustomField(BaseCustomField) 22 | ... 23 | 24 | and override ``get_fields()``, ``define_value()`` and ``raise_error()`` according to your needs. 25 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/single-fields/description.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Use single fields in your form 7 | ============================== 8 | 9 | | You can simply take single fields from this app and use them in you own form. 10 | | Just in your project include 11 | 12 | .. code-block:: python 13 | 14 | from django_form_builder import dynamic_fields 15 | 16 | and use every field as a normal form field 17 | 18 | .. code-block:: python 19 | 20 | my_field = dynamic_fields.DynamicFieldClassName(params) 21 | 22 | 23 | Every field has (or inherit) a ``raise_error()`` method that can be overrided to implement cleaning features and 24 | validation functions. 25 | -------------------------------------------------------------------------------- /docs/source/features/signed-files.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Upload P7M and signed PDF files 7 | =============================== 8 | 9 | Custom fields set provides a base class called ``CustomSignedFileField`` that 10 | via *FileSignatureValidator* library checks if an upload attachment is digitally signed. 11 | 12 | Also, with ``get_cleaned_signature_params()`` method, it returns the sign details 13 | 14 | - Signature Validation 15 | - Signing Time 16 | - Signer full Distinguished Name 17 | 18 | | P7M file fields are built by ``CustomSignedP7MField(CustomSignedFileField)`` class. 19 | | Signed PDF file fields are built by ``CustomSignedPdfField(CustomSignedFileField)`` class. 20 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/single-fields/customization.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Create your own fields 7 | ====================== 8 | 9 | If you need to define your own fields inheriting an existing one, 10 | you can fastly create them by importing ``dynamic_fields`` 11 | 12 | .. code-block:: python 13 | 14 | from django_form_builder import dynamic_fields 15 | 16 | make an inheritance declaration 17 | 18 | .. code-block:: python 19 | 20 | class MyCustomField(dynamic_fields.DynamicFieldClassName): 21 | # e.g. MyCustomField(BaseCustomField) 22 | ... 23 | 24 | and override ``get_fields()``, ``define_value()`` and ``raise_error()`` according to your needs. 25 | -------------------------------------------------------------------------------- /docs/build/html/_sources/features/signed-files.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Upload P7M and signed PDF files 7 | =============================== 8 | 9 | Custom fields set provides a base class called ``CustomSignedFileField`` that 10 | via *FileSignatureValidator* library checks if an upload attachment is digitally signed. 11 | 12 | Also, with ``get_cleaned_signature_params()`` method, it returns the sign details 13 | 14 | - Signature Validation 15 | - Signing Time 16 | - Signer full Distinguished Name 17 | 18 | | P7M file fields are built by ``CustomSignedP7MField(CustomSignedFileField)`` class. 19 | | Signed PDF file fields are built by ``CustomSignedPdfField(CustomSignedFileField)`` class. 20 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /example/example/urls.py: -------------------------------------------------------------------------------- 1 | """example URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/3.0/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | 19 | 20 | urlpatterns = [ 21 | path('admin/', admin.site.urls), 22 | ] 23 | 24 | import form.urls 25 | urlpatterns += path('', include(form.urls, namespace='form')), 26 | -------------------------------------------------------------------------------- /django_form_builder/enc.py: -------------------------------------------------------------------------------- 1 | import base64 2 | 3 | from cryptography.fernet import Fernet 4 | from cryptography.hazmat.backends import default_backend 5 | from cryptography.hazmat.primitives import hashes 6 | from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC 7 | 8 | from django.conf import settings 9 | 10 | 11 | _secret = getattr(settings, 'CAPTCHA_SECRET', b'secret') 12 | _salt = getattr(settings, 'CAPTCHA_SALT', b'salt') 13 | _kdf = PBKDF2HMAC(algorithm=hashes.SHA256(), 14 | length=32, 15 | salt=_salt, 16 | iterations=100000, 17 | backend=default_backend()) 18 | 19 | key = base64.urlsafe_b64encode(_kdf.derive(_secret)) 20 | _encoder = Fernet(key) 21 | 22 | def encrypt(text): 23 | enc_text = _encoder.encrypt(text.encode()) 24 | return enc_text 25 | 26 | 27 | def decrypt(b64_text): 28 | text = base64.b64decode(b64_text) 29 | decrypted = _encoder.decrypt(text) 30 | return decrypted 31 | -------------------------------------------------------------------------------- /docs/source/install/requirements-setup.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Requirements and Setup 7 | ====================== 8 | 9 | Install ``django-form-builder` 10 | 11 | .. code-block:: python 12 | python setup.py install 13 | # or 14 | pip install django-form-builder 15 | 16 | 17 | Only ``FileSignatureValidator`` library is required as system dependency, it is needed to verify digitally signed attachments. 18 | See also requirements for python requirements. 19 | 20 | .. code-block:: python 21 | 22 | pip install git+https://github.com/peppelinux/FileSignatureValidator.git 23 | 24 | In ``INSTALLED_APPS`` include ``django_form_builder`` app. 25 | 26 | .. code-block:: python 27 | 28 | INSTALLED_APPS = ( 29 | # other apps 30 | 'django_form_builder', 31 | ) 32 | -------------------------------------------------------------------------------- /.github/workflows/pypi.yml: -------------------------------------------------------------------------------- 1 | name: Publish Python distribution to PyPI and TestPyPI 2 | on: 3 | release: 4 | types: 5 | - created 6 | 7 | jobs: 8 | build-n-publish: 9 | name: Publish Python distribution to PyPI 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@master 13 | - name: Setup Python 3.11 14 | uses: actions/setup-python@v1 15 | with: 16 | python-version: 3.11 17 | - name: Install pypa/build 18 | run: >- 19 | python -m 20 | pip install 21 | build 22 | --user 23 | - name: Build a binary wheel and a source tarball 24 | run: >- 25 | python -m 26 | build 27 | --sdist 28 | --wheel 29 | --outdir dist/ 30 | . 31 | - name: Publish distribution to PyPI 32 | uses: pypa/gh-action-pypi-publish@release/v1 33 | with: 34 | user: __token__ 35 | password: ${{ secrets.PYPI_API_TOKEN }} 36 | -------------------------------------------------------------------------------- /docs/source/usage/single-fields/methods.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Fields methods and attributes 7 | ============================= 8 | 9 | | ``BaseCustomField`` is the base class for every custom field. 10 | | This class defines two attributes and trhee foundamental methods that make fields work well. 11 | 12 | **Attributes** 13 | 14 | - ``is_complex`` (default *False*): if *True*, specifies that the field is composed by more elementar fields (like two DateFields); 15 | - ``is_formset`` (default *False*): if *True*, specifies that the field is a `Django Formset `_. 16 | 17 | **Methods** 18 | 19 | - ``def define_value(self, custom_value=None, **kwargs)``: it integrates the field initialization with custom configuration parameters defined by user (e.g. choices of a SelectBox); 20 | - ``get_fields(self)``: if field *is_complex*, it returns a Python list of child fields. Else, it returns ``[self]``; 21 | - ``def raise_error(self, name, cleaned_data, **kwargs):``: it integrates ``clean()`` method to have a customizable behaviour processing ``cleaned_data``. 22 | -------------------------------------------------------------------------------- /docs/source/features/formset.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Add/Remove Formset dynamically with javascript 7 | ============================================== 8 | 9 | Django Form Builder provides a particular type of field, ``CustomComplexTableField``, 10 | that allows user to easily insert `Django Formset `_ Fields in his form. 11 | 12 | The built-in javascript enables form inserting and removing via frontend, simply using the relative buttons! 13 | 14 | To build a formset just define the ``CustomComplexTableField`` attribute *valore* setting columuns. 15 | Divide each one using *#* char and, for every column, define the field type with a dictionary, like in the example 16 | 17 | .. code-block:: html 18 | 19 | column1({'type':'CustomSelectBoxField', 'choices': 'value1;value2;value3',})#column2({'type':'CustomRadioBoxField', 'choices': 'value1;value2',})#column3#column4({'type':'BaseDateField',}) 20 | 21 | Column with no params dict generate ``CustomCharField`` by default. 22 | 23 | -------------------------------- 24 | 25 | .. thumbnail:: ../images/formset.png 26 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/single-fields/methods.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Fields methods and attributes 7 | ============================= 8 | 9 | | ``BaseCustomField`` is the base class for every custom field. 10 | | This class defines two attributes and trhee foundamental methods that make fields work well. 11 | 12 | **Attributes** 13 | 14 | - ``is_complex`` (default *False*): if *True*, specifies that the field is composed by more elementar fields (like two DateFields); 15 | - ``is_formset`` (default *False*): if *True*, specifies that the field is a `Django Formset `_. 16 | 17 | **Methods** 18 | 19 | - ``def define_value(self, custom_value=None, **kwargs)``: it integrates the field initialization with custom configuration parameters defined by user (e.g. choices of a SelectBox); 20 | - ``get_fields(self)``: if field *is_complex*, it returns a Python list of child fields. Else, it returns ``[self]``; 21 | - ``def raise_error(self, name, cleaned_data, **kwargs):``: it integrates ``clean()`` method to have a customizable behaviour processing ``cleaned_data``. 22 | -------------------------------------------------------------------------------- /docs/build/html/_sources/features/formset.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Add/Remove Formset dynamically with javascript 7 | ============================================== 8 | 9 | Django Form Builder provides a particular type of field, ``CustomComplexTableField``, 10 | that allows user to easily insert `Django Formset `_ Fields in his form. 11 | 12 | The built-in javascript enables form inserting and removing via frontend, simply using the relative buttons! 13 | 14 | To build a formset just define the ``CustomComplexTableField`` attribute *valore* setting columuns. 15 | Divide each one using *#* char and, for every column, define the field type with a dictionary, like in the example 16 | 17 | .. code-block:: html 18 | 19 | column1({'type':'CustomSelectBoxField', 'choices': 'value1;value2;value3',})#column2({'type':'CustomRadioBoxField', 'choices': 'value1;value2',})#column3#column4({'type':'BaseDateField',}) 20 | 21 | Column with no params dict generate ``CustomCharField`` by default. 22 | 23 | -------------------------------- 24 | 25 | .. thumbnail:: ../images/formset.png 26 | -------------------------------------------------------------------------------- /django_form_builder/templates/widgets/formset.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | {% load static %} 3 | 4 | {% if not readonly %} 5 | 17 | {{ formset.management_form }} 18 | {% endif %} 19 | 20 | {% for form in formset %} 21 |
22 |
23 | 24 | {{form.as_table}} 25 |
26 |
27 | {% if not readonly %} 28 | 31 | {% endif %} 32 |
33 | {% endfor %} 34 | 35 | {% if not readonly %} 36 |
37 | 40 |
41 | {% endif %} 42 | -------------------------------------------------------------------------------- /docs/build/html/_static/custom.css: -------------------------------------------------------------------------------- 1 | body, 2 | h1, h2, 3 | .rst-content .toctree-wrapper p.caption, 4 | h3, h4, h5, h6, 5 | legend{ 6 | font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; 7 | } 8 | 9 | .wy-side-nav-search{ 10 | background: #ffffff; 11 | } 12 | 13 | .wy-side-nav-search>a, 14 | .wy-side-nav-search .wy-dropdown>a{ 15 | color: #9b9c9e; 16 | font-weight: normal; 17 | } 18 | 19 | .wy-menu-vertical header, 20 | .wy-menu-vertical p.caption{ 21 | color: #fff; 22 | font-size:85%; 23 | } 24 | 25 | .wy-nav-top{ 26 | background: #fff; 27 | border-bottom: 1px solid #f7f5f5; 28 | } 29 | 30 | .wy-nav-top a{ 31 | display: block; 32 | color: #9b9c9e; 33 | font-weight: normal; 34 | } 35 | 36 | .wy-nav-top i{ 37 | color: #BE0417; 38 | } 39 | 40 | .wy-nav-top img{ 41 | border-radius: 0; 42 | background: none; 43 | width: 65%; 44 | } 45 | 46 | img{ 47 | height: auto !important; 48 | } 49 | 50 | .document{ 51 | text-align: justify; 52 | } 53 | 54 | h1{ 55 | text-align: left; 56 | } 57 | 58 | #logo_main{ 59 | margin-bottom: 0; 60 | } 61 | 62 | #title_under_logo{ 63 | margin-bottom: 1em; 64 | } 65 | 66 | .alert-danger { 67 | color: #721c24; 68 | background-color: #f8d7da; 69 | border-color: #f5c6cb; 70 | } 71 | .alert-primary { 72 | color: #004085; 73 | background-color: #cce5ff; 74 | border-color: #b8daff; 75 | } 76 | .alert { 77 | position: relative; 78 | padding: .75rem 1.25rem; 79 | margin-bottom: 1rem; 80 | border: 1px solid transparent; 81 | border-radius: .25rem; 82 | } 83 | -------------------------------------------------------------------------------- /docs/source/_static/custom.css: -------------------------------------------------------------------------------- 1 | body, 2 | h1, h2, 3 | .rst-content .toctree-wrapper p.caption, 4 | h3, h4, h5, h6, 5 | legend{ 6 | font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; 7 | } 8 | 9 | .wy-side-nav-search{ 10 | background: #ffffff; 11 | } 12 | 13 | .wy-side-nav-search>a, 14 | .wy-side-nav-search .wy-dropdown>a{ 15 | color: #9b9c9e; 16 | font-weight: normal; 17 | } 18 | 19 | .wy-menu-vertical header, 20 | .wy-menu-vertical p.caption{ 21 | color: #fff; 22 | font-size:85%; 23 | } 24 | 25 | .wy-nav-top{ 26 | background: #fff; 27 | border-bottom: 1px solid #f7f5f5; 28 | } 29 | 30 | .wy-nav-top a{ 31 | display: block; 32 | color: #9b9c9e; 33 | font-weight: normal; 34 | } 35 | 36 | .wy-nav-top i{ 37 | color: #BE0417; 38 | } 39 | 40 | .wy-nav-top img{ 41 | border-radius: 0; 42 | background: none; 43 | width: 65%; 44 | } 45 | 46 | img{ 47 | height: auto !important; 48 | } 49 | 50 | .document{ 51 | text-align: justify; 52 | } 53 | 54 | h1{ 55 | text-align: left; 56 | } 57 | 58 | #logo_main{ 59 | margin-bottom: 0; 60 | } 61 | 62 | #title_under_logo{ 63 | margin-bottom: 1em; 64 | } 65 | 66 | .alert-danger { 67 | color: #721c24; 68 | background-color: #f8d7da; 69 | border-color: #f5c6cb; 70 | } 71 | .alert-primary { 72 | color: #004085; 73 | background-color: #cce5ff; 74 | border-color: #b8daff; 75 | } 76 | .alert { 77 | position: relative; 78 | padding: .75rem 1.25rem; 79 | margin-bottom: 1rem; 80 | border: 1px solid transparent; 81 | border-radius: .25rem; 82 | } 83 | -------------------------------------------------------------------------------- /django_form_builder/captcha.py: -------------------------------------------------------------------------------- 1 | import os 2 | import random 3 | import string 4 | 5 | from captcha.audio import AudioCaptcha 6 | from captcha.image import ImageCaptcha 7 | 8 | from django.conf import settings 9 | from . exceptions import AudioCaptchaLangPackNotFound 10 | from . settings import CAPTCHA_DEFAULT_LANG 11 | 12 | 13 | def get_captcha(text=None, lang=getattr(settings, 14 | 'CAPTCHA_DEFAULT_LANG', 15 | CAPTCHA_DEFAULT_LANG)): 16 | fonts = getattr(settings, 'CAPTCHA_FONTS', None) 17 | length = getattr(settings, 'CAPTCHA_LENGTH', 5) 18 | voicedir = getattr(settings, 'CAPTCHA_VOICEDIR', 19 | os.path.join(os.path.abspath(os.path.dirname(__file__)), 20 | 'data', 'audio_captcha', lang)) 21 | # if audio for that language is not available 22 | # fallback to settings default (english: en) 23 | if not os.path.exists(voicedir): 24 | voicedir = getattr(settings, 'CAPTCHA_VOICEDIR', 25 | os.path.join(os.path.abspath(os.path.dirname(__file__)), 26 | 'data', 'audio_captcha', 27 | CAPTCHA_DEFAULT_LANG)) 28 | image = ImageCaptcha(fonts=fonts) 29 | 30 | try: 31 | audio = AudioCaptcha(voicedir=voicedir) 32 | except IndexError as e: 33 | raise AudioCaptchaLangPackNotFound() 34 | 35 | text = text or ''.join([random.choice(string.ascii_letters+string.hexdigits) # nosec 36 | for i in range(length)]) 37 | 38 | data_image = image.generate(text) 39 | data_audio = audio.generate(text) 40 | return data_image, data_audio 41 | -------------------------------------------------------------------------------- /docs/source/_templates/unical_template/layout.html: -------------------------------------------------------------------------------- 1 | {% extends "!layout.html" %} 2 | 3 | {% block extrahead %} 4 | 5 | 6 | {% endblock %} 7 | 8 | 9 | 10 | {% block sidebartitle %} 11 | 12 | {% if logo %} 13 | {# Not strictly valid HTML, but it's the only way to display/scale 14 | it properly, without weird scripting or heaps of work 15 | #} 16 | 17 | {% endif %} 18 | 19 | {% if logo and theme_logo_only %} 20 | 25 | 26 | {% if theme_display_version %} 27 | {%- set nav_version = version %} 28 | {% if READTHEDOCS and current_version %} 29 | {%- set nav_version = current_version %} 30 | {% endif %} 31 | {% if nav_version %} 32 |
33 | {{ nav_version }} 34 |
35 | {% endif %} 36 | {% endif %} 37 | 38 | {% include "searchbox.html" %} 39 | 40 | {% endblock %} 41 | 42 | 43 | 44 | 45 | {% block mobile_nav %} 46 | 47 | 48 | 49 | 50 | 51 | {{ project }} 52 | 53 | {% endblock %} 54 | -------------------------------------------------------------------------------- /django_form_builder/templates/widgets/captcha.html: -------------------------------------------------------------------------------- 1 | {% load i18n %} 2 | 3 | 12 | 13 |
14 |
15 | 16 |
17 | 20 |
21 | 22 |
23 | 32 | 33 |
37 |
38 | 39 |
40 | 47 |
48 | 49 |

{% trans "Inserisci il valore rappresentato nella immagine CaPTCHA." %}

50 | 51 |
52 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from glob import glob 3 | from setuptools import find_packages, setup 4 | 5 | with open(os.path.join(os.path.dirname(__file__), 'README.md')) as readme: 6 | README = readme.read() 7 | 8 | # allow setup.py to be run from any path 9 | os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir))) 10 | 11 | # rm -R build/ dist/ *egg-info 12 | # python3 setup.py sdist 13 | # twine upload dist/* 14 | 15 | setup( 16 | name='django-form-builder', 17 | version='1.2.2', 18 | packages=find_packages(), 19 | package_data={'': ['*.wav']}, 20 | data_files=[ 21 | ('', glob('django_form_builder/data/audio_captcha/*/default.wav', recursive=True)), 22 | ], 23 | include_package_data=True, 24 | license='Apache 2.0', 25 | description='Django Form builder', 26 | long_description=README, 27 | long_description_content_type='text/markdown', 28 | url='https://github.com/UniversitaDellaCalabria/django-form-builder', 29 | author='Giuseppe De Marco, Francesco Filicetti', 30 | author_email='giuseppe.demarco@unical.it, francesco.filicetti@unical.it', 31 | classifiers=[ 32 | 'Environment :: Web Environment', 33 | 'Framework :: Django', 34 | 'Framework :: Django :: 3.0', 35 | 'Framework :: Django :: 4.0', 36 | 'Framework :: Django :: 5.0', 37 | 'Intended Audience :: Developers', 38 | "License :: OSI Approved :: Apache Software License", 39 | 'Operating System :: OS Independent', 40 | 'Programming Language :: Python', 41 | 'Programming Language :: Python :: 3', 42 | ], 43 | install_requires=[ 44 | 'wheel', 45 | 'django>=3.0,<6.0', 46 | 'filesig>=0.3', 47 | 'cryptography>=2.8', 48 | 'captcha>=0.3' 49 | ], 50 | ) 51 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | django-form-builder's documentation 7 | =================================== 8 | 9 | A Django Framework application to build dynamic forms and define 10 | custom form fields types. 11 | 12 | **Github:** https://github.com/UniversitaDellaCalabria/django-form-builder 13 | 14 | **Features:** 15 | 16 | - Forms definitions via JSON object; 17 | - Save compiled form as JSON objects in model db and get its structure and contents with a simple model method call; 18 | - Override form constructor in order to add static common fields; 19 | - Create input fields using heritable classes, with customizable validation methods; 20 | - Manage Django Formset fields, with form insertion and removal via javascript; 21 | - Manage and verify digitally signed file fields (PDF and P7M) without a certification authority validation (TODO via third-party API). 22 | 23 | --------------------------------------- 24 | 25 | .. toctree:: 26 | :maxdepth: 2 27 | :caption: Installation 28 | 29 | install/requirements-setup.rst 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | :caption: Use single fields in your form 34 | 35 | Description 36 | Methods ad Attributes 37 | Create your own fields 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | :caption: Build dynamic forms 42 | 43 | Description 44 | Add static fields to a form 45 | Configuration 46 | 47 | .. toctree:: 48 | :maxdepth: 2 49 | :caption: Special features 50 | 51 | Digitally signed attachments 52 | Formset javascript manager 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/source/usage/dynamic-forms/customization.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Create your DynamicFormClass and add static fields 7 | ================================================== 8 | 9 | If you need some static field in your form, than you can define a new Form Class, inheriting *BaseDynamicForm* 10 | 11 | .. code-block:: python 12 | 13 | from django_form_builder import dynamic_fields 14 | from django_form_builder.forms import BaseDynamicForm 15 | 16 | class MyDynamicForm(BaseDynamicForm): 17 | def __init__(self, 18 | constructor_dict={}, 19 | custom_params={}, 20 | *args, 21 | **kwargs): 22 | # Add a custom static field common to all dynamic forms 23 | self.fields = {} 24 | my_static_field = dynamic_fields.format_field_name(choice_field_name) 25 | my_static_field_data = {'required' : True, 26 | 'label': choice_field_label, 27 | 'help_text': choice_field_helptext} 28 | my_static_field = getattr(dynamic_fields, 29 | 'CustomFieldClass')(**my_static_field_data) 30 | self.fields[my_static_field_id] = my_static_field 31 | 32 | # call super() constructor to build form 33 | super().__init__(# define it only if you 34 | # define a custom field source, 35 | # see "Create your own fields" paragraph. 36 | # fields_source=dynamic_fields_integration, 37 | initial_fields=self.fields, 38 | constructor_dict=constructor_dict, 39 | custom_params=custom_params, 40 | *args, **kwargs) 41 | 42 | # if needed, override clean() method with your own params 43 | def clean(self, *args, **kwargs): 44 | cleaned_data = super().clean(own_param=own_value) 45 | -------------------------------------------------------------------------------- /docs/build/html/_sources/index.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | django-form-builder's documentation 7 | =================================== 8 | 9 | A Django Framework application to build dynamic forms and define 10 | custom form fields types. 11 | 12 | **Github:** https://github.com/UniversitaDellaCalabria/django-form-builder 13 | 14 | **Features:** 15 | 16 | - Forms definitions via JSON object; 17 | - Save compiled form as JSON objects in model db and get its structure and contents with a simple model method call; 18 | - Override form constructor in order to add static common fields; 19 | - Create input fields using heritable classes, with customizable validation methods; 20 | - Manage Django Formset fields, with form insertion and removal via javascript; 21 | - Manage and verify digitally signed file fields (PDF and P7M) without a certification authority validation (TODO via third-party API). 22 | 23 | --------------------------------------- 24 | 25 | .. toctree:: 26 | :maxdepth: 2 27 | :caption: Installation 28 | 29 | install/requirements-setup.rst 30 | 31 | .. toctree:: 32 | :maxdepth: 2 33 | :caption: Use single fields in your form 34 | 35 | Description 36 | Methods ad Attributes 37 | Create your own fields 38 | 39 | .. toctree:: 40 | :maxdepth: 2 41 | :caption: Build dynamic forms 42 | 43 | Description 44 | Add static fields to a form 45 | Configuration 46 | 47 | .. toctree:: 48 | :maxdepth: 2 49 | :caption: Special features 50 | 51 | Digitally signed attachments 52 | Formset javascript manager 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/source/_templates/unical_template/footer.html: -------------------------------------------------------------------------------- 1 |
2 | {% if (theme_prev_next_buttons_location == 'bottom' or theme_prev_next_buttons_location == 'both') and (next or prev) %} 3 | 11 | {% endif %} 12 | 13 |
14 | 15 |
16 |

17 | {%- if show_copyright %} 18 | {%- if hasdoc('copyright') %} 19 | {% trans path=pathto('copyright'), copyright=copyright|e %}{{ copyright }}.{% endtrans %} 20 | {%- else %} 21 | {% trans copyright=copyright|e %}{{ copyright }}.{% endtrans %} 22 | {%- endif %} 23 | {%- endif %} 24 | 25 | {%- if build_id and build_url %} 26 | {% trans build_url=build_url, build_id=build_id %} 27 | 28 | Build 29 | {{ build_id }}. 30 | 31 | {% endtrans %} 32 | {%- elif commit %} 33 | {% trans commit=commit %} 34 | 35 | Revision {{ commit }}. 36 | 37 | {% endtrans %} 38 | {%- elif last_updated %} 39 | {% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %} 40 | {%- endif %} 41 | 42 |

43 |
44 | 45 | 46 | {%- if show_sphinx %} 47 | {% trans %}Built with Sphinx{% endtrans %}. 48 | {%- endif %} 49 | 50 | {%- block extrafooter %} 51 |
Last update 03/07/2019 52 | {% endblock %} 53 |
54 |
55 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/dynamic-forms/customization.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Create your DynamicFormClass and add static fields 7 | ================================================== 8 | 9 | If you need some static field in your form, than you can define a new Form Class, inheriting *BaseDynamicForm* 10 | 11 | .. code-block:: python 12 | 13 | from django_form_builder import dynamic_fields 14 | from django_form_builder.forms import BaseDynamicForm 15 | 16 | class MyDynamicForm(BaseDynamicForm): 17 | def __init__(self, 18 | constructor_dict={}, 19 | custom_params={}, 20 | *args, 21 | **kwargs): 22 | # Add a custom static field common to all dynamic forms 23 | self.fields = {} 24 | my_static_field = dynamic_fields.format_field_name(choice_field_name) 25 | my_static_field_data = {'required' : True, 26 | 'label': choice_field_label, 27 | 'help_text': choice_field_helptext} 28 | my_static_field = getattr(dynamic_fields, 29 | 'CustomFieldClass')(**my_static_field_data) 30 | self.fields[my_static_field_id] = my_static_field 31 | self.fields[my_static_field_id].initial = self.descrizione_indicatore 32 | 33 | # call super() constructor to build form 34 | super().__init__(# define it only if you 35 | # define a custom field source, 36 | # see "Create your own fields" paragraph. 37 | # fields_source=dynamic_fields_integration, 38 | initial_fields=self.fields, 39 | constructor_dict=constructor_dict, 40 | custom_params=custom_params, 41 | *args, **kwargs) 42 | 43 | # if needed, override clean() method with your own params 44 | def clean(self, *args, **kwargs): 45 | cleaned_data = super().clean(own_param=own_value) 46 | -------------------------------------------------------------------------------- /README-dev.md: -------------------------------------------------------------------------------- 1 | from django_form_builder.forms import BaseDynamicForm 2 | from django_form_builder.models import DynamicFieldMap 3 | from collections import OrderedDict 4 | 5 | 6 | constructor_dict = OrderedDict([('Telefono', 7 | ('CustomCharField', 8 | {'label': 'Telefono', 9 | 'required': True, 10 | 'help_text': 'Fisso o Mobile', 11 | 'pre_text': ''}, 12 | '')), 13 | ('Credenziali attive dal', 14 | ('BaseDateField', 15 | {'label': 'Credenziali attive dal', 16 | 'required': True, 17 | 'help_text': 'Data di attivazione delle credenziali', 18 | 'pre_text': ''}, 19 | '')), 20 | ('al', 21 | ('BaseDateField', 22 | {'label': 'al', 23 | 'required': True, 24 | 'help_text': 'data di scadenza delle credenziali. ATTENZIONE: non saranno considerati valori superiori ai 2 anni.', 25 | 'pre_text': ''}, 26 | '')), 27 | ('Descrizione Attività', 28 | ('TextAreaField', 29 | {'label': 'Descrizione Attività', 30 | 'required': True, 31 | 'help_text': "Descrizione dell'attività per la quale si richiedono le credenziali", 32 | 'pre_text': ''}, 33 | '')), 34 | ('Richiede che le seguenti anagrafiche vengano attivate', 35 | ('CustomComplexTableField', 36 | {'label': 'Richiede che le seguenti anagrafiche vengano attivate', 37 | 'required': True, 38 | 'help_text': 'inserire almeno first_name, last_name e email', 39 | 'pre_text': ''}, 40 | 'first_name#last_name#place_of_birth#date_of_birth#codice_fiscale#email#tel#valid_until'))]) 41 | 42 | form = DynamicFieldMap.get_form(BaseDynamicForm, 43 | constructor_dict=constructor_dict, 44 | custom_params=None, 45 | #data=data, 46 | #files=files, 47 | remove_filefields=False, 48 | remove_datafields=False) 49 | 50 | -------------------------------------------------------------------------------- /django_form_builder/templates/examples/edit_form_example.html: -------------------------------------------------------------------------------- 1 | {% extends 'base_form_example.html' %} 2 | 3 | {% load django_form_builder_tags %} 4 | {% load i18n %} 5 | 6 | {% block allegati %} 7 | {% if allegati %} 8 |

{% trans "Attachments" %}

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% for k,v in allegati.items %} 18 | 19 | 22 | 23 | 35 | 51 | 52 | {% endfor %} 53 | 54 |
{% trans "Name" %}{% trans "File" %}{% trans "Details" %}
20 | {{k}} 21 | {{v}} 24 | {% get_attachment_sign_details form_with_attachments attachments_path k v as sign_details %} 25 | {% if sign_details %} 26 |
    27 | {% for kk, vv in sign_details.items %} 28 |
  • {{ kk }}: {{ vv }}
  • 29 | {% endfor %} 30 |
31 | {% else %} 32 | - 33 | {% endif %} 34 |
36 | 37 | 38 |
39 | 40 | {% trans "Download" %} 41 |
42 |
43 | 44 | 45 |
46 | 47 | {% trans "Remove" %} 48 |
49 |
50 |
55 | {% endif %} 56 | {% endblock allegati %} 57 | -------------------------------------------------------------------------------- /.github/workflows/python-app.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a single version of Python 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: django-form-builder 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | python-version: 21 | - '3.8' 22 | - '3.9' 23 | - '3.10' 24 | - '3.11' 25 | django-version: 26 | - '3.0' 27 | - '4.0' 28 | 29 | steps: 30 | - uses: actions/checkout@v2 31 | - name: Set up Python ${{ matrix.python-version }} 32 | uses: actions/setup-python@v2 33 | with: 34 | python-version: ${{ matrix.python-version }} 35 | - name: Install dependencies 36 | run: | 37 | python -m pip install --upgrade pip 38 | if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi 39 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 40 | - name: Lint with flake8 41 | run: | 42 | # stop the build if there are Python syntax errors or undefined names 43 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 44 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 45 | flake8 . --count --exit-zero --statistics 46 | 47 | - name: Test with Django tests 48 | working-directory: . 49 | run: | 50 | DJANGO_SETTINGS_MODULE=example.example.settings 51 | coverage erase 52 | coverage run ./example/manage.py test 53 | coverage report -m 54 | coverage report --fail-under=70 55 | coverage xml 56 | - name: Upload coverage to Codecov 57 | uses: codecov/codecov-action@v1 58 | with: 59 | token: ${{ secrets.CODECOV_TOKEN }} 60 | file: ./coverage.xml 61 | flags: unittests 62 | env_vars: OS,PYTHON 63 | name: codecov-umbrella 64 | fail_ci_if_error: true 65 | path_to_write_report: ./codecov_report.txt 66 | # verbose: true 67 | - name: Bandit Security Scan 68 | run: | 69 | bandit -r -x docs,django_form_builder/tests/* django_form_builder/* 70 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # http://www.sphinx-doc.org/en/master/config 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'Django Form Builder' 21 | copyright = '2019, Università della Calabria' 22 | author = 'Università della Calabria' 23 | 24 | # The full version, including alpha/beta/rc tags 25 | release = '0.1' 26 | 27 | 28 | # -- General configuration --------------------------------------------------- 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = [ 34 | ] 35 | 36 | # Add any paths that contain templates here, relative to this directory. 37 | templates_path = ['_templates/unical_template'] 38 | 39 | html_logo = "_static/unical_logo.svg" 40 | 41 | # List of patterns, relative to source directory, that match files and 42 | # directories to ignore when looking for source files. 43 | # This pattern also affects html_static_path and html_extra_path. 44 | exclude_patterns = [] 45 | 46 | # Add any Sphinx extension module names here, as strings. They can be 47 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 48 | # ones. 49 | extensions = [ 50 | 'sphinxcontrib.images', 51 | ] 52 | 53 | # -- Options for HTML output ------------------------------------------------- 54 | 55 | # The theme to use for HTML and HTML Help pages. See the documentation for 56 | # a list of builtin themes. 57 | # 58 | html_theme = 'sphinx_rtd_theme' 59 | 60 | # Add any paths that contain custom static files (such as style sheets) here, 61 | # relative to this directory. They are copied after the builtin static files, 62 | # so a file named "default.css" will overwrite the builtin "default.css". 63 | html_static_path = ['_static'] 64 | 65 | master_doc = 'index' 66 | -------------------------------------------------------------------------------- /example/form/templates/form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | {{ form.media }} 11 | 12 | 13 | 14 | {% if messages %} 15 |
    16 | {% for message in messages %} 17 |
  • {{ message|safe }}
  • 18 | {% endfor %} 19 |
20 |
21 | {% endif %} 22 | 23 | 24 | 25 |
26 | {% for field in form %} 27 | 28 | {{ field.field.pre_text }} 29 | 30 | {% if field.field.widget.input_type != 'hidden' %} 31 |
32 | 33 | {{ field.label_tag }} 34 | {% if field.field.required %}*{% endif %} 35 | 36 |
37 | {% endif %} 38 | 39 | {{ field }} 40 | 41 | 42 | {% if field.help_text %} 43 |
44 | 45 | {{ field.help_text|safe }} 46 | 47 | {% endif %} 48 | 49 | 50 | 51 | {% if field.errors and field.field.widget.input_type != 'hidden' %} 52 | 53 | {{ field.errors }} 54 | 55 | {% endif %} 56 | 57 | 58 | {% if field.field.widget.input_type != 'hidden' %} 59 |
60 | {% endif %} 61 | {% endfor %} 62 | {% csrf_token %} 63 | 64 |
65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CI build](https://github.com/UniversitaDellaCalabria/django-form-builder/workflows/django-form-builder/badge.svg) 2 | ![Python version](https://img.shields.io/badge/license-Apache%202-blue.svg) 3 | ![License](https://img.shields.io/badge/python-3.5%20%7C%203.6%20%7C%203.7%20%7C%203.8-blue.svg) 4 | 5 | 6 | Django Form Builder 7 | ------------------- 8 | 9 | A Django Framework application to build dynamic forms, with widgets and Django's standards, using JSON objects. 10 | 11 | Forms can be saved in a configurable storage (or settings.py). Users that requires high levels of customization will find what they're look for. 12 | 13 | Consult the [Official Documentation](https://django-form-builder.readthedocs.io/en/latest/index.html) at readthedocs for usage specifications and advanced topics. 14 | 15 | ![Home](docs/source/images/dyn_form_building.png) 16 | _**Image 1:** Example of Dynamic Form built via frontend_ 17 | 18 | ![Home](docs/source/images/dyn_form_preview.png) 19 | _**Image 2**: Preview of the builded form_ 20 | 21 | Features 22 | -------- 23 | 24 | - Forms definitions via JSON object 25 | - Save compiled form as JSON objects in model db and get its structure and contents with a simple model method call 26 | - Override form constructor in order to add static common fields 27 | - Create input fields using heritable classes, with customizable validation methods 28 | - Manage [Django Formset](https://docs.djangoproject.com/en/2.2/topics/forms/formsets/) fields, with form insertion and removal via javascript; 29 | - Manage and verify digitally signed file fields (PDF and P7M) without a certification authority validation (TODO via third-party API) 30 | - Audio and Image Captcha 31 | 32 | Examples 33 | -------- 34 | 35 | Example of a dynamic form JSON in database 36 | 37 | ```json 38 | { 39 | "field_1": "value_field_1", 40 | "field_2": "value_field_2", 41 | "field_3": "value_field_3", 42 | "attachments": { 43 | "p7m": "file_1.pdf.p7m", 44 | "pdf": "file_2.pdf" 45 | } 46 | } 47 | ``` 48 | 49 | CaPTCHA 50 | ------- 51 | 52 | In `settings.py` configure these parameters 53 | 54 | ```` 55 | CAPTCHA_SECRET = b'your_secret' 56 | CAPTCHA_SALT = b'your_salt' 57 | ```` 58 | 59 | Tests 60 | ----- 61 | 62 | ```` 63 | # build a virtualend where to install all the requirements and requirements-dev ... 64 | cd example 65 | ./manage.py test 66 | 67 | # coverage 68 | coverage erase 69 | coverage run ./manage.py test 70 | coverage report -m 71 | ```` 72 | 73 | 74 | Build 75 | ----- 76 | 77 | ```` 78 | rm -R build/ dist/ *egg-info 79 | python3 setup.py sdist 80 | twine upload dist/* 81 | ```` 82 | -------------------------------------------------------------------------------- /django_form_builder/formsets.py: -------------------------------------------------------------------------------- 1 | import ast 2 | import re 3 | import sys 4 | from django import forms 5 | from django.conf import settings 6 | from django.utils.module_loading import import_string 7 | 8 | from . settings import CUSTOM_WIDGETS_IN_FORMSETS 9 | from . utils import format_field_name, _split_choices 10 | 11 | 12 | def get_empty_form(form_class=forms.Form): 13 | class Dynamic(form_class): 14 | pass 15 | return Dynamic 16 | 17 | 18 | def build_formset(choices, extra=0, required=False, prefix='form', data={}, files={}): 19 | """ Get formset 20 | """ 21 | _regexp = '(?P[a-zA-Z0-9À-ÿ\'\"\_ ]*)\((?P[\{\}\.0-9a-zA-ZÀ-ÿ\'\"\:\;\_\,\s\- ]*)\)' 22 | min_num = 0 23 | if required: min_num = 1 24 | eform = get_empty_form() 25 | for choice in choices: 26 | colname = format_field_name(choice) # needed for simple CharField withoud attrs 27 | contenuto = re.search(_regexp, choice) 28 | field_dict = None 29 | mod_name = __package__ + '.dynamic_fields' 30 | sysmod = sys.modules[mod_name] 31 | if contenuto: 32 | coldict = contenuto.groupdict().get('coldict') 33 | colname = format_field_name(contenuto.groupdict()['colname']) 34 | if coldict: 35 | field_dict = ast.literal_eval(coldict) 36 | field_type_name = field_dict['type'] 37 | del field_dict['type'] 38 | custom_field = getattr(sysmod, field_type_name)(**field_dict) \ 39 | if hasattr(sysmod, field_type_name) \ 40 | else getattr(sysmod, 'CustomCharField')() 41 | # choice if use or not fields custom widget 42 | # javascript may cause some problem 43 | use_custom_widget = getattr(settings, 'CUSTOM_WIDGETS_IN_FORMSETS', CUSTOM_WIDGETS_IN_FORMSETS) 44 | if use_custom_widget: 45 | custom_widget = getattr(settings, 'CUSTOM_WIDGETS').get(field_type_name) \ 46 | if hasattr(settings, 'CUSTOM_WIDGETS') else None 47 | if custom_widget: 48 | custom_field.widget = import_string(custom_widget)() 49 | 50 | if field_dict.get('choices'): 51 | custom_field.choices += _split_choices(field_dict.get('choices')) 52 | else: 53 | # custom_field = forms.CharField() 54 | custom_field = getattr(sysmod, 'CustomCharField')() 55 | eform.base_fields[colname] = custom_field 56 | eform.declared_fields[colname] = custom_field 57 | 58 | # Django formset 59 | fac = forms.formset_factory(eform, extra=extra, min_num=min_num) 60 | if data: 61 | return fac(prefix=prefix, data=data, files=files) 62 | return fac(prefix=prefix) 63 | -------------------------------------------------------------------------------- /django_form_builder/settings.py: -------------------------------------------------------------------------------- 1 | from django.utils.translation import gettext_lazy as _ 2 | 3 | 4 | CLASSIFICATION_LIST = (('protocollo', _('Protocollo')), 5 | ('decreto_rettorale', _('Decreto Rettorale (D.R.)')), 6 | ('decreto_direttore_generale', _('Decreto del Direttore Generale (D.D.G.)')), 7 | ('decreto_dirigente_struttura', _('Decreto del Direttore Dipartimento o Dirigente Struttura')), 8 | ('decreto_direttore_cr', _('Decreto del Direttore del Centro Residenziale (D.CR.)')), 9 | ('decreto_prorettore', _('Decreto del Prorettore (Centro Residenziale)')), 10 | ('delibera_dipartimento_facolta', _('Delibera di Dipartimento/Facoltà')), 11 | ('delibera_senato', _('Delibera del Senato')), 12 | ('delibera_cda', _('Delibera del C.D.A.'))) 13 | 14 | # 2.5MB - 2621440 15 | # 5MB - 5242880 16 | # 10MB - 10485760 17 | # 20MB - 20971520 18 | # 50MB - 5242880 19 | # 100MB 104857600 20 | # 250MB - 214958080 21 | # 500MB - 429916160 22 | MAX_UPLOAD_SIZE = 10485760 23 | 24 | PDF_FILETYPE = ('application/pdf',) 25 | DATA_FILETYPE = ('text/csv', 'application/json', 26 | 'application/vnd.ms-excel', 27 | 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 28 | 'application/vnd.oasis.opendocument.spreadsheet', 29 | 'application/wps-office.xls', 30 | ) 31 | TEXT_FILETYPE = ('text/plain', 32 | 'application/vnd.oasis.opendocument.text', 33 | 'application/msword', 34 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 35 | ) 36 | IMG_FILETYPE = ('image/jpeg', 'image/png', 'image/gif', 'image/x-ms-bmp') 37 | P7M_FILETYPE = ('application/pkcs7-mime',) 38 | SIGNED_FILETYPE = PDF_FILETYPE + P7M_FILETYPE 39 | PERMITTED_UPLOAD_FILETYPE = TEXT_FILETYPE + DATA_FILETYPE + SIGNED_FILETYPE + IMG_FILETYPE 40 | 41 | # maximum permitted filename lengh in attachments, uploads 42 | ATTACH_NAME_MAX_LEN = 50 43 | 44 | ATTACHMENTS_DICT_PREFIX = "allegati" 45 | 46 | # attachments validation messages 47 | WRONG_TYPE = _("Per favore esegui l'upload di soli file " 48 | "in {}. " 49 | "Attualmente questo è '{}'") 50 | WRONG_SIZE = _("Per favore mantieni la dimensione del file entro {}. " 51 | "Attualmente questo è {}") 52 | WRONG_LENGTH = _("Per favore usa una lunghezza massima del nome dell'allegato " 53 | "inferiore a {}. Attualmente hai inserito un nome di {} caratteri") 54 | 55 | # formset special words 56 | FORMSET_REGEX = "^(?P{})-(?P[0-9]+)-(?P[a-zA-ZÀ-ÿ0-9_°^\-\'\"]+)$" 57 | FORMSET_FULL_REGEX = FORMSET_REGEX.format("[a-zA-ZÀ-ÿ0-9_°^\-\'\"]+") 58 | 59 | FORMSET_TEMPLATE_NAMEID = 'NNNNN' 60 | MANAGEMENT_FORMSET_STRINGS = [FORMSET_TEMPLATE_NAMEID, 61 | '-TOTAL_FORMS', '-INITIAL_FORMS', 62 | '-MAX_NUM_FORMS','-MIN_NUM_FORMS'] 63 | 64 | CAPTCHA_DEFAULT_LANG = 'en' 65 | CAPTCHA_EXPIRATION_TIME = 120000 # milliseconds 66 | CUSTOM_WIDGETS_IN_FORMSETS = True 67 | -------------------------------------------------------------------------------- /docs/build/html/_static/css/badge_only.css: -------------------------------------------------------------------------------- 1 | .fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../fonts/fontawesome-webfont.eot");src:url("../fonts/fontawesome-webfont.eot?#iefix") format("embedded-opentype"),url("../fonts/fontawesome-webfont.woff") format("woff"),url("../fonts/fontawesome-webfont.ttf") format("truetype"),url("../fonts/fontawesome-webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} 2 | -------------------------------------------------------------------------------- /docs/source/usage/dynamic-forms/description.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Build dynamic forms 7 | =================== 8 | 9 | Now you can build your own form dynamically both in Django backend and frontend, just selecting the fields that you want, 10 | in total flexibility and easiness. 11 | 12 | Every form can be saved in a configurable storage, in JSON format or simply defined in a Python Dictionary. 13 | Please see ``django_dynamic_form.dynamic_fields`` to see all the supported type. 14 | 15 | 16 | :: 17 | 18 | from django_form_builder.forms import BaseDynamicForm 19 | from collections import OrderedDict 20 | 21 | constructor_dict = OrderedDict([('Telefono', # field name 22 | ('CustomCharField', # defines the FieldType 23 | {'label': 'Telefono', 24 | 'required': True, 25 | 'help_text': 'Fisso o Mobile', 26 | 'pre_text': ''}, # a text to be rendered before the input field 27 | '')), 28 | ('Credenziali attive dal', 29 | ('BaseDateField', 30 | {'label': 'Credenziali attive dal', 31 | 'required': True, 32 | 'help_text': 'Data di attivazione delle credenziali', 33 | 'pre_text': ''}, 34 | '')), 35 | ('al', 36 | ('BaseDateField', 37 | {'label': 'al', 38 | 'required': True, 39 | 'help_text': 'data di scadenza delle credenziali.', 40 | 'pre_text': ''}, 41 | '')), 42 | ('Descrizione Attività', 43 | ('TextAreaField', 44 | {'label': 'Descrizione Attività', 45 | 'required': True, 46 | 'help_text': "Descrizione dell'attività per la quale si richiedono le credenziali", 47 | 'pre_text': ''}, 48 | '')), 49 | ('Richiede che le seguenti anagrafiche vengano attivate', 50 | ('CustomComplexTableField', # a django fieldset 51 | {'label': 'Richiede che le seguenti anagrafiche vengano attivate', 52 | 'required': True, 53 | 'help_text': 'inserire almeno first_name, last_name e email', 54 | 'pre_text': ''}, 55 | 'first_name#last_name#place_of_birth#date_of_birth#codice_fiscale#email#tel#valid_until'))]) 56 | 57 | form = BaseDynamicForm.get_form(#class_obj=YourCustomDynFormClass, # None by default, then use BaseDynamicForm 58 | constructor_dict=constructor_dict, 59 | custom_params=None, 60 | #data=data, # if there's some data to load 61 | #files=files, # if there's some file attachments (handled separately) 62 | remove_filefields=False, 63 | remove_datafields=False) 64 | 65 | -------------------------------- 66 | 67 | *Example of Dynamic Form built via frontend:* 68 | 69 | .. thumbnail:: ../../images/dyn_form_building.png 70 | 71 | *Preview of the builded form:* 72 | 73 | .. thumbnail:: ../../images/dyn_form_preview.png 74 | -------------------------------------------------------------------------------- /django_form_builder/locale/en/django.po: -------------------------------------------------------------------------------- 1 | # django-form-builder 2 | # en 3 | 4 | msgid "Testo" 5 | msgstr "Text" 6 | 7 | msgid "Indirizzo IP" 8 | msgstr "IP Address" 9 | 10 | msgid "Formato non valido" 11 | msgstr "Invalid format" 12 | 13 | msgid "Numero massimo di scelte consentito: {}" 14 | msgstr "Max allowed choices: {}" 15 | 16 | msgid "Allegato (generico)" 17 | msgstr "Attachment (generic)" 18 | 19 | msgid "Allegato Immagine" 20 | msgstr "Picture attachment" 21 | 22 | msgid "Allegato file dati (JSON, CSV, Excel)" 23 | msgstr "Data file attachment (JSON, CSV, Excel)" 24 | 25 | msgid "Allegato PDF" 26 | msgstr "PDF Attachment" 27 | 28 | msgid "Allegato PDF firmato" 29 | msgstr "Signed PDF Attachment" 30 | 31 | msgid "Errore di validazione della firma digitale" 32 | msgstr "Digital sign validation error " 33 | 34 | msgid "Numero intero positivo" 35 | msgstr "Positive integer field" 36 | 37 | msgid "Solo numeri ammessi" 38 | msgstr "Only number admitted" 39 | 40 | msgid "Numero con virgola positivo" 41 | msgstr "Positive float number" 42 | 43 | msgid "Testo lungo" 44 | msgstr "Long text" 45 | 46 | msgid "Checkbox multi-valore" 47 | msgstr "Multi-value checkbox" 48 | 49 | msgid "Lista di opzioni (tendina)" 50 | msgstr "Selectbox" 51 | 52 | msgid "Lista di opzioni (checkbox)" 53 | msgstr "Radiobox" 54 | 55 | msgid "Data" 56 | msgstr "Date" 57 | 58 | msgid "Data e Ora (campi separati)" 59 | msgstr "Datetime (separated fields)" 60 | 61 | msgid "Data e ora (campo singolo)" 62 | msgstr "Datetime (single field)" 63 | 64 | msgid "Ore" 65 | msgstr "Hours" 66 | 67 | msgid "Minuti" 68 | msgstr "Minutes" 69 | 70 | msgid "Data inizio e Data fine" 71 | msgstr "Start date and End date" 72 | 73 | msgid "Data inizio" 74 | msgstr "Start date" 75 | 76 | msgid "Data fine" 77 | msgstr "End date" 78 | 79 | msgid "La data di inizio non può essere successiva a quella di fine" 80 | msgstr "The start date cannot be later than the end date" 81 | 82 | msgid "Protocollo (tipo/numero/data)" 83 | msgstr "Protocol (type/number/date)" 84 | 85 | msgid "Tipo numerazione" 86 | msgstr "Type" 87 | 88 | msgid "Scegli se protocollo/decreto/delibera, al/alla quale la numerazione è riferita" 89 | msgstr "Choose whether protocol/decree/resolution, to which the numbering refers" 90 | 91 | msgid "Numero Protocollo/Delibera/Decreto" 92 | msgstr "Number" 93 | 94 | msgid "Indica il numero del protocollo/decreto/delibera" 95 | msgstr "Indicates the number of the protocol/decree/resolution" 96 | 97 | msgid "Data Protocollo/Delibera/Decreto" 98 | msgstr "Date" 99 | 100 | msgid "Indica la data del protocollo/decreto/delibera" 101 | msgstr "Indicates the date of the protocol/decree/resolution" 102 | 103 | msgid "Valore mancante" 104 | msgstr "Missing value" 105 | 106 | msgid "La data di protocollo non può essere successiva ad oggi" 107 | msgstr "The protocol date cannot be later than today" 108 | 109 | msgid "Campo nascosto" 110 | msgstr "Hidden field" 111 | 112 | msgid "Questo campo necessita di almeno una riga" 113 | msgstr "This field needs at least one row" 114 | 115 | msgid "Inserimenti multipli" 116 | msgstr "Formset" 117 | 118 | msgid "Aggiungi inserimento" 119 | msgstr "Add another one" 120 | 121 | msgid "Rimuovi inserimento" 122 | msgstr "Remove this one" 123 | 124 | msgid "Errore nella costruzione del campo" 125 | msgstr "Error in field building" 126 | 127 | msgid "La definizione delle righe non è corretta" 128 | msgstr "The definition of the rows is incorrect" 129 | 130 | msgid "Verifica la denominazione delle classi ed evita l'utilizzo di caratteri speciali" 131 | msgstr "Check the naming of the classes and avoid using special characters" 132 | -------------------------------------------------------------------------------- /django_form_builder/tests/base.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.files.uploadedfile import SimpleUploadedFile 4 | from django.test import TestCase 5 | 6 | from django_form_builder import dynamic_fields 7 | from django_form_builder.forms import BaseDynamicForm 8 | from django_form_builder.models import * 9 | from django_form_builder.utils import format_field_name 10 | 11 | 12 | class BaseTest(TestCase): 13 | 14 | def get_baseform(self, initial_fields, data={}, files={}): 15 | """ 16 | Build a form from BaseDynamicForm 17 | """ 18 | form = BaseDynamicForm.get_form(initial_fields=initial_fields, 19 | data=data, 20 | files=files) 21 | return form 22 | 23 | def create_field(self, field_class, field_label='', required=True): 24 | """ 25 | Create a field using class name 26 | """ 27 | label = field_label or 'test field' 28 | field_data = {'required': required, 29 | 'label': label} 30 | field = getattr(dynamic_fields, field_class)(**field_data) 31 | if field.is_complex: 32 | return field.get_fields() 33 | return [field,] 34 | 35 | def create_fake_file(self, name="test", ext="pdf", 36 | content_type="application/pdf"): 37 | """ 38 | Create a fake file to simulate upload 39 | """ 40 | return SimpleUploadedFile("{}.{}".format(name, ext), 41 | b"file_content", 42 | content_type=content_type) 43 | 44 | def get_file(self, real_file_name, 45 | name="test", ext="pdf", 46 | content_type="application/pdf"): 47 | """ 48 | Simulate upload using a real file 49 | """ 50 | if not real_file_name: return None 51 | module_dir = "{}/{}".format(os.path.dirname(__file__), "files") 52 | file_path = os.path.join(module_dir, real_file_name) 53 | file_obj = open(file_path, 'rb') 54 | return SimpleUploadedFile("{}.{}".format(name, ext), 55 | file_obj.read(), 56 | content_type=content_type) 57 | 58 | def single_field_form(self, field_class, 59 | data_value='{}', file_value='{}', 60 | required=True): 61 | """ 62 | Build a form with a single field 63 | """ 64 | field = self.create_field(field_class=field_class, 65 | required=required)[0] 66 | field_id = format_field_name(field.label) 67 | initial_fields = {field_id: field} 68 | data = {field_id: data_value} 69 | files = {field_id: file_value} 70 | form = self.get_baseform(initial_fields=initial_fields, 71 | data=data, 72 | files=files) 73 | return form 74 | 75 | def complex_field_form(self, field_class, data, field_label=''): 76 | """ 77 | Build a form with a single complex field 78 | """ 79 | fields = self.create_field(field_class, field_label) 80 | initial_fields = {} 81 | for field in fields: 82 | initial_fields[field.name] = field 83 | data = data 84 | form = self.get_baseform(initial_fields=initial_fields, 85 | data=data) 86 | return form 87 | 88 | def get_filepath(self): 89 | return "{}/{}".format(os.path.dirname(__file__), "files") 90 | 91 | def get_full_filepath(self, filename): 92 | module_dir = "{}/{}".format(os.path.dirname(__file__), "files") 93 | return os.path.join(module_dir, filename) 94 | -------------------------------------------------------------------------------- /example/example/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for example project. 3 | 4 | Generated by 'django-admin startproject' using Django 3.0.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/3.0/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/3.0/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '!ng(6w-+f-0f#lh8qpf-j=qe3=hkhzz5o&e_j_na7&818sc81f' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | 'django_form_builder', 42 | 'form', 43 | ] 44 | 45 | MIDDLEWARE = [ 46 | 'django.middleware.security.SecurityMiddleware', 47 | 'django.contrib.sessions.middleware.SessionMiddleware', 48 | 'django.middleware.common.CommonMiddleware', 49 | 'django.middleware.csrf.CsrfViewMiddleware', 50 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 51 | 'django.contrib.messages.middleware.MessageMiddleware', 52 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 53 | ] 54 | 55 | ROOT_URLCONF = 'example.urls' 56 | 57 | TEMPLATES = [ 58 | { 59 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 60 | 'DIRS': [], 61 | 'APP_DIRS': True, 62 | 'OPTIONS': { 63 | 'context_processors': [ 64 | 'django.template.context_processors.debug', 65 | 'django.template.context_processors.request', 66 | 'django.contrib.auth.context_processors.auth', 67 | 'django.contrib.messages.context_processors.messages', 68 | ], 69 | }, 70 | }, 71 | ] 72 | 73 | WSGI_APPLICATION = 'example.wsgi.application' 74 | 75 | 76 | # Database 77 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 78 | 79 | DATABASES = { 80 | 'default': { 81 | 'ENGINE': 'django.db.backends.sqlite3', 82 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 83 | } 84 | } 85 | 86 | 87 | # Password validation 88 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 89 | 90 | AUTH_PASSWORD_VALIDATORS = [ 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 96 | }, 97 | { 98 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 99 | }, 100 | { 101 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 102 | }, 103 | ] 104 | 105 | 106 | # Internationalization 107 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 108 | 109 | LANGUAGE_CODE = 'en-us' 110 | TIME_ZONE = 'UTC' 111 | USE_I18N = True 112 | USE_L10N = True 113 | USE_TZ = True 114 | 115 | 116 | # Static files (CSS, JavaScript, Images) 117 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 118 | 119 | STATIC_URL = '/static/' 120 | 121 | # prints to stdout when test runs 122 | NOSE_ARGS = ['--nocapture', 123 | '--nologcapture',] 124 | -------------------------------------------------------------------------------- /example/form/views.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | 3 | from django.contrib import messages 4 | from django.http import HttpResponse 5 | from django.shortcuts import render 6 | from django.views.decorators.csrf import csrf_exempt 7 | from django.utils.html import strip_tags 8 | 9 | from django_form_builder.forms import BaseDynamicForm 10 | from django_form_builder.utils import get_labeled_errors 11 | 12 | 13 | # this is the dictionary that builds the DynamicForm 14 | constructor_dict = OrderedDict([ 15 | # CharField 16 | ('Telefono', 17 | ('CustomCharField', 18 | {'label': 'Telefono', 19 | 'required': True, 20 | 'help_text': 'Fisso o Mobile', 21 | 'pre_text': ''}, 22 | '') 23 | ), 24 | # Complex field (start date / end date) 25 | ('Credenziali attive dal/al', 26 | ('DateStartEndComplexField', 27 | {'label': 'Credenziali attive dal/al', 28 | 'required': True, 29 | 'help_text': 'Data di attivazione e disattivazione delle credenziali', 30 | 'pre_text': ''}, 31 | '') 32 | ), 33 | # TextField 34 | ('Descrizione Attività', 35 | ('TextAreaField', 36 | {'label': 'Descrizione Attività', 37 | 'required': True, 38 | 'help_text': "Descrizione dell'attività per la quale si richiedono le credenziali", 39 | 'pre_text': ''}, 40 | '') 41 | ), 42 | # Formset 43 | ('Richiede che le seguenti anagrafiche vengano attivate', 44 | ('CustomComplexTableField', 45 | {'label': 'Richiede che le seguenti anagrafiche vengano attivate', 46 | 'required': True, 47 | 'help_text': '', 48 | 'pre_text': 'This is a formset, this text is printed before rendering field'}, 49 | # Columns of tables with different field types 50 | 'first_name({"type":"CustomSelectBoxField","choices":"v1;v2;v3"})' 51 | '#' 52 | 'last_name' 53 | '#' 54 | 'place_of_birth' 55 | '#' 56 | 'date_of_birth' 57 | '#' 58 | 'codice_fiscale' 59 | '#' 60 | 'email({"type":"CustomEmailField"})' 61 | '#' 62 | 'tel({"type":"PositiveIntegerField"})' 63 | '#' 64 | 'valid_until({"type":"BaseDateField"})') 65 | ), 66 | # Captcha 67 | ('CaPTCHA', 68 | ('CustomCaptchaComplexField', 69 | {'label': 'CaPTCHA', 70 | 'pre_text': ''}, 71 | '') 72 | ), 73 | ]) 74 | 75 | 76 | @csrf_exempt 77 | def dynform(request): 78 | if request.method == 'GET': 79 | form = BaseDynamicForm.get_form(constructor_dict=constructor_dict, 80 | #data=data, 81 | #files=files, 82 | remove_filefields=False, 83 | remove_datafields=False) 84 | # if POST (form submitted) 85 | else: 86 | form = BaseDynamicForm.get_form(constructor_dict=constructor_dict, 87 | data=request.POST, 88 | files=request.FILES, 89 | remove_filefields=False, 90 | remove_datafields=False) 91 | 92 | if form.is_valid(): 93 | messages.add_message(request, messages.SUCCESS, "form is valid") 94 | else: 95 | # show all error messages 96 | for k,v in get_labeled_errors(form).items(): 97 | messages.add_message(request, messages.ERROR, 98 | "{}: {}".format(k, strip_tags(v))) 99 | 100 | d = {'form': form} 101 | return render(request, "form.html", d) 102 | -------------------------------------------------------------------------------- /docs/build/html/_static/js/theme.js: -------------------------------------------------------------------------------- 1 | /* sphinx_rtd_theme version 0.4.3 | MIT license */ 2 | /* Built 20190212 16:02 */ 3 | require=function r(s,a,l){function c(e,n){if(!a[e]){if(!s[e]){var i="function"==typeof require&&require;if(!n&&i)return i(e,!0);if(u)return u(e,!0);var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}var o=a[e]={exports:{}};s[e][0].call(o.exports,function(n){return c(s[e][1][n]||n)},o,o.exports,r,s,a,l)}return a[e].exports}for(var u="function"==typeof require&&require,n=0;n"),i("table.docutils.footnote").wrap("
"),i("table.docutils.citation").wrap("
"),i(".wy-menu-vertical ul").not(".simple").siblings("a").each(function(){var e=i(this);expand=i(''),expand.on("click",function(n){return t.toggleCurrent(e),n.stopPropagation(),!1}),e.prepend(expand)})},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),i=e.find('[href="'+n+'"]');if(0===i.length){var t=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(i=e.find('[href="#'+t.attr("id")+'"]')).length&&(i=e.find('[href="#"]'))}0this.docHeight||(this.navBar.scrollTop(i),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",function(){this.linkScroll=!1})},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current"),e.siblings().find("li.current").removeClass("current"),e.find("> ul li.current").removeClass("current"),e.toggleClass("current")}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:e.exports.ThemeNav,StickyNav:e.exports.ThemeNav}),function(){for(var r=0,n=["ms","moz","webkit","o"],e=0;e 1) 40 | var splitted = target[0].split('-'); 41 | var index = splitted[splitted.length-1]; 42 | // decrease the index (es: form-1 -> form-0) 43 | var new_html = parent_html.replace(id_regex, 44 | prefix+'-'+(parseInt(index)-1)); 45 | // update the parent_div HTML code 46 | parent_div.html(new_html); 47 | // return false 48 | return false; 49 | } 50 | 51 | /** 52 | * Delete the form and update the ID indexes of successive forms 53 | * @param {element} to_remove: the element that contains the "remove" button and the form 54 | * @param {String} prefix: the Django formset prefix 55 | * @param {String} container_class_div: the class of div that contains the form 56 | */ 57 | function deleteForm(to_remove, prefix, container_class_div) { 58 | // calculate the number of total forms in formset 59 | total = $('#id_' + prefix + '-TOTAL_FORMS').val(); 60 | // retrieve all the forms following the one I'm deleting 61 | var successive_forms = to_remove.nextAll(container_class_div); 62 | // reindex each of them 63 | successive_forms.each(function(){ 64 | reindex_forms($(this), prefix); 65 | }); 66 | // remove the form 67 | to_remove.remove(); 68 | // decrease total number 69 | total--; 70 | $('#id_' + prefix + '-TOTAL_FORMS').val(total); 71 | } 72 | 73 | // "add new form" event using the generic form template 74 | $(document).on('click', '.add-form-row', function(e){ 75 | // If this method is called, the default action of the event will not be triggered. 76 | e.preventDefault(); 77 | // get formset prefix 78 | var formset_prefix = $(this).attr('id').split(/add-form-(.+)/)[1] 79 | // get formset template 80 | var formset_template = $('#formset-template-'+formset_prefix); 81 | // get generic_id attribute 82 | var generic_id = formset_template.attr('generic_id') 83 | // get the position of "add new" button 84 | var position = $(this).parent(); 85 | // clone the template and create a new form in formset 86 | clone(formset_template, formset_prefix, position, generic_id); 87 | // return false 88 | return false; 89 | }); 90 | 91 | // "remove form" event 92 | $(document).on('click', '.remove-form-row', function(e){ 93 | // If this method is called, the default action of the event will not be triggered. 94 | e.preventDefault(); 95 | // get the CSS class of element that contains form and button 96 | var container_class = '.form-container'; 97 | // get formset prefix 98 | var prefix = $(this).attr('id').split(/-[0-9+]/)[0] 99 | // get the element to remove (contains the form and the "remove" button) 100 | var to_remove = $(this).closest(container_class); 101 | // call deleteForm method 102 | deleteForm(to_remove, prefix, container_class); 103 | // return false 104 | return false; 105 | }); 106 | -------------------------------------------------------------------------------- /django_form_builder/models.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sys 3 | 4 | from django.db import models 5 | from django.utils.translation import gettext_lazy as _ 6 | 7 | from . dynamic_fields import get_fields_types 8 | from . forms import BaseDynamicForm 9 | from . utils import get_as_dict 10 | 11 | 12 | _dynamic_fields = get_fields_types() 13 | if 'makemigrations' in sys.argv or 'migrate' in sys.argv: # pragma: no cover 14 | _dynamic_fields = [('', '-')] 15 | 16 | 17 | class DynamicFieldMap(models.Model): 18 | """ 19 | """ 20 | name = models.CharField(max_length=150,) 21 | field_type = models.CharField(max_length=100, 22 | choices = _dynamic_fields) 23 | valore = models.TextField(max_length=20000, 24 | blank=True, 25 | default='', 26 | verbose_name=_('Lista di Valori'), 27 | help_text=_("Viene considerato solo se si sceglie" 28 | " 'Menu a tendina' oppure 'Serie di Opzioni'." 29 | " (Es: valore1;valore2;valore3...)")) 30 | is_required = models.BooleanField(default=True) 31 | aiuto = models.CharField(max_length=254, blank=True, default='') 32 | pre_text = models.TextField(blank=True, default='') 33 | ordinamento = models.PositiveIntegerField(help_text=_("posizione nell'ordinamento"), 34 | blank=True, 35 | default=0) 36 | 37 | class Meta: 38 | abstract = True 39 | ordering = ('ordinamento',) 40 | 41 | 42 | class SavedFormContent(models.Model): 43 | """ 44 | """ 45 | # libreria esterna oppure cambio client per JsonField 46 | # non serve gestirlo come JsonField perchè non vi facciamo ricerche al suo interno ;) 47 | modulo_compilato = models.TextField() 48 | 49 | @staticmethod 50 | def compiled_form(data_source=None, 51 | constructor_dict={}, 52 | files=None, 53 | remove_filefields=True, 54 | remove_datafields=False, 55 | form_source=None, 56 | # fields_order=[], 57 | extra_datas={}, 58 | **kwargs): 59 | """ 60 | Returns form compiled by data (json_dict = json.loads(data_source)) 61 | """ 62 | json_dict = json.loads(data_source) 63 | data = get_as_dict(json_dict, allegati=False) 64 | if extra_datas: 65 | for k,v in extra_datas.items(): 66 | data[k]=v 67 | if not form_source: 68 | form_source = BaseDynamicForm 69 | form = form_source.get_form(constructor_dict=constructor_dict, 70 | data=data, 71 | files=files, 72 | remove_filefields=remove_filefields, 73 | remove_datafields=remove_datafields, 74 | **kwargs) 75 | # Già invocato nel "form_source", ma è bene tenerlo come riferimento 76 | # if fields_order: 77 | # form.order_fields(fields_order) 78 | return form 79 | 80 | @staticmethod 81 | def compiled_form_readonly(form, attr='disabled', fields_to_remove=[]): 82 | """ 83 | Returns a more clean version of the compiled_form. 84 | - Not compiled fields aren't shown (remove_not_compiled_fields()); 85 | - Title attribute by default isn't shown; 86 | - Form fields are readonly. 87 | Note: SelectBox aren't affected by readonly attribute! 88 | 89 | This method is useful to produce not editable compiled form. 90 | """ 91 | form.remove_not_compiled_fields() 92 | for field_to_remove in fields_to_remove: 93 | del form.fields[field_to_remove] 94 | for generic_field in form: 95 | field = form.fields[generic_field.name] 96 | widget = field.widget 97 | widget.attrs[attr] = True 98 | # If field is a Formset, the widget will make it readonly 99 | if field.is_formset: 100 | widget.make_readonly(attr) 101 | continue 102 | # Es: TextArea non ha attributo 'input_type' 103 | # Senza questo controllo il codice genera un'eccezione 104 | if not hasattr(widget, 'input_type'): 105 | # widget.attrs[attr] = True 106 | continue 107 | tipo = widget.input_type 108 | if tipo in ['select', 'checkbox', 'radiobox']: 109 | widget.attrs['disabled'] = True 110 | # else: 111 | # widget.attrs[attr] = True 112 | return form 113 | 114 | class Meta: 115 | abstract = True 116 | -------------------------------------------------------------------------------- /docs/build/html/searchindex.js: -------------------------------------------------------------------------------- 1 | Search.setIndex({docnames:["features/formset","features/signed-files","index","install/requirements-setup","usage/dynamic-forms/configuration","usage/dynamic-forms/customization","usage/dynamic-forms/description","usage/single-fields/customization","usage/single-fields/description","usage/single-fields/methods"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,sphinx:55},filenames:["features/formset.rst","features/signed-files.rst","index.rst","install/requirements-setup.rst","usage/dynamic-forms/configuration.rst","usage/dynamic-forms/customization.rst","usage/dynamic-forms/description.rst","usage/single-fields/customization.rst","usage/single-fields/description.rst","usage/single-fields/methods.rst"],objects:{},objnames:{},objtypes:{},terms:{"char":0,"class":[1,2,4,5,7,9],"default":[0,9],"function":8,"import":[4,5,7,8],"new":[4,5],"return":[1,4,9],"static":[2,4],"super":5,"true":[4,5,9],The:0,Use:2,__init__:5,_meta:4,accord:7,add:2,all:[4,5],allow:0,also:[1,3,4],api:2,app:[3,8],applic:2,arg:5,attach:[1,2,3],attribut:[0,2,4],author:2,backend:6,base:[1,9],basecustomfield:[7,9],basedatefield:0,basedynamicform:5,behaviour:9,book:4,both:6,build:[0,2,4,5],build_constructor_dict:4,builder:0,built:[0,1,6],button:0,call:[1,2,4,5],can:[5,6,7,8],car:4,cascad:4,certif:2,check:1,child:9,choic:[0,4,9],choice_field_helptext:5,choice_field_label:5,choice_field_nam:5,choos:4,class_nam:4,class_obj:4,clean:[5,8,9],cleaned_data:[5,9],column1:0,column2:0,column3:0,column4:0,column:0,columun:0,com:[2,3],common:[2,5],compil:[2,4],compiled_form:4,compos:[4,9],configur:[2,6,9],constructor:[2,4,5],constructor_dict:[4,5],contain:4,content:[2,4],creat:[2,4],custom:[1,2,4,5,9],custom_param:[4,5],custom_valu:9,customcharfield:0,customcomplextablefield:0,customfieldclass:5,customiz:[2,9],customradioboxfield:0,customselectboxfield:0,customsignedfilefield:1,customsignedp7mfield:1,customsignedpdffield:1,data:4,data_sourc:4,datefield:9,declar:7,def:[4,5,9],defin:[0,2,4,5,7,9],define_valu:[7,9],definit:2,depend:3,descript:2,descrizione_indicator:5,detail:[1,4],dict:0,dictionari:[0,4],differ:4,digit:[1,2,3],distinguish:1,divid:0,django:[0,6,9],django_form_build:[3,4,5,7,8],dynam:[2,5],dynamic_field:[4,5,7,8],dynamic_fields_integr:5,dynamicfieldclassnam:[7,8],dynamicfieldmap:4,each:[0,4],easi:6,easili:0,elementar:9,els:[4,9],empti:4,enabl:0,entiti:4,everi:[0,4,6,8,9],exampl:[0,6],exist:7,extra_1:4,extra_2:4,fals:[4,9],fastli:7,featur:[2,8],field:[0,1,2,4,6],field_typ:4,fields_sourc:5,file:[2,4],filefield:4,filesignaturevalid:[1,3],fill:4,flexibl:6,foreign:4,foreignkei:4,form:[0,5],form_fields_from_model:4,form_sourc:4,format:6,format_field_nam:5,formset:[2,9],foundament:9,framework:2,from:[4,5,7,8],frontend:[0,6],full:1,gener:0,get:2,get_cleaned_signature_param:1,get_field:[4,7,9],get_fields_typ:4,get_form:4,getattr:5,git:3,github:[2,3],has:[4,8],have:[4,9],help_text:5,herit:2,his:0,http:[2,3],implement:8,includ:[3,8],inherit:[4,5,7,8],initi:[5,9],initial_field:5,input:2,insert:[0,2],instal:[2,3],installed_app:3,integr:[4,9],is_complex:9,is_formset:9,its:[2,4],javascript:2,json:[2,4,6],just:[0,6,8],kei:4,kind:4,kwarg:[4,5,9],label:5,librari:[1,3],like:[0,9],link:4,list:[4,9],make:[4,7,9],manag:2,map:4,method:[1,2,4,5,8],model:[2,4],modulo_compilato:4,more:[4,9],my_custom_fields_fil:4,my_ent:4,my_field:8,my_static_field:5,my_static_field_data:5,my_static_field_id:5,mycustomfield:7,mydynamicform:[4,5],myentityclass:4,myfieldslistmodel:4,mymodelclass:4,name:[1,9],need:[3,4,5,7],none:[4,9],normal:8,now:6,object:[2,4],on_delet:4,onc:4,one:[0,4,7],onli:[3,4,5],order:2,order_bi:4,ordinamento:4,other:[3,4],other_extra_param:4,our:4,overrid:[2,4,5,7,8],own:[2,4,5,6,8],own_param:5,own_valu:5,p7m:2,paragraph:5,param:[0,4,5,8],paramet:9,parti:2,particular:0,pass:4,pdf:2,peppelinux:3,pip:3,preview:6,process:9,project:8,provid:[0,1],python:[3,9],raise_error:[7,8,9],rebuild:4,rel:0,remov:[2,4],remove_datafield:4,remove_filefield:4,render:4,repres:4,requir:[2,5],respect:4,retriev:4,save:[2,4,6],savedformcont:4,scratch:4,see:[3,5],select:6,selectbox:9,self:[4,5,9],set:[0,1,4],setup:2,sign:[2,3],signatur:1,signer:1,simpl:2,simpli:[0,4,8],singl:[2,4],some:5,someth:4,sourc:[4,5],special:2,specifi:9,step:4,storag:6,store:4,strictli:4,structur:[2,4],submit:4,system:3,tabl:4,take:8,than:5,them:[7,8],thi:[4,8,9],third:2,time:1,todo:2,total:6,trhee:9,two:9,type:[0,2],uniqu:4,universitadellacalabria:2,use:8,used:4,user:[0,9],uses:4,using:[0,2,4],valid:[1,2,4,8],valor:0,value1:0,value2:0,value3:0,value_1:4,value_2:4,verifi:[2,3],via:[0,1,2,6],view:4,want:[4,6],well:9,what:4,wil:4,without:2,work:9,you:[4,5,6,7,8],your:[2,6]},titles:["Add/Remove Formset dynamically with javascript","Upload P7M and signed PDF files","django-form-builder\u2019s documentation","Requirements and Setup","Configure your project to use dynamic forms","Create your DynamicFormClass and add static fields","Build dynamic forms","Create your own fields","Use single fields in your form","Fields methods and attributes"],titleterms:{"static":5,Use:8,add:[0,5],attribut:9,build:6,builder:2,configur:4,creat:[5,7],django:2,document:2,dynam:[0,4,6],dynamicformclass:5,field:[5,7,8,9],file:1,form:[2,4,6,8],formset:0,javascript:0,method:9,own:7,p7m:1,pdf:1,project:4,remov:0,requir:3,setup:3,sign:1,singl:8,upload:1,use:4,your:[4,5,7,8]}}) -------------------------------------------------------------------------------- /django_form_builder/tests/test_02_formset.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from django.test import TestCase 4 | 5 | from django_form_builder import dynamic_fields 6 | from django_form_builder.forms import BaseDynamicForm 7 | from django_form_builder.models import * 8 | from django_form_builder.utils import (_split_choices_in_list, 9 | _split_choices_in_list_canc, 10 | get_formset_dict, 11 | get_formset_list, 12 | get_formset_labeled_errors, 13 | get_labeled_errors) 14 | from django_form_builder.widgets import FormsetdWidget 15 | 16 | from . base import BaseTest 17 | 18 | 19 | logger = logging.getLogger('my_logger') 20 | 21 | class TestFormsets(BaseTest): 22 | 23 | def test_formset(self): 24 | """ 25 | Build a formset passing valid example data 26 | """ 27 | choices_string = "col1({'type':'CustomSelectBoxField', 'choices':'v1;v2;v3'})#"\ 28 | "co({'type':'BaseDateField'})#"\ 29 | "ccc" 30 | prefix = "prefix" 31 | data = { 32 | '{}-TOTAL_FORMS'.format(prefix): '1', 33 | '{}-INITIAL_FORMS'.format(prefix): '0', 34 | '{}-MAX_NUM_FORMS'.format(prefix): '', 35 | '{}-0-col1'.format(prefix): 'v1', 36 | '{}-0-co'.format(prefix): '1904-06-16', 37 | '{}-0-ccc'.format(prefix): 'Plain text', 38 | } 39 | 40 | choices = _split_choices_in_list_canc(choices_string) 41 | formset = dynamic_fields.build_formset(choices=choices, 42 | required=True, 43 | prefix=prefix, 44 | data=data) 45 | logger.info("Test form with formset") 46 | assert formset.is_valid() 47 | 48 | def test_formset_invalid(self): 49 | """ 50 | Build a formset passing invalid example data 51 | """ 52 | choices_string = "col1({'type':'CustomSelectBoxField', 'choices':'v1;v2;v3'})#"\ 53 | "co({'type':'BaseDateField'})#"\ 54 | "ccc" 55 | prefix = "prefix" 56 | data = { 57 | '{}-TOTAL_FORMS'.format(prefix): '1', 58 | '{}-INITIAL_FORMS'.format(prefix): '0', 59 | '{}-MAX_NUM_FORMS'.format(prefix): '', 60 | '{}-0-col1'.format(prefix): 'v1', 61 | '{}-0-co'.format(prefix): '1904-106-16', 62 | '{}-0-ccc'.format(prefix): 'Plain text', 63 | } 64 | 65 | choices = _split_choices_in_list_canc(choices_string) 66 | formset = dynamic_fields.build_formset(choices=choices, 67 | required=True, 68 | prefix=prefix, 69 | data=data) 70 | logger.info("Test form with formset (invalid)") 71 | logger.info(get_formset_labeled_errors(formset.errors)) 72 | self.assertFalse(formset.is_valid()) 73 | 74 | def test_split_choices_in_list(self): 75 | """ 76 | Test splitting choices string 77 | """ 78 | choices = 'v1;v2;v3' 79 | logger.info("Test _split_choices_in_list()") 80 | assert _split_choices_in_list(choices) 81 | 82 | def test_formset_list(self): 83 | """ 84 | Test get_formset_list() method 85 | """ 86 | prefix = "prefix" 87 | data = { 88 | '{}-TOTAL_FORMS'.format(prefix): '1', 89 | '{}-INITIAL_FORMS'.format(prefix): '0', 90 | '{}-MAX_NUM_FORMS'.format(prefix): '', 91 | '{}-0-col1'.format(prefix): 'v1', 92 | '{}-0-co'.format(prefix): '1904-106-16', 93 | '{}-0-ccc'.format(prefix): 'Plain text', 94 | } 95 | logger.info("Test get_formset_list()") 96 | assert get_formset_list(data) 97 | 98 | def test_formset_widget(self): 99 | """ 100 | Test FormsetdWidget 101 | """ 102 | choices_string = "col1({'type':'CustomSelectBoxField', 'choices':'v1;v2;v3'})#"\ 103 | "co({'type':'BaseDateField'})#"\ 104 | "ccc" 105 | prefix = "prefix" 106 | data = { 107 | '{}-TOTAL_FORMS'.format(prefix): '1', 108 | '{}-INITIAL_FORMS'.format(prefix): '0', 109 | '{}-MAX_NUM_FORMS'.format(prefix): '', 110 | '{}-0-col1'.format(prefix): 'v1', 111 | '{}-0-co'.format(prefix): '1904-106-16', 112 | '{}-0-ccc'.format(prefix): 'Plain text', 113 | } 114 | 115 | formset_field = self.create_field('CustomComplexTableField')[0] 116 | choices = _split_choices_in_list_canc(choices_string) 117 | formset_field.widget = FormsetdWidget(field_required=True, 118 | prefix=prefix, 119 | data=data, 120 | files={}, 121 | choices=choices) 122 | 123 | logger.info("Test form with formset widget (FormsetdWidget)") 124 | logger.info(get_formset_labeled_errors(formset_field.widget.formset.errors)) 125 | assert formset_field.widget.get_js_template() 126 | assert formset_field.widget.make_readonly() 127 | -------------------------------------------------------------------------------- /docs/source/usage/dynamic-forms/configuration.rst: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Configure your project to use dynamic forms 7 | =========================================== 8 | 9 | - **Step 1** 10 | 11 | Every Dynamic Form needs a table to store the list of fields that compose it. 12 | 13 | Also, it has to be strictly linked to a project model entity to be rendered 14 | (e.g. what kind of object wil the form map? A Book, a Car or something else!?). 15 | 16 | In your project's models, then, create a Model Class to store the list of fields, 17 | make it inherit class ``DynamicFieldMap`` and choose the ForeignKey that represents the 18 | form linked model entity. 19 | 20 | .. code-block:: python 21 | 22 | from django_form_builder.dynamic_fields import get_fields_types 23 | from django_form_builder.models import DynamicFieldMap 24 | 25 | class MyFieldsListModel(DynamicFieldMap): 26 | """ 27 | This class represents every single form field, each one linked to a unique object 28 | """ 29 | 30 | # if you want to integrate dynamic fields with your own, 31 | # define a new file that import all 'dynamic_fields' and defines others new and 32 | # then pass it as param to get_fields_types(class_name=my_custom_fields_file) 33 | 34 | my_entity = models.ForeignKey(MyEntityClass, on_delete=models.CASCADE) 35 | DynamicFieldMap._meta.get_field('field_type').choices = get_fields_types() 36 | 37 | - **Step 2** 38 | 39 | Every submitted *dynamic form*, if valid, save its content as a JSON. 40 | Once we have our fields model (step 1), we have to define a Model Class to save our compiled form JSON attribute. 41 | 42 | .. code-block:: python 43 | 44 | from django_form_builder.models import SavedFormContent 45 | 46 | class MyModelClass(SavedFormContent): 47 | """ 48 | This class contains the JSON with all submitted form details 49 | """ 50 | ... 51 | 52 | - **Step 3** 53 | 54 | In your views, use/override ``get_form()`` and ``compiled_form()`` methods to respectively build form structure from scratch (using your *step 1* model class) 55 | and rebuild and fill it simply by the JSON field. 56 | 57 | .. code-block:: python 58 | 59 | from django_form_builder.models import DynamicFieldMap 60 | 61 | ... 62 | 63 | # the class used as foreign key in 'Step 1' 64 | class MyEntityClass(models.Model): 65 | 66 | ... 67 | 68 | def get_form(self, 69 | data=None, 70 | files=None, 71 | remove_filefields=False, 72 | remove_datafields=False, 73 | **kwargs): 74 | """ 75 | Returns the form (empty if data=None) 76 | if remove_filefields is not False, remove from form the passed FileFields 77 | if remove_datafields is True, remove all fields different from FileFields 78 | """ 79 | # retrieve all the fields (the model class is in 'Step 1') 80 | form_fields_from_model = self.myfieldslistmodel.all().order_by('ordinamento') 81 | if not form_fields_from_model: return None 82 | # Static method of DynamicFieldMap that build the constructor dictionary 83 | constructor_dict = DynamicFieldMap.build_constructor_dict(form_fields_from_model) 84 | 85 | # more params to pass with 'data' 86 | custom_params = {'extra_1': value_1, 87 | 'extra_2': value_2} 88 | # the form retrieved by calling get_form() static method 89 | form = DynamicFieldMap.get_form(# define it only if you 90 | # need your custom form: 91 | # class_obj=MyDynamicForm, 92 | constructor_dict=constructor_dict, 93 | custom_params=custom_params, 94 | data=data, 95 | files=files, 96 | remove_filefields=remove_filefields, 97 | remove_datafields=remove_datafields) 98 | 99 | return form 100 | 101 | .. code-block:: python 102 | 103 | from django_form_builder.models import SavedFormContent 104 | 105 | ... 106 | 107 | # the class used in 'Step 2' 108 | class MyModelClass(SavedFormContent): 109 | 110 | ... 111 | 112 | def compiled_form(self, files=None, remove_filefields=True): 113 | """ 114 | Returns the builded and filled form 115 | Integrates django_form_builder.models.SavedFormContent.compiled_form 116 | SavedFormContent.compiled_form uses DynamicFieldMap.get_form() filled 117 | """ 118 | # set get_form() source class (step 1) 119 | form_source = self.my_entity 120 | # set data source class (inherited from 'SavedFormContent') 121 | data_source = self.modulo_compilato 122 | 123 | form = SavedFormContent.compiled_form(data_source=data_source, 124 | files=files, 125 | remove_filefields=remove_filefields, 126 | form_source=form_source, 127 | **other_extra_params) 128 | 129 | return form 130 | -------------------------------------------------------------------------------- /docs/build/html/_sources/usage/dynamic-forms/configuration.rst.txt: -------------------------------------------------------------------------------- 1 | .. django-form-builder documentation master file, created by 2 | sphinx-quickstart on Tue Jul 2 08:50:49 2019. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Configure your project to use dynamic forms 7 | =========================================== 8 | 9 | - **Step 1** 10 | 11 | Every Dynamic Form needs a table to store the list of fields that compose it. 12 | 13 | Also, it has to be strictly linked to a project model entity to be rendered 14 | (e.g. what kind of object wil the form map? A Book, a Car or something else!?). 15 | 16 | In your project's models, then, create a Model Class to store the list of fields, 17 | make it inherit class ``DynamicFieldMap`` and choose the ForeignKey that represents the 18 | form linked model entity. 19 | 20 | .. code-block:: python 21 | 22 | from django_form_builder.dynamic_fields import get_fields_types 23 | from django_form_builder.models import DynamicFieldMap 24 | 25 | class MyFieldsListModel(DynamicFieldMap): 26 | """ 27 | This class represents every single form field, each one linked to a unique object 28 | """ 29 | 30 | # if you want to integrate dynamic fields with your own, 31 | # define a new file that import all 'dynamic_fields' and defines others new and 32 | # then pass it as param to get_fields_types(class_name=my_custom_fields_file) 33 | 34 | my_entity = models.ForeignKey(MyEntityClass, on_delete=models.CASCADE) 35 | DynamicFieldMap._meta.get_field('field_type').choices = get_fields_types() 36 | 37 | - **Step 2** 38 | 39 | Every submitted *dynamic form*, if valid, save its content as a JSON. 40 | Once we have our fields model (step 1), we have to define a Model Class to save our compiled form JSON attribute. 41 | 42 | .. code-block:: python 43 | 44 | from django_form_builder.models import SavedFormContent 45 | 46 | class MyModelClass(SavedFormContent): 47 | """ 48 | This class contains the JSON with all submitted form details 49 | """ 50 | ... 51 | 52 | - **Step 3** 53 | 54 | In your views, use/override ``get_form()`` and ``compiled_form()`` methods to respectively build form structure from scratch (using your *step 1* model class) 55 | and rebuild and fill it simply by the JSON field. 56 | 57 | .. code-block:: python 58 | 59 | from django_form_builder.models import DynamicFieldMap 60 | 61 | ... 62 | 63 | # the class used as foreign key in 'Step 1' 64 | class MyEntityClass(models.Model): 65 | 66 | ... 67 | 68 | def get_form(self, 69 | data=None, 70 | files=None, 71 | remove_filefields=False, 72 | remove_datafields=False, 73 | **kwargs): 74 | """ 75 | Returns the form (empty if data=None) 76 | if remove_filefields is not False, remove from form the passed FileFields 77 | if remove_datafields is True, remove all fields different from FileFields 78 | """ 79 | # retrieve all the fields (the model class is in 'Step 1') 80 | form_fields_from_model = self.myfieldslistmodel.all().order_by('ordinamento') 81 | if not form_fields_from_model: return None 82 | # Static method of DynamicFieldMap that build the constructor dictionary 83 | constructor_dict = DynamicFieldMap.build_constructor_dict(form_fields_from_model) 84 | 85 | # more params to pass with 'data' 86 | custom_params = {'extra_1': value_1, 87 | 'extra_2': value_2} 88 | # the form retrieved by calling get_form() static method 89 | form = DynamicFieldMap.get_form(# define it only if you 90 | # need your custom form: 91 | # class_obj=MyDynamicForm, 92 | constructor_dict=constructor_dict, 93 | custom_params=custom_params, 94 | data=data, 95 | files=files, 96 | remove_filefields=remove_filefields, 97 | remove_datafields=remove_datafields) 98 | 99 | return form 100 | 101 | .. code-block:: python 102 | 103 | from django_form_builder.models import SavedFormContent 104 | 105 | ... 106 | 107 | # the class used in 'Step 2' 108 | class MyModelClass(SavedFormContent): 109 | 110 | ... 111 | 112 | def compiled_form(self, files=None, remove_filefields=True): 113 | """ 114 | Returns the builded and filled form 115 | Integrates django_form_builder.models.SavedFormContent.compiled_form 116 | SavedFormContent.compiled_form uses DynamicFieldMap.get_form() filled 117 | """ 118 | # set get_form() source class (step 1) 119 | form_source = self.my_entity 120 | # set data source class (inherited from 'SavedFormContent') 121 | data_source = self.modulo_compilato 122 | 123 | form = SavedFormContent.compiled_form(data_source=data_source, 124 | files=files, 125 | remove_filefields=remove_filefields, 126 | form_source=form_source, 127 | **other_extra_params) 128 | 129 | return form 130 | --------------------------------------------------------------------------------