Skip to main content

Form library with advanced features like nested forms

Project description

Build Status Current Release Latest Documentation Status Python Support

Introduction

Deform is a Python form library for generating HTML forms on the server side. Date and time picking widgets, rich text editors, forms with dynamically added and removed items and a few other complex use cases are supported out of the box.

Deform integrates with the Pyramid web framework and several other web frameworks. Deform comes with Chameleon templates and Bootstrap 3 styling. Under the hood, Colander schemas are used for serialization and validation. The Peppercorn library maps HTTP form submissions to nested structure.

Although Deform uses Chameleon templates internally, you can embed rendered Deform forms into any template language.

Use cases

Deform is ideal for complex server-side generated forms. Potential use cases include:

  • Complex data entry forms

  • Administrative interfaces

  • Python based websites with high amount of data manipulation forms

  • Websites where additional front end framework is not needed

Installation

Install using pip and Python package installation best practices:

pip install deform

Example

See all widget examples. Below is a sample form loop using the Pyramid web framework.

https://github.com/Pylons/deform/raw/master/docs/example.png

Example code:

"""Self-contained Deform demo example."""
from __future__ import print_function

from pyramid.config import Configurator
from pyramid.session import UnencryptedCookieSessionFactoryConfig
from pyramid.httpexceptions import HTTPFound

import colander
import deform


class ExampleSchema(deform.schema.CSRFSchema):

    name = colander.SchemaNode(
        colander.String(),
        title="Name")

    age = colander.SchemaNode(
        colander.Int(),
        default=18,
        title="Age",
        description="Your age in years")


def mini_example(request):
    """Sample Deform form with validation."""

    schema = ExampleSchema().bind(request=request)

    # Create a styled button with some extra Bootstrap 3 CSS classes
    process_btn = deform.form.Button(name='process', title="Process")
    form = deform.form.Form(schema, buttons=(process_btn,))

    # User submitted this form
    if request.method == "POST":
        if 'process' in request.POST:

            try:
                appstruct = form.validate(request.POST.items())

                # Save form data from appstruct
                print("Your name:", appstruct["name"])
                print("Your age:", appstruct["age"])

                # Thank user and take him/her to the next page
                request.session.flash('Thank you for the submission.')

                # Redirect to the page shows after succesful form submission
                return HTTPFound("/")

            except deform.exception.ValidationFailure as e:
                # Render a form version where errors are visible next to the fields,
                # and the submitted values are posted back
                rendered_form = e.render()
    else:
        # Render a form with initial default values
        rendered_form = form.render()

    return {
        # This is just rendered HTML in a string
        # and can be embedded in any template language
        "rendered_form": rendered_form,
    }


def main(global_config, **settings):
    """pserve entry point"""
    session_factory = UnencryptedCookieSessionFactoryConfig('seekrit!')
    config = Configurator(settings=settings, session_factory=session_factory)
    config.include('pyramid_chameleon')
    deform.renderer.configure_zpt_renderer()
    config.add_static_view('static_deform', 'deform:static')
    config.add_route('mini_example', path='/')
    config.add_view(mini_example, route_name="mini_example", renderer="templates/mini.pt")
    return config.make_wsgi_app()

This example is in deformdemo repository. Run the example with pserve:

pserve mini.ini --reload

Status

This library is actively developed and maintained. Deform 2.x branch has been used in production on several sites since 2014. Automatic test suite has 100% Python code coverage and 500+ tests.

Projects using Deform

2.0.15 (2020-12-10)

Features and Fixes

  • Add support of Python 3.8 and 3.9.

  • Added a new widget SelectizeWidget based on the jQuery plugin selectize.js. [stevepiercy] https://github.com/Pylons/deform/issues/260

  • Improved handling of the readonly HTML attribute in certain widgets. The readonly HTML form control attribute makes the element not mutable, meaning the user cannot edit the control. When "readonly": "readonly" is one of the items in a dict passed into the attributes option when creating a widget, the rendered widget both prevents the user from changing the value, and if the form does not pass validation after submitted then the field value will be displayed.

    readonly is supported by most form controls, but not all. Deform adds some logic to add read-only support for a few of those form controls, as described below.

    CheckboxWidget and CheckboxChoiceWidget

    Due to the nature of how checkbox values are processed, the readonly attribute has no effect. To achieve a read-only behavior, pass in attributes={"onclick": "return false;"}. This will render as an inline JavaScript onclick="return false;" for each checkbox item.

    MoneyInputWidget

    The provided value will be displayed in the input and be not editable.

    RadioChoiceWidget

    For the selected value it will render an attribute in the HTML as readonly="readonly", and for all other values as disabled="disabled".

    SelectWidget

    For selection of single options only, the selected value will render an attribute in the HTML as readonly="readonly", and for all other values as disabled="disabled". Multiple selections, set by the multiple=True option, do not support the readonly attribute on the <select> element. For multiple selections, use the SelectizeWidget.

    SelectizeWidget

    For both single and multiple selections, the selected value or values will be rendered as selected, and the others will not be selectable. Selectize uses JavaScript to “lock” the form control.

    TextAreaWidget

    The provided value will be displayed in the input and be not editable.

    TextInputWidget

    The provided value will be displayed in the input and be not editable.

    [stevepiercy] https://github.com/Pylons/deform/issues/260

  • Optionally bypass the resource registry and specify a resource as a dict where its keys are the type of asset ("js" or "css") and its values are either a string or a list of strings of paths to assets on disk. [tdamsma] https://github.com/Pylons/deform/issues/485

  • Conditionally load jquery.maskedinput if and only if mask option is provided. [tisdall, stevepiercy] https://github.com/Pylons/deform/pull/487

  • Changed dateparts widget to use type="number" instead of default text. [stevepiercy] https://github.com/Pylons/deform/issues/442

  • Clarify that a sequence type (list, tuple, or x/range) is required for values passed into a SelectWidget or RadioChoiceWidget. [stevepiercy] https://github.com/Pylons/deform/issues/385

  • Switch from using nosetests to pytest as the test runner, as nosetests is no longer maintained. [stevepiercy] https://github.com/Pylons/deform/pull/497 https://github.com/Pylons/deform/pull/498

  • Switch from Travis-CI and Appveyor to GitHub Actions, due to Travis-CI changing its plans to be ineffective for the Pylons Project. [stevepiercy] https://github.com/Pylons/deform/pull/492 https://github.com/Pylons/deform/pull/495

  • Add Docker containerization of Deform and deformdemo as an option for running tests, and improve related documentation. [sydoluciani] https://github.com/Pylons/deform/pull/493 https://github.com/Pylons/deform/pull/494

Deprecations

  • Drop support of Python 3.5.

  • Select2Widget is now deprecated and will be removed in Deform 3.0.0 because its jQuery plugin Select2 removed a lock feature in v4.0.0 and its future development is uncertain. [stevepiercy] https://github.com/Pylons/deform/issues/260

Documentation

2.0.14 (2020-08-26)

2.0.13 (2020-08-25)

  • richtext.pt: The contents of the RichTextWidget’s <textarea> was not HTML-escaped, but now it is.

    Note that unescaped content is still rendered if delayed_load is enabled. Now, however, to avoid rendering unescaped non-validated user input, delayed_load is ignored when redisplaying a field containing an error. See https://github.com/Pylons/deform/pull/204

  • This time, really update select2 widget to version 4.0.13. See https://github.com/Pylons/deform/pull/459

2.0.12 (2020-08-23)

2.0.11 (2020-08-21)

  • Drop support of Python 3.4.

  • Changed the implementation of input autofocus from JavaScript to an HTML5 input attribute.

    Forms now have an optional focus parameter (on or off) and fields have an optional autofocus parameter.

    • If focus is on, and at least one field has an autofocus schema parameter set to on, the first of these fields will receive focus on page load.

    • If focus is on or omitted, and no field has an autofocus schema parameter set to on, the first input of the first form on the page will receive focus on page load.

    • If focus is off, no focusing will be done.

    Default: on. (This is unchanged from the JavaScript implementation.)

    See https://github.com/Pylons/deform/pull/365/

  • Replace the flake8-isort plugin with plain old isort. See https://github.com/Pylons/deform/pull/427

  • Improved the script that launches Selenium webdriver to clean up the locale directory after completing a run of functional tests so that its files do not get committed by accident. We also enforce coding style and add a formatter, and improved the contributing documentation. See https://github.com/Pylons/deform/pull/428

  • Updated Bootstrap to 3.4.1.

2.0.10 (2020-07-03)

  • Correct release date.

2.0.9 (2020-07-03)

2.0.8 (2019-10-07)

2.0.7 (2018-11-14)

2.0.6 (2018-08-29)

2.0.5 (2018-02-20)

2.0.4 (2017-02-11)

  • Added ability to pass a translator function to deform.renderer.configure_zpt_renderer

2.0.3 (2016-11-19)

2.0.2 (2016-11-14)

  • Fix regression of <select> widget default values not honoured

  • Updated Select2 widget JavaScript

2.0.1 (2016-10-25)

  • Drop support for Python 2.6.

  • Documentation reorganization and clean up to conform with Pylons Project projects.

  • Fix select and select2 widget templates failing on Python 3.x

2.0 (2016-10-23)

  • Release polish

2.0b3 (2016-10-22)

  • Update demos and add standalone mini example

2.0b2 (2016-10-22)

  • Fix README on PyPI

2.0b1 (2016-10-22)

2.0a2 (2013-10-18)

  • PasswordWidget and CheckedPasswordWidget have grown an additional argument/attribute named redisplay, which controls what happens on a validation failure of a form involving such a field. If redisplay is True (the default), the password will be re-rendered into the form when the form is re-rendered after validation failure. If redisplay is False, the password will not be re-rendered into the form. The default is False, which means that, as of this release, passwords will not be redisplayed; this changes the default behavior wrt previous releases. Values typed into password fields are not redisplayed by default during validation failure, as a security measure (the value winds up in browser history). Use PasswordWidget(redisplay=True) or CheckedPasswordWidget(redisplay=True) to make these widgets redisplay passwords on validation failures, matching the old behavior.

  • When using the default Chameleon template renderer, template names can now be “asset specifications” e.g. mypackage:subdir1/subdir2/mytemplate.pt instead of extensionless paths relative to a search path. When template names are specified as asset specifications, the pkg_resources.resource_filename API is used to dereference them into an actual file path.

2.0a1 (2013-10-05)

This is an alpha release of Deform v2. Deform v2 is backwards incompatible with Deform v1. It requires the use of Twitter Bootstrap v3, whereas deform v1 did not require Bootstrap.

A demonstration site that shows Deform 2 in action exists at https://deformdemo.pylonsproject.org.

Both Deform 1 and Deform 2 will be maintained going forward. If you wish to continue using Deform 1, because you cannot upgrade, or cannot depend on Bootstrap 3, please pin your deform distribution requirement to something below 2.0a1, e.g. deform<=1.999.

This first alpha release is missing formal documentation updates. Apologies, we needed to get a release out onto PyPI, as not having one is holding back the development of a number of platforms and applications that depend on the changes in v2+. Documentation updates will be forthcoming over the lifetime of future alpha/beta releases. However, below is a list of known issues that need to be addressed to make a final release of Deform 2, as well as information about new features, and migration notes. You may also be able to make use of the demo site at https://deformdemo.pylonsproject.org to divine how things have changed, and what CSS and JavaScript resources you’ll need to include in your pages to make use of this release.

TODO

  • docs

  • decide how to explain form.css (include in requirements or?)

  • horizontal/inline forms + structural things

  • assets for templates: deform should provide a tool to resolve that?

  • placeholder support for all textual inputs (and required/maxlength see also https://github.com/Pylons/deform/pull/116)

  • display help-blocks for readonly fields?

  • maybe readonly should be a property of the schema, not the widget.

  • consider whether “style”/”css_class” on multi-input widgets should apply to a container or each element.

  • audit use of e.g. string:${css_class} so we don’t see unexpected class=”None” in widget rendering output.

  • some sort of test for mapping_item input_prepend/input_append

  • Currently description shows up as both tooltip of label and as help-block. Maybe make these two things separate or at least don’t show them both using the same value.

  • normalize CSS class names to deform-foo rather than deformFoo

  • sequence_of_sequences: js that processes close/order buttons has to be less promiscuous (it uses e.g. “find”); symptom: buttons appear/disappear, act on the wrong element, etc… ugh 2013/10/05 cannot replicate, but still believe there may be an issue, but maybe iElectric fixed it

NICE TO HAVE

NEW FEATURES:

MIGRATION NOTES:

  • removed deprecated height, width, skin, theme parameters from RichTextWidget (use “options” instead)

  • removed deprecated render_initial_item from SequenceWidget

  • removed deprecated deform.Set (use colander.Set instead)

  • DateInputWidget renamed parameter dateFormat to format (dateFormat now unsupported).

  • DateTimeInputWidget now renders as two fields: one for a date and one for a time, using pickadate.

  • We no longer bother trying to use the native datetimeinput widget on any browser, because the support is so spotty.

  • DateTimeInputWidget takes two options now: date_options and time_options instead of a single options dictionary. The options are pickadate date/time options respectively.

  • It is no longer possible to do DateTimeWidget().options[‘a’] = ‘foo’ or DateTimeWidget().date_options[‘a’] = ‘foo’. If you need to change options imperatively, set the entire .options/.date_options dictionary.

  • merged TypeaheadInputWidget to AutocompleteInputWidget (removed delay parameter)

  • AutocompleteInputWidget now accepts string type for “values”

  • widgets no longer accepts “size” (instead use style=”width: x”), except SelectWidget (it means the size of the dropdown)

  • get_widget_resources now returns asset specifications rather than deform-static-relative paths

  • deform 2.0 requires users to manually load TB 3.0 and jquery 2.0

  • required labels no longer insert an asterisk inside a <span class=”req”> inside themselves. instead the label element has a required class if the field is required; use form.css to display this as an asterisk.

  • min_length of AutocompleteInputWidget now defaults to 1 (was 2)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deform-2.0.15.tar.gz (869.5 kB view details)

Uploaded Source

Built Distribution

deform-2.0.15-py3-none-any.whl (893.5 kB view details)

Uploaded Python 3

File details

Details for the file deform-2.0.15.tar.gz.

File metadata

  • Download URL: deform-2.0.15.tar.gz
  • Upload date:
  • Size: 869.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.3

File hashes

Hashes for deform-2.0.15.tar.gz
Algorithm Hash digest
SHA256 1e912937650c1dbb830079dd9c039950762a230223a567740fbf1b23f1090367
MD5 787a8ec7694b8f915b679a224229e2ee
BLAKE2b-256 d57dc83746cf2209900fc2b688ff084b9f131cb7e5b4b8b57a0fd74f7237d0ee

See more details on using hashes here.

File details

Details for the file deform-2.0.15-py3-none-any.whl.

File metadata

  • Download URL: deform-2.0.15-py3-none-any.whl
  • Upload date:
  • Size: 893.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.25.0 setuptools/50.3.2 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.7.3

File hashes

Hashes for deform-2.0.15-py3-none-any.whl
Algorithm Hash digest
SHA256 2320de140a0003e53138cea394f0196bcc72cf18607a6a6a1bcef7c38b39ff35
MD5 44bfa918c9c7a067e3bd338b8139c7fa
BLAKE2b-256 6888f863123d5dd36dfcb6d6d116ea759a275c05e3e8a348f10814bdad2df7f7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page