Form library with advanced features like nested forms
Project description
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.
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
Community and links
2.0.6 (2018-08-29)
Drop Python 3.3 support. See https://github.com/Pylons/deform/pull/371
Add support to Python 3.7.
2.0.5 (2018-02-20)
i18n cleanup https://github.com/Pylons/deform/pull/332 and https://github.com/Pylons/deform/pull/363
Fix bug in _FieldStorage under Python 3.x (issues #339 and #357).
Declare Python 3.6 compatibility and enable tests against Python 3.6 (all tests pass with no changes).
Closes #333: MANIFEST.in including docs, licenses and text files.
Add link button type See https://github.com/Pylons/deform/issues/166
Add traditional chinese localization
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)
Added accordions to MappingWidget: http://deformdemo.repoze.org/mapping_accordion/
Added CSS class deform-form-buttons to style form button group: https://github.com/Pylons/deform/pull/308
Add more options to TextAreaCSVWidget: https://github.com/Pylons/deform/pull/309
Always render an item with a default CSS class: https://github.com/Pylons/deform/pull/306
Updated pickdate.js library used for the date picker: https://github.com/Pylons/deform/pull/248
Widget Selenium test suite runs both under Python 2 and 3. Lots of Selenium testing headache fixed with some implicit wait support.
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)
Updated bootstrap to 3.3.6.
Fix dateparts.pt and datetimeinput.pt for changes in bootstrap v3.0.3. (The culprit is boostrap commit 853b69f.)
Make dateinput work again by using the fixed name “date” as expected by the pstruct schema. See https://github.com/Pylons/deform/pull/221.
Changed ISO8601_REGEX import to match change in colander
Add support for Python 3.4, PyPy3.
Raise Invalid rather than other errors when deserializing broken or malicious pstructs with invalid types. See https://github.com/Pylons/deform/pull/203
Read a time widget.
Fix a bug in the DateInputWidget. See https://github.com/Pylons/deform/pull/192.
Ensured that None would not show up as a css class name in rendered template output. See https://github.com/Pylons/deform/pull/191
we now use dashed-names (e.g. deform-seq). A full list of changes is below:
Old New deformClosebutton deform-closebutton deformFileupload deform-file-upload deformFormFieldset deform-form-fieldset deformInsertBefore deform-insert-before deformOrderbutton deform-orderbutton deformProto deform-proto deformReplaces deform-replaces deformSeq deform-seq deformSeqAdd deform-seq-add deformSeqContainer deform-seq-container deformSeqItem deform-seq-item deformSet-item deform-set-item errorMsg error-msg errorMsgLbl error-msg-lbl
Fixed handling of buttons in nested sequences. See https://github.com/Pylons/deform/issues/197
Upload widget is themed like Bootstrap https://github.com/Pylons/deform/pull/280
Select widget handles the mixture of strings and ints https://github.com/Pylons/deform/pull/300/ and https://github.com/Pylons/deform/pull/299
Have the button css_class override the default button class. This is backwards-incompatible and will require users of css_class to add a btn-default/btn-primary class to the css_class.
Simplified Chinese translation https://github.com/Pylons/deform/pull/274
Don’t cause unnecessary JavaScript calls on page load https://github.com/Pylons/deform/pull/267/
Allow override Button Bootstap CSS styles https://github.com/Pylons/deform/pull/251
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 http://deform2demo.repoze.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 http://deform2demo.repoze.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
structural widget (mapping_item.pt) - do we need that or not or what? + add a demo
prepend/append t.bootstrap stuff
https://github.com/Pylons/deform/pull/116#issuecomment-23210460
group demos by widget type
handle ajax demo more UX friendly
Put drag handles in panel headers: https://github.com/Pylons/deform/issues/180
NEW FEATURES:
input_prepend/input_append in mapping_item widget.
field.parent
field.get_root
inline attr of checkboxchoice and radiochoice widgets (see https://github.com/Pylons/deform/pull/182)
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.