A Python HTML form library.
Clone or download
Latest commit 010cb72 Nov 14, 2018
Failed to load latest commit information.
deform Fix linting Nov 12, 2018
docs Drop html_smartypants; run linkcheck and fix broken links May 31, 2018
.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
.flake8 Apply black to the codebase (#381) Nov 12, 2018
.gitignore Add .python-version to .gitignore Aug 30, 2018
.hgignore Merge Blaise's css_class patches from https://bitbucket.org/blaf/deform: Aug 21, 2010
.isort.cfg Apply black to the codebase (#381) Nov 12, 2018
.travis.yml Apply black to the codebase (#381) Nov 12, 2018
CHANGES.txt Back to development: 2.0.8 Nov 14, 2018
CONTRIBUTING.rst further improvements for running functional tests Mar 23, 2018
CONTRIBUTORS.txt Add `tags` option support to `Select2Widget` #372 (#373) Nov 12, 2018
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 Apply black to the codebase (#381) Nov 12, 2018
README.rst Update links May 31, 2018
RELEASING.txt Update release emmail Dec 16, 2016
RESEARCH.txt Start jamming templates in. Mar 21, 2010
TODO.txt garden Sep 5, 2010
contributing.md Create contributing.md Mar 9, 2017
i18n.sh minor i18n.sh improvement Feb 8, 2017
lingua.ini Cleaning up contrib process. Jun 5, 2016
pyproject.toml Apply black to the codebase (#381) Nov 12, 2018
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 Apply black to the codebase (#381) Nov 12, 2018
setup.py Apply black to setup.py Nov 14, 2018
tox.ini Apply black to the codebase (#381) Nov 12, 2018



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 since 2014. Automatic test suite has 100% Python code coverage and 500+ tests.

Projects using Deform

Community and links