Skip to content

Pylons/deform

Repository files navigation

Deform

Build Status Current Release Main Documentation Status Latest Documentation Status

Python Support

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 5 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.

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.

https://github.com/Pylons/deform/raw/main/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

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.