simplecodes-wtforms-b83e12f59ac1/.hg_archival.txt0000644000000000000000000000017111723462231020113 0ustar 00000000000000repo: 8797aae3dd3b32825d16f06146cc18d8e14b5f54 node: b83e12f59ac1be690533141025d17f7cd0bc1467 branch: default tag: 1.0.1 simplecodes-wtforms-b83e12f59ac1/.hgignore0000644000000000000000000000027411723462231016634 0ustar 00000000000000syntax: regexp \.py[co]$ \.py,cover$ \..*\.swp$ \.eprj$ \.coverage$ \.DS_Store$ ^build/ ^docs/_build ^docs/html ^dist/ ^MANIFEST$ ^WTForms\.egg-info wtforms/ext/i18n/.*\.mo$ simplecodes-wtforms-b83e12f59ac1/.hgtags0000644000000000000000000000076711723462231016316 0ustar 00000000000000f4343b732b213c1e719e18a4906bd53c007382ba 0.1 f0a603646b048056114ee82ecebac1a003b37fb8 0.2 b8a23af99f8e2ef7b82e27949f236ce9df6b1217 0.3 e97f651eb02e8bb7667abe337ca9c3d4eea308cf 0.3.1 e8936b958da03582dce83ad5574512909ee2446e 0.4 97d88af6bca0409b9cfde5b206f22209aaf9ec8c 0.5 9c6469d4b06bf2fac94ca687523fae389378a446 0.6 eab645ef8ca1dee6fd39ea28f93a1a37a4cb2347 0.6.1 8e5a93665d108cc8977936e6ab54706ebc05587a 0.6.2 6a6954927a13911fae6941fd0aac13b8d6372a42 0.6.3 643ce2169fb4359f8b541102e7db22fed4871215 1.0 simplecodes-wtforms-b83e12f59ac1/AUTHORS.txt0000644000000000000000000000052311723462231016714 0ustar 00000000000000WTForms is written and maintained by the WTForms Team and various contributors. Lead Developers: - Thomas Johansson - James Crasta Contributors: - Adam Lowry - Ali Aafshar - Andreas Madsack - Christopher Grebs - Eduardo Schettino - Emil Vladev - Rodrigo Moraes - Sebastian Wiesner - Vinay Sajip simplecodes-wtforms-b83e12f59ac1/CHANGES.txt0000644000000000000000000002002111723462231016632 0ustar 00000000000000WTForms Changelog ================= Version 1.0.1 ------------- Released February 29, 2012 - Fixed issues related to building for python 3 and python pre-releases. - Add object_data to fields to get at the originally passed data. Version 1.0 ----------- Released February 28, 2012 - Output HTML5 compact syntax by default. - Substantial code reorg, cleanup, and test improvements - Added ext.csrf for a way to implement CSRF protection - ext.sqlalchemy: * Support PGInet, MACADDR, and UUID field conversion * Support callable defaults - ext.appengine: * model_form now supports generating forms with the same ordering as model. * ReferencePropertyField now gets get_label like the other ORM fields - Add localization support for WTForms built-in messages - Python 3 support (via 2to3) - Minor changes/fixes: * An empty label string can be specified on fields if desired * Option widget can now take kwargs customization * Field subclasses can provide default validators as a class property * DateTimeField can take time in microseconds * Numeric fields all set .data to None on coercion error for consistency. Version 0.6.3 ------------- Released April 24, 2011 - Documentation: Substantial documentation improvements, including adding Crash Course as a sphinx document. - ext.django: QuerySetSelectField (and ModelSelectField) now accept get_label similar to sqlalchemy equivalents. - ext.appengine: * model_form fixes: FloatField(#50), TimeField, DateTimeField(#55) * ReferencePropertyField: now properly stores model object, not key. (#48) Version 0.6.2 ------------- Released January 22, 2011 - Bug Fixes: * ext.appengine: various field fixes (#34, #48), model_form changes (#41) * Fix issue in Optional with non-string input. * Make numeric fields more consistent. - Tests: Improve test coverage substantially. Version 0.6.1 ------------- Released September 17th, 2010 - Bug Fixes: * ext.appengine ReferencePropertyField (#36, #37) * dateutil fields: render issue (r419), and consistency issue (#35) * Optional validator failed when raw_data was absent (r418) - Documentation: docs now mention HTML escaping functionality (#38) - Add preliminary support for providing a translations object that can translate built-in validation and coercion errors (#32) Version 0.6 ----------- Released April 25th, 2010. - Widgets: * HTML is now marked as safe (using __html__) so that compatible templating engines will not auto-escape it. - Fields: * Field._default is now Field.default. * All fields now have a `raw_data` property. * Fields which are select fields (including those in .ext) can be iterated to produce options, and have an option_widget kwarg. * Minor bugfixes and cleanup in FieldList, Select(Multiple)Field, QuerySelectField to address behavioral consistency. * Added FloatField, based on IntegerField. - Extensions: * ext.appengine now supports FloatProperty and GeoPtProperty. * ext.sqlalchemy QueryMultipleSelectField changed to QuerySelectMultipleField. Version 0.5 ----------- Released February 13th, 2010. - Added a BaseForm class which provides the core processing and validation functionality of Form without requiring declarative subclassing. - Fields: * Field labels now default to a humanized field name. * Fields now have a `short_name` property which is the un-prefixed name. * DecimalField now rounds values for display without float coercion. See docs for details on how to format decimals. - Extensions: * ext.sqlalchemy.fields now has an additional QuerySelectMultipleField, and all fields can now support multiple-column primary keys. * ext.sqlalchemy.orm contains tools for making forms from ORM models. * Added ext.dateutil for flexible date-time parsing. * Added ext.appengine contributed by Rodrigo Moraes. - Added AnyOf and NoneOf validators. Version 0.4 ----------- Released October 10th, 2009. - Fields have much greater control over input processing. Filters have been added to implement a simple way to transform input data. - Added fields that encapsulate advanced data structures such as dynamic lists or child forms for more powerful field composing. - Fields now use widgets for rendering. - All built-in validators have been converted to classes to clean up the code. - `Form.auto_populate` and `Field.populate` were renamed to `populate_obj` to clarify that they populate another object, not the Form or Field. This is an API breaking change. - Dropped support for Python 2.3. Version 0.3.1 ------------- Released January 24th, 2009. - Several fixes were made to the code and tests to make WTForms compatible with Python 2.3/2.4. - Form's properties can now be accessed via dictionary-style access such as `form['author']`. This also has the intended effect of making variable lookups in Django templates more reliable. - Form and Field construction changes: Form now uses a metaclass to handle creating its `_unbound_fields` property, and Field construction now gives an instance of the new `UnboundField` class instead of using a partial function application. These are both internal changes and do not change the API. Version 0.3 ----------- Released January 18th, 2009. - Validation overhaul: Fields are now responsible for their own validation, instead of mostly relying on Form. There are also new pre_validate and post_validate hooks on subfields, adding a great deal of flexibility when dealing with field-level validation. Note that this is an API breaking change if you have any subfields that override `Field.validate`. These will need to be updated to use the new hooks. - Changes in how `process_data` and `process_formdata` are called: * `process_data` no longer accepts the `has_formdata` parameter. * At form instantiation time, `process_data` will be called only once for each field. If a model object is provided which contains the property, then this value is used. Otherwise, a keyword argument if specified is used. Failing that, the field's default value is used. * If any form data is sent, `process_formdata` will be called after `process_data` for each field. If no form data is available for the given field, it is called with an empty list. - wtforms.ext.django has been overhauled, both to mirror features and changes of the Django 1.0 release, and to add some useful fields for working with django ORM data in forms. - The `checker` keyword argument to SelectField, SelectMultipleField, and RadioField has been renamed to `coerce` to reflect the actual functionality of this callable. Version 0.2 ----------- Released January 13th, 2009. - We have documentation and unit tests! - Fields now have a `flags` property which contain boolean flags that are set either by the field itself or validators being specified on a field. The flags can then be used in checks in template or python code. - Changed the way fields take parameters, they are no longer quasi magic. This is a breaking change. Please see the documentation for the new syntax. - Added optional description argument to Field, accessible on the field as `description`. This provides an easy way to define e.g. help text in the same place as the form. - Added new semantics for validators which can stop the validation chain, with or without errors. - Added a regexp validator, and removed the not_empty validator in favour of two validators, optional and required. The new validators allow control over the validation chain in addition to checking emptiness. - Renamed wtforms.contrib to wtforms.ext and reorganised wtforms.ext.django. This is a breaking change if you were using the django extensions, but should only require changing your imports around a little. - Better support for other frameworks such as Pylons. Version 0.1 ----------- Released July 25th, 2008. - Initial release. simplecodes-wtforms-b83e12f59ac1/INSTALL.txt0000644000000000000000000000105011723462231016671 0ustar 00000000000000To install WTForms, run the following command: python setup.py install You can also download and install WTForms directly from the Python Package Index using either pip or easy_install: pip install WTForms easy_install -Z WTForms If you prefer, you can also simply place the `wtforms` subdirectory somewhere on your python path. This is useful if you are running the latest version from Mercurial, or want to deploy WTForms with your application on for example Google App Engine. Note that you need Python 2.4 or later to use WTForms. simplecodes-wtforms-b83e12f59ac1/LICENSE.txt0000644000000000000000000000275011723462231016655 0ustar 00000000000000Copyright (c) 2010 by Thomas Johansson, James Crasta and others. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. simplecodes-wtforms-b83e12f59ac1/MANIFEST.in0000644000000000000000000000042611723462231016566 0ustar 00000000000000include AUTHORS.txt include CHANGES.txt include INSTALL.txt include LICENSE.txt include MANIFEST.in include README.txt recursive-include docs * recursive-include tests * recursive-exclude docs/_build * recursive-exclude tests *.pyc recursive-include wtforms/ext/i18n/messages * simplecodes-wtforms-b83e12f59ac1/README.txt0000644000000000000000000000072611723462231016531 0ustar 00000000000000WTForms is a flexible forms validation and rendering library for python web development. For installation instructions, see INSTALL.txt. To get started using WTForms, we recommend reading the crash course on the website: http://wtforms.simplecodes.com/. If you downloaded the package from PyPI, there will be a prebuilt copy of the html documentation in the `docs/html/` directory. If not, you can generate it yourself by running `make html` in the `docs` directory. simplecodes-wtforms-b83e12f59ac1/docs/Makefile0000644000000000000000000000444611723462231017426 0ustar 00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html web pickle htmlhelp latex changes linkcheck help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " pickle to make pickle files (usable by e.g. sphinx-web)" @echo " htmlhelp to make HTML files and a HTML help project" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " changes to make an overview over all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" clean: -rm -rf _build/* html: mkdir -p _build/html _build/doctrees $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html @echo @echo "Build finished. The HTML pages are in _build/html." pickle: mkdir -p _build/pickle _build/doctrees $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle @echo @echo "Build finished; now you can process the pickle files or run" @echo " sphinx-web _build/pickle" @echo "to start the sphinx-web server." web: pickle htmlhelp: mkdir -p _build/htmlhelp _build/doctrees $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in _build/htmlhelp." latex: mkdir -p _build/latex _build/doctrees $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex @echo @echo "Build finished; the LaTeX files are in _build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." changes: mkdir -p _build/changes _build/doctrees $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes @echo @echo "The overview file is in _build/changes." linkcheck: mkdir -p _build/linkcheck _build/doctrees $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in _build/linkcheck/output.txt." simplecodes-wtforms-b83e12f59ac1/docs/_static/docstyles.css0000644000000000000000000000331111723462231022125 0ustar 00000000000000/* Those silly paragraph link entities */ a.headerlink { color: #B4B4B4!important; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none!important; visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } a.headerlink:hover { background-color: #B4B4B4; color: #F0F0F0!important; } /* Links to classes/functions */ a.reference { font-weight: bold; } #wtforms-documentation ul li a.reference, #toc ul li a.reference { font-weight: normal; } /* definition links */ dl.function dt, dl.class dt, dl.exception dt, dl.method dt, dl.attribute dt { font-weight: normal; } dt .descname { font-weight: bold } /* Warning boxes and other boxy things */ div.admonition, div.warning, div#toc { font-size: 0.9em; margin: 1em 0 0 0; border: 1px solid #86989B; background-color: #f7f7f7; } div.admonition p, div.warning p, div#toc p { margin: 0.5em 1em 0.5em 1em; padding: 0; } div.admonition pre, div.warning pre, div#toc pre { margin: 0.4em 1em 0.4em 1em; } div.admonition p.admonition-title, div.warning p.admonition-title, div#toc h3 { margin: 0; padding: 0.1em 0 0.1em 0.5em; color: white; border-bottom: 1px solid #86989B; font-weight: bold; background-color: #AFC1C4; } div.warning { border: 1px solid #940000; } div.warning p.admonition-title { background-color: #CF0000; border-bottom-color: #940000; } div.admonition ul, div.admonition ol, div.warning ul, div.warning ol, div#toc ul, div#toc ol { margin: 0.1em 0.5em 0.5em 3em; padding: 0; } simplecodes-wtforms-b83e12f59ac1/docs/_static/main.css0000644000000000000000000000204511723462231021043 0ustar 00000000000000body { font: 12px/1.4em 'Verdana', sans-serif; } h1, h2, h3, h4, h5, h6 { font-family: 'Trebuchet MS'; } h1, h2, h3 { font-weight: normal; } h2 { font-size: 1.8em; } h3 { font-size: 1.4em; } h4 { font-size: 1.2em; } a { color: #880000; text-decoration: none; } a:hover { text-decoration: underline; } img { border: 0; } pre { margin-left: 20px; border-left: 1px solid #dddddd; padding: 0 10px 5px 10px; } ul { padding-left: 25px; } ul ul { padding-left: 20px; } #body { margin: auto; max-width: 850px; } #header { border-bottom: 1px solid #efefef; position: relative; } #footer { border-top: 1px solid #efefef; text-align: center; color: #888; font-size: 10px; } #logo { margin: 0; padding: 0; } #menu { position: absolute; bottom: 5px; right: 5px; margin: 0; } #menu li { display: block; float: left; list-style-type: none; padding: 0 10px; } #menu li a { display: block; } #content { padding: 0 20px 5px 20px; } simplecodes-wtforms-b83e12f59ac1/docs/_static/wtforms.png0000644000000000000000000001241411723462231021615 0ustar 00000000000000PNG  IHDRE ePLTE⡞zzzmmm|||䩤ޙ֡||ڝ|uueeeܬuuuiiiTTU˒pppƁʍHHHaaaҎXXXƈrrrȐڌ^^^֔Λй戇xxvoo~~~wyegk뙟qszZZ]甘_ad|kmrPPPxxx𻹷ᣣsssՏッ󝘘\]\ӘNNN?OIDATx}XG~Dž@!FFFĻ1ؑ!g &R\n4O."!Ʋ{ߝwrNouA "}P:LI1W̽1gs >plۂ|426ä}B+gX#?{C܁ 8_M"S(m&PX9Wcnl7n80{U)-kJK`@<:z33R `_pMSӃ,YZA%kcbx@*Ƙ <Gn ZPyy5_cp!oC砺ѝ]_?J8Cޭ|pڨPh x@ &+z$2AsAr6srزt z/(} YFj݃KCr5"Jل#;fYB !ߧBz1o>\|lRpoO9`C˙caeU9@]Ӫpz-xkpRf7 Ls-k9`󖰰L=FcSCv0PU=twiMZ.^\4<όk:97t+Y=x֧=S߰8y5%eRܼ MYb%~^.3[㠲ɼ;7(YQfj/ W_?NzP:64=u۵ܐ5%j/a&g#0ޙPo.m'ӈJgs:ŒK8/{š瘱z̻PV%/7Яct]ф%ctOIMD0\R~mAiS͗Pff-ؠN4OAG3R6AYf&n]77+aPVojϬ ˯xh"T9̌)pᑇit&5%fx<rei,IB<RTe<3i䂉2ӥ'q!2-i>Mz3ږUGEɇW?72AIM`,y7+B,1\amʘ=[W5XٖFK}1N,٠y`?j2" l |my;Mz/;v6[SSe(1}㓪2SdBd;)]gFNe{]1_ffkF1ػ l;oצ Ӥ7k]*gN kW:MR˔iRk&􉼜wN#Bu)ٱ ՓS)VIbY.l*%}qxR;% ق:8xP#b//.V ;wQ[1'7`)Z=Zwd/jl<9˒74EmK`"ҖmXfϕ\*%5Sclۆm9'Ve(9Cً>ylq9$isuꪈH[ aXU>ny$YB^@sDf2f'2gBJ< ,VU!$^bIf_$m=+$i2/厬5Je6GVh%Z]x>oT)8pyˮNJN0/Hl CIJd4YzoYU%K鋈MKm:xsAA4ӏHeRGu0赚87Qf.ƺe^C+dNbW%p-8aWkkQ%ɷɓ/?O?"TQ)xfL5˫2YAiq˭܊ :kkW\PmCɲM!Oyzˏ,,p(Sq\Sp6#lhquz`[CJB{}N.ݘVH9 9($P;!=Em7xi[z h8?[y>Zl?`BqJ 0a']( `spN|:E&.m#YGqzWêqa;zewAB] -, çz^/m;PPq] vmӝ<ƍ`hd"c*2.LOtp)Adה 9 q$ㇹPpOӝK2 cdf&[2;(,q ruF-[̷o1_#=z05%IENDB`simplecodes-wtforms-b83e12f59ac1/docs/_templates/layout.html0000644000000000000000000000654111723462231022324 0ustar 00000000000000 WTForms Documentation {%- if builder != 'htmlhelp' %} {%- endif %} {%- if use_opensearch and builder != 'htmlhelp' %} {%- endif %} {%- if hasdoc('about') %} {%- endif %} {%- if hasdoc('copyright') %} {%- endif %} {%- if parents %} {%- endif %} {%- if next %} {%- endif %} {%- if prev %} {%- endif %} {% block extrahead %}{% endblock %}
{%- if display_toc %}

Table Of Contents

{{ toc }}
{%- endif %} {% block body %}{% endblock %}
simplecodes-wtforms-b83e12f59ac1/docs/conf.py0000644000000000000000000001354711723462231017267 0ustar 00000000000000# -*- coding: utf-8 -*- # # WTForms documentation build configuration file, created by # sphinx-quickstart on Fri Aug 01 15:29:36 2008. # # This file is execfile()d with the current directory set to its containing dir. # # The contents of this file are pickled, so don't put values in the namespace # that aren't pickleable (module imports are okay, they're removed automatically). # # All configuration values have a default value; values that are commented out # serve to show the default value. import sys, os sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) # If your extensions are in another directory, add it here. If the directory # is relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. #sys.path.append(os.path.abspath('some/directory')) # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General substitutions. project = 'WTForms' copyright = '2010 by Thomas Johansson, James Crasta' # The default replacements for |version| and |release|, also used in various # other places throughout the built documents. # # The short X.Y version. version = '1.0.1' # The full version, including alpha/beta/rc tags. release = '1.0.1' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' # List of documents that shouldn't be included in the build. #unused_docs = [] # List of directories, relative to source directories, that shouldn't be searched # for source files. #exclude_dirs = [] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'friendly' # Options for HTML output # ----------------------- # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'default.css' # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (within the static path) to place at the top of # the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, the reST sources are included in the HTML build as _sources/. #html_copy_source = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'WTFormsdoc' # Options for LaTeX output # ------------------------ # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ ('index', 'WTForms.tex', 'WTForms Documentation', 'Thomas Johansson, James Crasta', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True simplecodes-wtforms-b83e12f59ac1/docs/crash_course.rst0000644000000000000000000003517511723462231021203 0ustar 00000000000000.. _crash-course: Crash Course ============ So you’ve cracked your knuckles and started working on that awesome python webapp you want to write. You get through writing a few pages and finally you need to tackle that loathsome task: form input handling and validation. Enter WTForms. But why do I need *yet another* framework? Well, some webapp frameworks take the approach of associating database models with form handling. While this can be handy for very basic create/update views, chances are not every form you need can map directly to a database model. Or maybe you already use a generic form handling framework but you want to customize the HTML generation of those form fields, and define your own validation. With WTForms, your form field HTML can be generated for you, but we let you customize it in your templates. This allows you to maintain separation of code and presentation, and keep those messy parameters out of your python code. Because we strive for loose coupling, you should be able to do that in any templating engine you like, as well. .. _download-installation: Download / Installation ----------------------- The easiest way to install WTForms is by using easy_install or pip: .. code-block:: ruby easy_install WTForms pip install WTForms You can also `download`_ WTForms manually from PyPI and then run ``python setup.py install``. If you're the sort that likes to risk it all and run the latest version from Mercurial, you can grab a `packaged up version`_ of the tip, or head over to `Bitbucket`_ and clone the repository. .. _download: http://pypi.python.org/pypi/WTForms .. _packaged up version: http://bitbucket.org/simplecodes/wtforms/get/tip.zip .. _Bitbucket: http://bitbucket.org/simplecodes/wtforms Key Concepts ------------ - **Forms** are the core container of WTForms. Forms represent a collection of fields, which can be accessed on the form dictionary-style or atrribute style. - **Fields** do most of the heavy lifting. Each field represents a *data type* and the field handles coercing form input to that datatype. For example, `IntegerField` and `TextField` represent two different data types. Fields contain a number of useful properties, such as a label, description, and a list of validation errors, in addition to the data the field contains. - Every field has a **Widget** instance. The widget's job is rendering an HTML representation of that field. Widget instances can be specified for each field but every field has one by default which makes sense. Some fields are simply conveniences, for example `TextAreaField` is simply a `TextField` with the default widget being a `TextArea`. - In order to specify validation rules, fields contain a list of **Validators**. Getting Started --------------- Let's get right down to business and define our first form:: from wtforms import Form, BooleanField, TextField, validators class RegistrationForm(Form): username = TextField('Username', [validators.Length(min=4, max=25)]) email = TextField('Email Address', [validators.Length(min=6, max=35)]) accept_rules = BooleanField('I accept the site rules', [validators.Required()]) When you create a form, you define the fields in a way that is similar to the way many ORM’s have you define their columns; By defining class variables which are instantiations of the fields. Because forms are regular Python classes, you can easily extend them as you would expect:: class ProfileForm(Form): birthday = DateTimeField('Your Birthday', format='%m/%d/%y') signature = TextAreaField('Forum Signature') class AdminProfileForm(ProfileForm): username = TextField('Username', [validators.Length(max=40)]) level = IntegerField('User Level', [validators.NumberRange(min=0, max=10)]) Via subclassing, `AdminProfileForm`, gains all the fields already defined in `ProfileForm`. This allows you to easily share common subsets of fields between forms, such as the example above, where we are adding admin-only fields to `ProfileForm`. Using Forms ~~~~~~~~~~~ Using a form is as simple as instantiating it. Consider the following django-like view, using the `RegistrationForm` we defined earlier:: def register(request): form = RegistrationForm(request.POST) if request.method == 'POST' and form.validate(): user = User() user.username = form.username.data user.email = form.email.data user.save() redirect('register') return render_response('register.html', form=form) First, we instantiate the form, providing it with any data available in ``request.POST``. We then check if the request is made using POST, and if it is, we validate the form, and check that the user accepted the rules. If successful, we create a new User and assign the data from the validated form to it, and save it. Editing existing objects ^^^^^^^^^^^^^^^^^^^^^^^^ Our earlier registration example showed how to accept input and validate it for new entries, but what if we want to edit an existing object? Easy:: def edit_profile(request): user = request.current_user form = ProfileForm(request.POST, user) if request.method == 'POST' and form.validate(): form.populate_obj(user) user.save() redirect('edit_profile') return render_response('edit_profile.html', form=form) Here, we instantiate the form by providing both request.POST and the user object to the form. By doing this, the form will get any data that isn't present in the post data from the `user` object. We're also using the form's `populate_obj` method to re-populate the user object with the contents of the validated form. This method is provided for convenience, for use when the field names match the names on the object you're providing with data. Typically, you will want to assign the values manually, but for this simple case it's perfect. It can also be useful for CRUD and admin forms. Exploring in the console ^^^^^^^^^^^^^^^^^^^^^^^^ WTForms forms are very simple container objects, and perhaps the easiest way to find out what's available to you in a form is to play around with a form in the console:: >>> from wtforms import Form, TextField, validators >>> class UsernameForm(Form): ... username = TextField('Username', [validators.Length(min=5)], default=u'test') ... >>> form = UsernameForm() >>> form['username'] >>> form.username.data u'test' >>> form.validate() False >>> form.errors {'username': [u'Field must be at least 5 characters long.']} What we've found here is that when you instantiate a form, it contains instances of all the fields, which can be accessed via either dictionary-style or attribute-style. These fields have their own properties, as does the enclosing form. When we validate the form, it returns False, meaning at least one validator was not satisfied. form.errors will give you a summary of all the errors. .. code-block:: python >>> form2 = UsernameForm(username=u'Robert') >>> form2.data {'username': u'Robert'} >>> form2.validate() True This time, we passed a new value for username when instantiating UserForm, and it was sufficient to validate the form. How Forms get data ~~~~~~~~~~~~~~~~~~ In addition to providing data using the first two arguments (`formdata` and `obj`), you can pass keyword arguments to populate the form. Note though that a few names are reserved: `formdata`, `obj`, and `prefix`. `formdata` takes precendence over `obj`, which itself takes precedence over keyword arguments. For example:: def change_username(request): user = request.current_user form = ChangeUsernameForm(request.POST, user, username='silly') if request.method == 'POST' and form.validate(): user.username = form.username.data user.save() return redirect('change_username') return render_response('change_username.html', form=form) While you almost never use all three methods together in practice, it illustrates how WTForms looks up the `username` field: 1. If a form was submitted (request.POST is not empty), process the form input. Even if there was no form input for this field in particular, if there exists form input of any sort, then we will process the form input. 2. If there was no form input, then try the following in order: 1. Check if `user` has an attribute named `username`. 2. Check if a keyword argument named `username` was provided. 3. Finally, if everything else fails, use the default value provided by the field, if any. Validators ~~~~~~~~~~ Validation in WTForms is done by providing a field with a set of validators to run when the containing form is validated. You provide these via the field constructor's second argument, `validators`:: class ChangeEmailForm(Form): email = TextField('Email', [validators.Length(min=6, max=120), validators.Email()]) You can provide any number of validators to a field. Typically, you will want to provide a custom error message:: class ChangeEmailForm(Form): email = TextField('Email', [ validators.Length(min=6, message=_(u'Little short for an email address?')), validators.Email(message=_(u'That\'s not a valid email address.')) ]) It is generally preferable to provide your own messages, as the default messages by necessity are generic. This is also the way to provide localised error messages. For a list of all the built-in validators, check the :mod:`Validators Reference ` Rendering Fields ~~~~~~~~~~~~~~~~ Rendering a field is as simple as coercing it to a string:: >>> from wtforms import Form, TextField >>> class SimpleForm(Form): ... content = TextField('content') ... >>> form = SimpleForm(content='foobar') >>> str(form.content) '' >>> unicode(form.content) u'' However, the real power comes from rendering the field with its :meth:`~wtforms.fields.Field.__call__` method. By calling the field, you can provide keyword arguments, which will be injected as html parameters in the output:: >>> form.content(style="width: 200px;", class_="bar") u'' Now let's apply this power to rendering a form in a `Jinja `_ template. First, our form:: class LoginForm(Form): username = TextField('Username') password = PasswordField('Password') form = LoginForm() And the template: .. code-block:: html+jinja
{{ form.username.label }}: {{ form.username(class="css_class") }}
{{ form.password.label }}: {{ form.password() }}
Alternately, if you're using Django templates, you can use the `form_field` templatetag we provide in our Django extension, when you want to pass keyword arguments: .. code-block:: html+django {% load wtforms %}
{{ form.username.label }}: {% form_field form.username class="css_class" %}
{{ form.password.label }}: {{ form.password }}
Both of these will output: .. code-block:: html
:
:
WTForms is template engine agnostic, and will work with anything that allows attribute access, string coercion, and/or function calls. The `form_field` templatetag is provided as a convenience as you can't pass arguments in Django templates. Displaying Errors ~~~~~~~~~~~~~~~~~ Now that we have a template for our form, let's add error messages: .. code-block:: html+jinja
{{ form.username.label }}: {{ form.username(class="css_class") }}
{% if form.username.errors %}
    {% for error in form.username.errors %}
  • {{ error }}
  • {% endfor %}
{% endif %}
{{ form.password.label }}: {{ form.password() }}
{% if form.password.errors %}
    {% for error in form.password.errors %}
  • {{ error }}
  • {% endfor %}
{% endif %}
If you prefer one big list of errors at the top, this is also easy: .. code-block:: html+jinja {% if form.errors %}
    {% for field_name, field_errors in form.errors|dictsort if field_errors %} {% for error in field_errors %}
  • {{ form[field_name].label }}: {{ error }}
  • {% endfor %} {% endfor %}
{% endif %} As error handling can become a rather verbose affair, it is preferable to use Jinja macros (or equivalent) to reduce boilerplate in your templates. (:ref:`example `) Custom Validators ~~~~~~~~~~~~~~~~~ There are two ways to provide custom validators. By defining a custom validator and using it on a field:: from wtforms.validators import ValidationError def is_42(form, field): if field.data != 42: raise ValidationError('Must be 42') class FourtyTwoForm(Form): num = IntegerField('Number', [is_42]) Or by providing an in-form field-specific validator:: class FourtyTwoForm(Form): num = IntegerField('Number') def validate_num(form, field): if field.data != 42: raise ValidationError(u'Must be 42') For more complex validators that take parameters, check the :ref:`custom-validators` section. Next Steps ---------- The crash course has just skimmed the surface on how you can begin using WTForms to handle form input and validation in your application. For more information, you'll want to check the following: - The :ref:`WTForms documentation ` has API documentation for the entire library. - :ref:`specific_problems` can help you tackle specific integration issues with WTForms and other frameworks. - The `mailing list`_ is where you can get help, discuss bugs in WTForms, and propose new features. .. _mailing list: http://groups.google.com/group/wtforms/ simplecodes-wtforms-b83e12f59ac1/docs/ext.rst0000644000000000000000000003267611723462231017326 0ustar 00000000000000.. _extensions: Extensions ========== .. module:: wtforms.ext WTForms ships with a number of extensions that make it easier to work with other frameworks and libraries, such as Django. Appengine --------- .. module:: wtforms.ext.appengine WTForms now includes support for AppEngine fields as well as auto-form generation. Model Forms ~~~~~~~~~~~ .. module:: wtforms.ext.appengine.db See the module docstring for examples on how to use :func:`model_form`. .. autofunction:: model_form(model, base_class=Form, only=None, exclude=None, field_args=None, converter=None) Datastore-backed Fields ~~~~~~~~~~~~~~~~~~~~~~~ .. module:: wtforms.ext.appengine.fields .. autoclass:: ReferencePropertyField(default field arguments, reference_class=None, get_label=None, allow_blank=False, blank_text=u'') .. autoclass:: StringListPropertyField(default field arguments) .. autoclass:: GeoPtPropertyField(default field arguments) Dateutil -------- .. module:: wtforms.ext.dateutil.fields For better date-time parsing using the `python-dateutil`_ package, :mod:`wtforms.ext.dateutil` provides a set of fields to use to accept a wider range of date input. .. _python-dateutil: http://labix.org/python-dateutil .. autoclass:: DateTimeField(default field arguments, parse_kwargs=None, display_format='%Y-%m-%d %H:%M') .. autoclass:: DateField(default field arguments, parse_kwargs=None, display_format='%Y-%m-%d') Django ------ .. module:: wtforms.ext.django This extension provides templatetags to make it easier to work with Django templates and WTForms' html attribute rendering. It also provides a generator for automatically creating forms based on Django ORM models. Templatetags ~~~~~~~~~~~~ .. module:: wtforms.ext.django.templatetags.wtforms Django templates does not allow arbitrarily calling functions with parameters, making it impossible to use the html attribute rendering feature of WTForms. To alleviate this, we provide a templatetag. Adding :mod:`wtforms.ext.django` to your INSTALLED_APPS will make the wtforms template library available to your application. With this you can pass extra attributes to form fields similar to the usage in jinja: .. code-block:: django {% load wtforms %} {% form_field form.username class="big_text" onclick="do_something()" %} **Note** By default, using the `{{ form.field }}` syntax in django models will be auto-escaped. To avoid this happening, use Django's `{% autoescape off %}` block tag or use WTForms' `form_field` template tag. Model forms ~~~~~~~~~~~ .. module:: wtforms.ext.django.orm .. autofunction:: model_form(model, base_class=Form, only=None, exclude=None, field_args=None, converter=None) :func:`model_form` attempts to glean as much metadata as possible from inspecting the model's fields, and will even attempt to guess at what validation might be wanted based on the field type. For example, converting an `EmailField` will result in a :class:`~wtforms.fields.TextField` with the :func:`~wtforms.validators.email` validator on it. if the `blank` property is set on a model field, the resulting form field will have the :func:`~wtforms.validators.optional` validator set. Just like any other Form, forms created by ModelForm can be extended via inheritance:: UserFormBase = model_form(User) class UserForm(UserFormBase): new_pass = PasswordField('', [validators.optional(), validators.equal_to('confirm_pass')]) confirm_pass = PasswordField() When combined with :meth:`form iteration `, model_form is a handy way to generate dynamic CRUD forms which update with added fields to the model. One must be careful though, as it's possible the generated form fields won't be as strict with validation as a hand-written form might be. ORM-backed fields ~~~~~~~~~~~~~~~~~ .. module:: wtforms.ext.django.fields While linking data to most fields is fairly easy, making drop-down select lists using django ORM data can be quite repetitive. To this end, we have added some helpful tools to use the django ORM along with wtforms. .. autoclass:: QuerySetSelectField(default field args, queryset=None, get_label=None, allow_blank=False, blank_text=u'') .. code-block:: python class ArticleEdit(Form): title = TextField() column = QuerySetSelectField(get_label='title', allow_blank=True) category = QuerySetSelectField(queryset=Category.objects.all()) def edit_article(request, id): article = Article.objects.get(pk=id) form = ArticleEdit(obj=article) form.column.queryset = Column.objects.filter(author=request.user) As shown in the above example, the queryset can be set dynamically in the view if needed instead of at form construction time, allowing the select field to consist of choices only relevant to the user. .. autoclass:: ModelSelectField(default field args, model=None, get_label='', allow_blank=False, blank_text=u'') SQLAlchemy ---------- .. module:: wtforms.ext.sqlalchemy This extension provides SelectField integration with SQLAlchemy ORM models, similar to those in the Django extension. ORM-backed fields ~~~~~~~~~~~~~~~~~ .. module:: wtforms.ext.sqlalchemy.fields These fields are provided to make it easier to use data from ORM objects in your forms. .. code-block:: python def enabled_categories(): return Category.query.filter_by(enabled=True) class BlogPostEdit(Form): title = TextField() blog = QuerySelectField(get_label='title') category = QuerySelectField(query_factory=enabled_categories, allow_blank=True) def edit_blog_post(request, id): post = Post.query.get(id) form = ArticleEdit(obj=post) # Since we didn't provide a query_factory for the 'blog' field, we need # to set a dynamic one in the view. form.blog.query = Blog.query.filter(Blog.author == request.user).order_by(Blog.name) .. autoclass:: QuerySelectField(default field args, query_factory=None, get_pk=None, get_label=None, allow_blank=False, blank_text=u'') .. autoclass:: QuerySelectMultipleField(default field args, query_factory=None, get_pk=None, get_label=None, allow_blank=False, blank_text=u'') CSRF ---- .. module:: wtforms.ext.csrf The CSRF package includes tools that help you implement checking against cross-site request forgery ("csrf"). Due to the large number of variations on approaches people take to CSRF (and the fact that many make compromises) the base implementation allows you to plug in a number of CSRF validation approaches. CSRF implementations are made by subclassing :class:`~wtforms.ext.csrf.form.SecureForm`. For utility, we have provided one possible CSRF implementation in the package that can be used with many frameworks for session-based hash secure keying, :class:`~wtforms.ext.csrf.session.SessionSecureForm`. All CSRF implementations hinge around creating a special token, which is put in a hidden field on the form named 'csrf_token', which must be rendered in your template to be passed from the browser back to your view. There are many different methods of generating this token, but they are usually the result of a cryptographic hash function against some data which would be hard to forge. .. module:: wtforms.ext.csrf.form .. autoclass:: SecureForm .. automethod:: generate_csrf_token .. automethod:: validate_csrf_token Creating your own CSRF implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here we will sketch out a simple theoretical CSRF implementation which generates a hash token based on the user's IP. **Note** This is a simplistic example meant to illustrate creating a CSRF implementation. This isn't recommended to be used in production because the token is deterministic and non-changing per-IP, which means this isn't the most secure implementation of CSRF. First, let's create our SecureForm base class:: from wtforms.ext.csrf import SecureForm from hashlib import md5 SECRET_KEY = '1234567890' class IPSecureForm(SecureForm): """ Generate a CSRF token based on the user's IP. I am probably not very secure, so don't use me. """ def generate_csrf_token(self, csrf_context): # csrf_context is passed transparently from the form constructor, # in this case it's the IP address of the user token = md5(SECRET_KEY + csrf_context).hexdigest() return token def validate_csrf_token(self, field): if field.data != field.current_token: raise ValueError('Invalid CSRF') Now that we have this taken care of, let's write a simple form and view which would implement this:: class RegistrationForm(IPSecureForm): name = TextField('Your Name') email = TextField('Email', [validators.email()]) def register(request): form = RegistrationForm(request.POST, csrf_context=request.ip) if request.method == 'POST' and form.validate(): pass # We're all good, create a user or whatever it is you do elif form.csrf_token.errors: pass # If we're here we suspect the user of cross-site request forgery else: pass # Any other errors return render('register.html', form=form) And finally, a simple template: .. code-block:: html+jinja
{{ form.csrf_token }}

{{ form.name.label }}: {{ form.name }}

{{ form.email.label }}: {{ form.email }}

Please note that implementing CSRF detection is not fool-proof, and even with the best CSRF protection implementation, it's possible for requests to be forged by expert attackers. However, a good CSRF protection would make it infeasible for someone from an external site to hijack a form submission from another user and perform actions as them without additional a priori knowledge. In addition, it's important to understand that very often, the more strict the CSRF protection, the higher the chance of false positives occurring (ie, legitimate users getting blocked by your CSRF protection) and choosing a CSRF implementation is actually a matter of compromise. We will attempt to provide a handful of usable reference algorithms built in to this library in the future, to allow that choice to be easy. Some tips on criteria people often examine when evaluating CSRF implementations: * **Reproducability** If a token is based on attributes about the user, it gains the advantage that one does not need secondary storage in which to store the value between requests. However, if the same attributes can be reproduced by an attacker, then the attacker can potentially forge this information. * **Reusability**. It might be desired to make a completely different token every use, and disallow users from re-using past tokens. This is an extremely powerful protection, but can have consequences on if the user uses the back button (or in some cases runs forms simultaneously in multiple browser tabs) and submits an old token, or otherwise. A possible compromise is to allow reusability in a time window (more on that later). * **Time Ranges** Many CSRF approaches use time-based expiry to make sure that a token cannot be (re)used beyond a certain point. Care must be taken in choosing the time criteria for this to not lock out legitimate users. For example, if a user might walk away while filling out a long-ish form, or to go look for their credit card, the time for expiry should take that into consideration to provide a balance between security and limiting user inconvenience. * **Requirements** Some CSRF-prevention methods require the use of browser cookies, and some even require client-side scripting support. The webmaster implementing the CSRF needs to consider that such requirements (though effective) may lock certain legitimate users out, and make this determination whether it is a good idea to use. For example, for a site already using cookies for login, adding another for CSRF isn't as big of a deal, but for other sites it may not be feasible. Session-based CSRF implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. automodule:: wtforms.ext.csrf.session **Usage** First, create a SessionSecureForm subclass that you can use as your base class for any forms you want CSRF support for:: from wtforms.ext.csrf.session import SessionSecureForm class MyBaseForm(SessionSecureForm): SECRET_KEY = 'EPj00jpfj8Gx1SjnyLxwBBSQfnQ9DJYe0Ym' TIME_LIMIT = timedelta(minutes=20) Now incorporate it into any form/view by further subclassing:: class Registration(MyBaseForm): name = TextField() def view(request): form = Registration(request.POST, csrf_context=request.session) # rest of view here Note that request.session is passed as the ``csrf_context=`` parameter, this is so that the CSRF token can be stored in your session for comparison on a later request. .. autoclass:: SessionSecureForm A provided CSRF implementation which puts CSRF data in a session. Must be subclassed to be used. **Class Attributes** .. attribute:: SECRET_KEY Must be set by subclasses to a random byte string that will be used to generate HMAC digests. .. attribute:: TIME_LIMIT If None, CSRF tokens never expire. If set to a ``datetime.timedelta``, this is how long til a generated token expires. Defaults to ``timedelta(minutes=30)`` simplecodes-wtforms-b83e12f59ac1/docs/faq.rst0000644000000000000000000001236211723462231017263 0ustar 00000000000000FAQ === This contains the most commonly asked questions about WTForms. The most current version of this document can always be found on the `WTForms Website`_. .. _WTForms Website: http://wtforms.simplecodes.com Why does WTForms copy Django Forms? ----------------------------------- Were we a bit more audacious, we'd probably say Django Forms copied us, but the reality is that WTForms and Django's "newforms" were actually written at about the same time. When WTForms was written, our primary goals were to provide HTML customization through templates, easily customized validation and a simple, declarative ORM-style API. At the time there was no newforms and the other alternatives either didn't support HTML generation, were very tightly coupled with a single framework, or relied too heavily on an ORM. Does WTForms work with [library here]? -------------------------------------- The answer is most likely **yes**. WTForms tries to provide as usable an API as possible. We've listed here some of the known libraries to work with WTForms, but if it's not listed, it doesn't mean it won't work. * **Request/Form Input** * Django * Webob (Includes Pylons, Google App Engine, Turbogears) * Werkzeug (Includes Flask, Tipfy) * any other cgi.FieldStorage-type multidict * **Templating Engines** * Jinja2 * Mako * Django Templates (To get the full power of WTForms in your templates, you will need to use the Django :mod:`extension `.) * Genshi * **Database Objects** * Pretty much any ORM or object-DB should work, as long as data objects allow attribute access to their members. Special support is there for SQLAlchemy, Google App Engine, and Django collections via :mod:`extensions `. Does WTForms support unicode? ----------------------------- Simple answer: Yes. Longer answer: WTForms uses unicode strings throughout the source code, and assumes that form input has already been coerced to unicode by your framework (Most frameworks already do this.) WTForms fields render to unicode strings by default, and therefore as long as your templating engine can work with that, you should have no unicode issues. What versions of Python are supported? -------------------------------------- WTForms supports Python versions 2.5 and up. Presently (as of December 2011), Python 3.x is not officially supported, but the development version has made headway on this. We expect the upcoming 1.0 release to fully support Python 3 using the '2to3' tool. How can I contribute to WTForms? -------------------------------- WTForms is not that scary. Really. We try to keep it as succint and readable as possible. If you feel like you have something to contribute to WTForms, let us know on the `mailing list`_. For bugs and feature requests, you can file a ticket on the `project page`_. .. _mailing list: http://groups.google.com/group/wtforms .. _project page: http://bitbucket.org/simplecodes/wtforms How do I mark in a template when a field is required? ----------------------------------------------------- Some validators (notably Required and Optional) set flags on the fields' :attr:`~wtforms.fields.Field.flags` object. To use this in a template, you can do something like: .. code-block:: html+jinja {% for field in form %} {{ field }} {% if field.flags.required %}*{% endif %}{{ field.label }} {% endfor %} Does WTForms handle file uploads? --------------------------------- Currently, it does not. This is because WTForms strives to be framework-agnostic, and every web framework handles file uploads somewhat differently. WTForms has a :class:`~wtforms.fields.FileField` which will let you render a file input widget, but the rest is up to you. An example use in a django-ish framework:: class MyForm(Form): image = FileField() def my_view(request): form = MyForm(request.POST) file_wrapper = request.FILES[form.image.name] # Do things with your file wrapper now Using ``form.image.name`` is an easy way to know what input name was generated for your file input, even if the form is prefixed. Why does blank input not go back to the default value? ------------------------------------------------------ A key design decision of WTForms was that form data -always- takes precedence when there's a form submission. That is, if a field exists on a form, and a form was posted, but that field's value was missing, it will not revert to a default, but instead store an empty value (and in some cases cause a validation error.) This is for a number of reasons: 1. Security. If a form reverted to defaults on missing data, then an evil user could potentially cause problems by submitting a hand-coded form with key missing fields. 2. Bug-finding. If you omitted a field in your template, it might fall through to the default and you'd possibly miss it. 3. Consistency. See the following mailing list posts for more discussion on the topic: - http://groups.google.com/group/wtforms/browse_frm/thread/6755a45a13878e9 - http://groups.google.com/group/wtforms/msg/fa409c8c89b6f62d How do I... [convoluted combination of libraries] ------------------------------------------------- You'll probably want to check out our :ref:`Solving Specific Problems ` doc. simplecodes-wtforms-b83e12f59ac1/docs/fields.rst0000644000000000000000000004412711723462231017766 0ustar 00000000000000Fields ====== .. module:: wtforms.fields Fields are responsible for rendering and data conversion. They delegate to validators for data validation. Field definitions ----------------- Fields are defined as members on a form in a declarative fashion:: class MyForm(Form): name = TextField(u'Full Name', [validators.required(), validators.length(max=10)]) address = TextAreaField(u'Mailing Address', [validators.optional(), validators.length(max=200)]) When a field is defined on a form, the construction parameters are saved until the form is instantiated. At form instantiation time, a copy of the field is made with all the parameters specified in the definition. Each instance of the field keeps its own field data and errors list. The label and validators can be passed to the constructor as sequential arguments, while all other arguments should be passed as keyword arguments. Some fields (such as :class:`SelectField`) can also take additional field-specific keyword arguments. Consult the built-in fields reference for information on those. The Field base class -------------------- .. class:: Field Stores and processes data, and generates HTML for a form field. Field instances contain the data of that instance as well as the functionality to render it within your Form. They also contain a number of properties which can be used within your templates to render the field and label. **Construction** .. automethod:: __init__ **Validation** To validate the field, call its `validate` method, providing a form and any extra validators needed. To extend validation behaviour, override `pre_validate` or `post_validate`. .. automethod:: validate .. automethod:: pre_validate .. automethod:: post_validate .. attribute:: errors If `validate` encounters any errors, they will be inserted into this list. **Data access and processing** To handle incoming data from python, override `process_data`. Similarly, to handle incoming data from the outside, override `process_formdata`. .. automethod:: process(formdata [, data]) .. automethod:: process_data .. automethod:: process_formdata .. attribute:: data Contains the resulting (sanitized) value of calling either of the process methods. Note that it is not HTML escaped when using in templates. .. attribute:: raw_data If form data is processed, is the valuelist given from the formdata wrapper. Otherwise, `raw_data` will be `None`. .. attribute:: object_data This is the data passed from an object or from kwargs to the field, stored unmodified. This can be used by templates, widgets, validators as needed (for comparison, for example) **Rendering** To render a field, simply call it, providing any values the widget expects as keyword arguments. Usually the keyword arguments are used for extra HTML attributes. .. automethod:: __call__ If one wants to pass the "class" argument which is a reserved keyword in some python-based templating languages, one can do:: form.field(class_="text_blob") This will output (for a text field): .. code-block:: html Note: Simply coercing the field to a string or unicode will render it as if it was called with no arguments. .. automethod:: __html__ Many template engines use the __html__ method when it exists on a printed object to get an 'html-safe' string that will not be auto-escaped. To allow for printing a bare field without calling it, all WTForms fields implement this method as well. **Properties** .. attribute:: name The HTML form name of this field. This is the name as defined in your Form prefixed with the `prefix` passed to the Form constructor. .. attribute:: short_name The un-prefixed name of this field. .. attribute:: id The HTML ID of this field. If unspecified, this is generated for you to be the same as the field name. .. attribute:: label This is a :class:`Label` instance which when evaluated as a string returns an HTML ``