A Python HTML form library.
JavaScript Python CSS Shell
Latest commit b127c96 Dec 18, 2016 @miohtama miohtama committed on GitHub Merge pull request #327 from liangent/master
Fix mismatching imports in docs/common_needs.rst
Failed to load latest commit information.
deform Revert "Merge pull request #233 from tisdall/structural_sequence" Dec 16, 2016
docs Fix mismatching imports in docs/common_needs.rst Dec 18, 2016
.bzrignore Commit forgotten .bzrignore. Apr 10, 2010
.coveragerc Don't do branch coverage, because we can get only 99% on some files Oct 22, 2016
.gitignore Let's try to use checkout for different folder for deformdemo and hop… Jun 5, 2016
.hgignore Merge Blaise's css_class patches from https://bitbucket.org/blaf/deform: Aug 21, 2010
.travis.yml Python 3 testing. Nov 19, 2016
CHANGES.txt Back to development: 2.0.4 Nov 19, 2016
CONTRIBUTING.rst Make it flaky Nov 19, 2016
CONTRIBUTORS.txt Merge PR 309 Nov 19, 2016
COPYRIGHT.txt - Moved to GitHub (https://github.com/Pylons/deform). Feb 16, 2011
HISTORY.txt fix typos Jan 15, 2015
LICENSE.txt Start jamming templates in. Mar 21, 2010
MANIFEST.in Fix typo in manifest Oct 22, 2016
README.rst Add users list Oct 25, 2016
RELEASING.txt Update release emmail Dec 16, 2016
RESEARCH.txt Start jamming templates in. Mar 21, 2010
TODO.txt garden Sep 5, 2010
i18n.sh Cleaning up contrib process. Jun 5, 2016
lingua.ini Cleaning up contrib process. Jun 5, 2016
messages.pot Python 3 testing. Nov 19, 2016
rtd.txt - fix rtd build Feb 19, 2016
run-selenium-tests.bash Pass command line arguments through tox to selenium script to nosetest Oct 22, 2016
setup.cfg - FileUploadWidget now sanitizes IE/Windows whole-path filenames before Apr 23, 2012
setup.py Back to development: 2.0.4 Nov 19, 2016
tox.ini Re-enable pypy3. Dec 16, 2016



https://travis-ci.org/Pylons/deform.png?branch=master Master Documentation Status Latest Documentation Status


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


Install using pip and Python package installation best practices:

pip install deform


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


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(

    age = colander.SchemaNode(
        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:

                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()
        # 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.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


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

Projects using Deform

Community and links