177
									
								
								docs/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								docs/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,177 @@ | ||||
| # Makefile for Sphinx documentation | ||||
| # | ||||
|  | ||||
| # You can set these variables from the command line. | ||||
| SPHINXOPTS    = | ||||
| SPHINXBUILD   = sphinx-build | ||||
| PAPER         = | ||||
| BUILDDIR      = _build | ||||
|  | ||||
| # User-friendly check for sphinx-build | ||||
| ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) | ||||
| $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) | ||||
| endif | ||||
|  | ||||
| # Internal variables. | ||||
| PAPEROPT_a4     = -D latex_paper_size=a4 | ||||
| PAPEROPT_letter = -D latex_paper_size=letter | ||||
| ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | ||||
| # the i18n builder cannot share the environment and doctrees with the others | ||||
| I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | ||||
|  | ||||
| .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext | ||||
|  | ||||
| help: | ||||
| 	@echo "Please use \`make <target>' where <target> is one of" | ||||
| 	@echo "  html       to make standalone HTML files" | ||||
| 	@echo "  dirhtml    to make HTML files named index.html in directories" | ||||
| 	@echo "  singlehtml to make a single large HTML file" | ||||
| 	@echo "  pickle     to make pickle files" | ||||
| 	@echo "  json       to make JSON files" | ||||
| 	@echo "  htmlhelp   to make HTML files and a HTML help project" | ||||
| 	@echo "  qthelp     to make HTML files and a qthelp project" | ||||
| 	@echo "  devhelp    to make HTML files and a Devhelp project" | ||||
| 	@echo "  epub       to make an epub" | ||||
| 	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | ||||
| 	@echo "  latexpdf   to make LaTeX files and run them through pdflatex" | ||||
| 	@echo "  latexpdfja to make LaTeX files and run them through platex/dvipdfmx" | ||||
| 	@echo "  text       to make text files" | ||||
| 	@echo "  man        to make manual pages" | ||||
| 	@echo "  texinfo    to make Texinfo files" | ||||
| 	@echo "  info       to make Texinfo files and run them through makeinfo" | ||||
| 	@echo "  gettext    to make PO message catalogs" | ||||
| 	@echo "  changes    to make an overview of all changed/added/deprecated items" | ||||
| 	@echo "  xml        to make Docutils-native XML files" | ||||
| 	@echo "  pseudoxml  to make pseudoxml-XML files for display purposes" | ||||
| 	@echo "  linkcheck  to check all external links for integrity" | ||||
| 	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)" | ||||
|  | ||||
| clean: | ||||
| 	rm -rf $(BUILDDIR)/* | ||||
|  | ||||
| html: | ||||
| 	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | ||||
| 	@echo | ||||
| 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html." | ||||
|  | ||||
| dirhtml: | ||||
| 	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml | ||||
| 	@echo | ||||
| 	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." | ||||
|  | ||||
| singlehtml: | ||||
| 	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml | ||||
| 	@echo | ||||
| 	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." | ||||
|  | ||||
| pickle: | ||||
| 	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle | ||||
| 	@echo | ||||
| 	@echo "Build finished; now you can process the pickle files." | ||||
|  | ||||
| json: | ||||
| 	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json | ||||
| 	@echo | ||||
| 	@echo "Build finished; now you can process the JSON files." | ||||
|  | ||||
| htmlhelp: | ||||
| 	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp | ||||
| 	@echo | ||||
| 	@echo "Build finished; now you can run HTML Help Workshop with the" \ | ||||
| 	      ".hhp project file in $(BUILDDIR)/htmlhelp." | ||||
|  | ||||
| qthelp: | ||||
| 	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp | ||||
| 	@echo | ||||
| 	@echo "Build finished; now you can run "qcollectiongenerator" with the" \ | ||||
| 	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:" | ||||
| 	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-formtools.qhcp" | ||||
| 	@echo "To view the help file:" | ||||
| 	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-formtools.qhc" | ||||
|  | ||||
| devhelp: | ||||
| 	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp | ||||
| 	@echo | ||||
| 	@echo "Build finished." | ||||
| 	@echo "To view the help file:" | ||||
| 	@echo "# mkdir -p $$HOME/.local/share/devhelp/django-formtools" | ||||
| 	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-formtools" | ||||
| 	@echo "# devhelp" | ||||
|  | ||||
| epub: | ||||
| 	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub | ||||
| 	@echo | ||||
| 	@echo "Build finished. The epub file is in $(BUILDDIR)/epub." | ||||
|  | ||||
| latex: | ||||
| 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | ||||
| 	@echo | ||||
| 	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." | ||||
| 	@echo "Run \`make' in that directory to run these through (pdf)latex" \ | ||||
| 	      "(use \`make latexpdf' here to do that automatically)." | ||||
|  | ||||
| latexpdf: | ||||
| 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | ||||
| 	@echo "Running LaTeX files through pdflatex..." | ||||
| 	$(MAKE) -C $(BUILDDIR)/latex all-pdf | ||||
| 	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." | ||||
|  | ||||
| latexpdfja: | ||||
| 	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | ||||
| 	@echo "Running LaTeX files through platex and dvipdfmx..." | ||||
| 	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja | ||||
| 	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." | ||||
|  | ||||
| text: | ||||
| 	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text | ||||
| 	@echo | ||||
| 	@echo "Build finished. The text files are in $(BUILDDIR)/text." | ||||
|  | ||||
| man: | ||||
| 	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man | ||||
| 	@echo | ||||
| 	@echo "Build finished. The manual pages are in $(BUILDDIR)/man." | ||||
|  | ||||
| texinfo: | ||||
| 	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | ||||
| 	@echo | ||||
| 	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." | ||||
| 	@echo "Run \`make' in that directory to run these through makeinfo" \ | ||||
| 	      "(use \`make info' here to do that automatically)." | ||||
|  | ||||
| info: | ||||
| 	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | ||||
| 	@echo "Running Texinfo files through makeinfo..." | ||||
| 	make -C $(BUILDDIR)/texinfo info | ||||
| 	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." | ||||
|  | ||||
| gettext: | ||||
| 	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale | ||||
| 	@echo | ||||
| 	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." | ||||
|  | ||||
| changes: | ||||
| 	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes | ||||
| 	@echo | ||||
| 	@echo "The overview file is in $(BUILDDIR)/changes." | ||||
|  | ||||
| linkcheck: | ||||
| 	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck | ||||
| 	@echo | ||||
| 	@echo "Link check complete; look for any errors in the above output " \ | ||||
| 	      "or in $(BUILDDIR)/linkcheck/output.txt." | ||||
|  | ||||
| doctest: | ||||
| 	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest | ||||
| 	@echo "Testing of doctests in the sources finished, look at the " \ | ||||
| 	      "results in $(BUILDDIR)/doctest/output.txt." | ||||
|  | ||||
| xml: | ||||
| 	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml | ||||
| 	@echo | ||||
| 	@echo "Build finished. The XML files are in $(BUILDDIR)/xml." | ||||
|  | ||||
| pseudoxml: | ||||
| 	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml | ||||
| 	@echo | ||||
| 	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." | ||||
							
								
								
									
										325
									
								
								docs/conf.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										325
									
								
								docs/conf.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,325 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| # | ||||
| # django-formtools documentation build configuration file, created by | ||||
| # sphinx-quickstart on Mon Oct  6 21:51:30 2014. | ||||
| # | ||||
| # This file is execfile()d with the current directory set to its containing dir. | ||||
| # | ||||
| # Note that not all possible configuration values are present in this | ||||
| # autogenerated file. | ||||
| # | ||||
| # All configuration values have a default; values that are commented out | ||||
| # serve to show the default. | ||||
|  | ||||
| import sys | ||||
| import os | ||||
|  | ||||
| os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tests.settings') | ||||
|  | ||||
| # If extensions (or modules to document with autodoc) are in another directory, | ||||
| # add these directories to sys.path here. If the directory is relative to the | ||||
| # documentation root, use os.path.abspath to make it absolute, like shown here. | ||||
| sys.path.insert(0, os.path.abspath('extensions')) | ||||
| sys.path.insert(0, os.path.abspath('..')) | ||||
|  | ||||
| # -- General configuration ----------------------------------------------------- | ||||
|  | ||||
| # If your documentation needs a minimal Sphinx version, state it here. | ||||
| #needs_sphinx = '1.0' | ||||
|  | ||||
| # 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', 'sphinx.ext.intersphinx', | ||||
|               'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig', | ||||
|               'sphinx.ext.viewcode', 'settings'] | ||||
|  | ||||
| # Add any paths that contain templates here, relative to this directory. | ||||
| # templates_path = ['_templates'] | ||||
|  | ||||
| # The suffix of source filenames. | ||||
| source_suffix = '.rst' | ||||
|  | ||||
| # The encoding of source files. | ||||
| #source_encoding = 'utf-8-sig' | ||||
|  | ||||
| # The master toctree document. | ||||
| master_doc = 'index' | ||||
|  | ||||
| # General information about the project. | ||||
| project = u'django-formtools' | ||||
| copyright = u'2014, Django Software Foundation and individual contributors' | ||||
|  | ||||
| # The version info for the project you're documenting, acts as replacement for | ||||
| # |version| and |release|, also used in various other places throughout the | ||||
| # built documents. | ||||
| # | ||||
| # The short X.Y version. | ||||
| try: | ||||
|     from formtools import __version__ | ||||
|     # The short X.Y version. | ||||
|     version = '.'.join(__version__.split('.')[:2]) | ||||
|     # The full version, including alpha/beta/rc tags. | ||||
|     release = __version__ | ||||
| except ImportError: | ||||
|     version = release = 'dev' | ||||
|  | ||||
| # The language for content autogenerated by Sphinx. Refer to documentation | ||||
| # for a list of supported languages. | ||||
| #language = None | ||||
|  | ||||
| # 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 patterns, relative to source directory, that match files and | ||||
| # directories to ignore when looking for source files. | ||||
| exclude_patterns = ['_build'] | ||||
|  | ||||
| # 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 = 'sphinx' | ||||
|  | ||||
| # A list of ignored prefixes for module index sorting. | ||||
| #modindex_common_prefix = [] | ||||
|  | ||||
| # If true, keep warnings as "system message" paragraphs in the built documents. | ||||
| #keep_warnings = False | ||||
|  | ||||
|  | ||||
| # -- Options for HTML output --------------------------------------------------- | ||||
|  | ||||
| # The theme to use for HTML and HTML Help pages.  See the documentation for | ||||
| # a list of builtin themes. | ||||
| html_theme = 'default' | ||||
|  | ||||
| # Theme options are theme-specific and customize the look and feel of a theme | ||||
| # further.  For a list of options available for each theme, see the | ||||
| # documentation. | ||||
| #html_theme_options = {} | ||||
|  | ||||
| # Add any paths that contain custom themes here, relative to this directory. | ||||
| #html_theme_path = ['_theme'] | ||||
|  | ||||
| # The name for this set of Sphinx documents.  If None, it defaults to | ||||
| # "<project> v<release> 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 (relative to this directory) 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_domain_indices = 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, links to the reST sources are added to the pages. | ||||
| #html_show_sourcelink = True | ||||
|  | ||||
| # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. | ||||
| #html_show_sphinx = True | ||||
|  | ||||
| # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. | ||||
| #html_show_copyright = True | ||||
|  | ||||
| # If true, an OpenSearch description file will be output, and all pages will | ||||
| # contain a <link> tag referring to it.  The value of this option must be the | ||||
| # base URL from which the finished HTML is served. | ||||
| #html_use_opensearch = '' | ||||
|  | ||||
| # This is the file name suffix for HTML files (e.g. ".xhtml"). | ||||
| #html_file_suffix = None | ||||
|  | ||||
| # Output file base name for HTML help builder. | ||||
| htmlhelp_basename = 'django-formtoolsdoc' | ||||
|  | ||||
|  | ||||
| # -- Options for LaTeX output -------------------------------------------------- | ||||
|  | ||||
| latex_elements = { | ||||
| # The paper size ('letterpaper' or 'a4paper'). | ||||
| #'papersize': 'letterpaper', | ||||
|  | ||||
| # The font size ('10pt', '11pt' or '12pt'). | ||||
| #'pointsize': '10pt', | ||||
|  | ||||
| # Additional stuff for the LaTeX preamble. | ||||
| #'preamble': '', | ||||
| } | ||||
|  | ||||
| # Grouping the document tree into LaTeX files. List of tuples | ||||
| # (source start file, target name, title, author, documentclass [howto/manual]). | ||||
| latex_documents = [ | ||||
|   ('index', 'django-formtools.tex', u'django-formtools Documentation', | ||||
|    u'Django Software Foundation and individual contributors', '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 | ||||
|  | ||||
| # If true, show page references after internal links. | ||||
| #latex_show_pagerefs = False | ||||
|  | ||||
| # If true, show URL addresses after external links. | ||||
| #latex_show_urls = False | ||||
|  | ||||
| # Documents to append as an appendix to all manuals. | ||||
| #latex_appendices = [] | ||||
|  | ||||
| # If false, no module index is generated. | ||||
| #latex_domain_indices = True | ||||
|  | ||||
|  | ||||
| # -- Options for manual page output -------------------------------------------- | ||||
|  | ||||
| # One entry per manual page. List of tuples | ||||
| # (source start file, name, description, authors, manual section). | ||||
| man_pages = [ | ||||
|     ('index', 'django-formtools', u'django-formtools Documentation', | ||||
|      [u'Django Software Foundation and individual contributors'], 1) | ||||
| ] | ||||
|  | ||||
| # If true, show URL addresses after external links. | ||||
| #man_show_urls = False | ||||
|  | ||||
|  | ||||
| # -- Options for Texinfo output ------------------------------------------------ | ||||
|  | ||||
| # Grouping the document tree into Texinfo files. List of tuples | ||||
| # (source start file, target name, title, author, | ||||
| #  dir menu entry, description, category) | ||||
| texinfo_documents = [ | ||||
|   ('index', 'django-formtools', u'django-formtools Documentation', | ||||
|    u'Django Software Foundation and individual contributors', 'django-formtools', 'One line description of project.', | ||||
|    'Miscellaneous'), | ||||
| ] | ||||
|  | ||||
| # Documents to append as an appendix to all manuals. | ||||
| #texinfo_appendices = [] | ||||
|  | ||||
| # If false, no module index is generated. | ||||
| #texinfo_domain_indices = True | ||||
|  | ||||
| # How to display URL addresses: 'footnote', 'no', or 'inline'. | ||||
| #texinfo_show_urls = 'footnote' | ||||
|  | ||||
| # If true, do not generate a @detailmenu in the "Top" node's menu. | ||||
| #texinfo_no_detailmenu = False | ||||
|  | ||||
|  | ||||
| # -- Options for Epub output --------------------------------------------------- | ||||
|  | ||||
| # Bibliographic Dublin Core info. | ||||
| epub_title = u'django-formtools' | ||||
| epub_author = u'Django Software Foundation and individual contributors' | ||||
| epub_publisher = u'Django Software Foundation and individual contributors' | ||||
| epub_copyright = u'2014, Django Software Foundation and individual contributors' | ||||
|  | ||||
| # The language of the text. It defaults to the language option | ||||
| # or en if the language is not set. | ||||
| #epub_language = '' | ||||
|  | ||||
| # The scheme of the identifier. Typical schemes are ISBN or URL. | ||||
| #epub_scheme = '' | ||||
|  | ||||
| # The unique identifier of the text. This can be a ISBN number | ||||
| # or the project homepage. | ||||
| #epub_identifier = '' | ||||
|  | ||||
| # A unique identification for the text. | ||||
| #epub_uid = '' | ||||
|  | ||||
| # A tuple containing the cover image and cover page html template filenames. | ||||
| #epub_cover = () | ||||
|  | ||||
| # A sequence of (type, uri, title) tuples for the guide element of content.opf. | ||||
| #epub_guide = () | ||||
|  | ||||
| # HTML files that should be inserted before the pages created by sphinx. | ||||
| # The format is a list of tuples containing the path and title. | ||||
| #epub_pre_files = [] | ||||
|  | ||||
| # HTML files shat should be inserted after the pages created by sphinx. | ||||
| # The format is a list of tuples containing the path and title. | ||||
| #epub_post_files = [] | ||||
|  | ||||
| # A list of files that should not be packed into the epub file. | ||||
| #epub_exclude_files = [] | ||||
|  | ||||
| # The depth of the table of contents in toc.ncx. | ||||
| #epub_tocdepth = 3 | ||||
|  | ||||
| # Allow duplicate toc entries. | ||||
| #epub_tocdup = True | ||||
|  | ||||
| # Fix unsupported image types using the PIL. | ||||
| #epub_fix_images = False | ||||
|  | ||||
| # Scale large images. | ||||
| #epub_max_image_width = 0 | ||||
|  | ||||
| # If 'no', URL addresses will not be shown. | ||||
| #epub_show_urls = 'inline' | ||||
|  | ||||
| # If false, no index is generated. | ||||
| #epub_use_index = True | ||||
|  | ||||
|  | ||||
| # Example configuration for intersphinx: refer to the Python standard library. | ||||
| intersphinx_mapping = { | ||||
|     'http://docs.python.org/': None, | ||||
|     'django': ('http://docs.djangoproject.com/en/dev/', | ||||
|                'http://docs.djangoproject.com/en/dev/_objects/'), | ||||
| } | ||||
							
								
								
									
										0
									
								
								docs/extensions/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								docs/extensions/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										6
									
								
								docs/extensions/settings.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								docs/extensions/settings.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| def setup(app): | ||||
|     app.add_crossref_type( | ||||
|         directivename="setting", | ||||
|         rolename="setting", | ||||
|         indextemplate="pair: %s; setting", | ||||
|     ) | ||||
							
								
								
									
										112
									
								
								docs/index.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								docs/index.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| ==================== | ||||
| The "form tools" app | ||||
| ==================== | ||||
|  | ||||
| .. module:: formtools | ||||
|     :synopsis: A set of high-level abstractions for Django forms | ||||
|                (:mod:`django.forms`).. | ||||
|  | ||||
| django-formtools is a collection of assorted utilities that are useful for | ||||
| specific form use cases. | ||||
|  | ||||
| Currently there are two tools: a helper for form previews and a form wizard | ||||
| view. | ||||
|  | ||||
| .. toctree:: | ||||
|  | ||||
|    preview | ||||
|    wizard | ||||
|  | ||||
| Installation | ||||
| ============ | ||||
|  | ||||
| To install django-formtools use your favorite packaging tool, e.g.pip:: | ||||
|  | ||||
|     pip install django-formtools | ||||
|  | ||||
| Or download the source distribution from PyPI_ at | ||||
| https://pypi.python.org/pypi/django-formtools, decompress the file and | ||||
| run ``python setup.py install`` in the unpacked directory. | ||||
|  | ||||
| Then add ``'formtools'`` to your :setting:`INSTALLED_APPS` setting:: | ||||
|  | ||||
|     INSTALLED_APPS = ( | ||||
|         # ... | ||||
|         'formtools', | ||||
|     ) | ||||
|  | ||||
| .. note:: | ||||
|  | ||||
|   Adding ``'formtools'`` to your ``INSTALLED_APPS`` setting is required | ||||
|   for translations and templates to work. Using django-formtools without | ||||
|   adding it to your ``INSTALLED_APPS`` setting is not recommended. | ||||
|  | ||||
| .. _PyPI: https://pypi.python.org/ | ||||
|  | ||||
| Internationalization | ||||
| ==================== | ||||
|  | ||||
| Formtools has its own catalog of translations, in the directory | ||||
| ``formtools/locale``, and it's not loaded automatically like Django's | ||||
| general catalog in ``django/conf/locale``. If you want formtools's | ||||
| texts to be translated, like the templates, you must include | ||||
| :mod:`formtools` in the :setting:`INSTALLED_APPS` setting, so | ||||
| the internationalization system can find the catalog, as explained in | ||||
| :ref:`django:how-django-discovers-translations`. | ||||
|  | ||||
| Contributing tools | ||||
| ================== | ||||
|  | ||||
| We'd love to add more of these, so please `create a ticket`_ with | ||||
| any code you'd like to contribute. One thing we ask is that you please use | ||||
| Unicode objects (``u'mystring'``) for strings, rather than setting the encoding | ||||
| in the file. See any of the existing flavors for examples. | ||||
|  | ||||
| See the `contributing documentation`_ for how to run the tests while working on a | ||||
| local flavor. | ||||
|  | ||||
| .. _create a ticket: https://github.com/django/django-formtools/issues | ||||
| .. _contributing documentation: https://github.com/django/django-formtools/blob/master/CONTRIBUTING.rst | ||||
|  | ||||
| Releases | ||||
| ======== | ||||
|  | ||||
| Due to django-formtools' history as a former contrib app, the app is | ||||
| required to be working with the actively maintained Django versions. See | ||||
| the documenation about `Django's release process`_ for more information. | ||||
|  | ||||
| django-formtools releases are not tied to the release cycle of Django. | ||||
| Version numbers follow the appropriate Python standards, e.g. PEPs 386_ and 440_. | ||||
|  | ||||
| .. _386: http://www.python.org/dev/peps/pep-0386/ | ||||
| .. _440: http://www.python.org/dev/peps/pep-0440/ | ||||
| .. _`Django's release process`: https://docs.djangoproject.com/en/dev/internals/release-process/ | ||||
|  | ||||
| How to migrate | ||||
| ============== | ||||
|  | ||||
| If you've used the old ``django.contrib.formtools`` package follow these | ||||
| two easy steps to update your code: | ||||
|  | ||||
| 1. Install the third-party ``django-formtools`` package. | ||||
|  | ||||
| 2. Change your app's import statements to reference the new packages. | ||||
|  | ||||
|    For example, change this:: | ||||
|  | ||||
|        from django.contrib.formtools.wizard.views import WizardView | ||||
|  | ||||
|    ...to this:: | ||||
|  | ||||
|        from formtools.wizard.views import WizardView | ||||
|  | ||||
| The code in the new package is the same (it was copied directly from Django), | ||||
| so you don't have to worry about backwards compatibility in terms of | ||||
| functionality. Only the imports have changed. | ||||
|  | ||||
| Indices and tables | ||||
| ================== | ||||
|  | ||||
| * :ref:`genindex` | ||||
| * :ref:`modindex` | ||||
| * :ref:`search` | ||||
							
								
								
									
										242
									
								
								docs/make.bat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								docs/make.bat
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,242 @@ | ||||
| @ECHO OFF | ||||
|  | ||||
| REM Command file for Sphinx documentation | ||||
|  | ||||
| if "%SPHINXBUILD%" == "" ( | ||||
| 	set SPHINXBUILD=sphinx-build | ||||
| ) | ||||
| set BUILDDIR=_build | ||||
| set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . | ||||
| set I18NSPHINXOPTS=%SPHINXOPTS% . | ||||
| if NOT "%PAPER%" == "" ( | ||||
| 	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% | ||||
| 	set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% | ||||
| ) | ||||
|  | ||||
| if "%1" == "" goto help | ||||
|  | ||||
| if "%1" == "help" ( | ||||
| 	:help | ||||
| 	echo.Please use `make ^<target^>` where ^<target^> is one of | ||||
| 	echo.  html       to make standalone HTML files | ||||
| 	echo.  dirhtml    to make HTML files named index.html in directories | ||||
| 	echo.  singlehtml to make a single large HTML file | ||||
| 	echo.  pickle     to make pickle files | ||||
| 	echo.  json       to make JSON files | ||||
| 	echo.  htmlhelp   to make HTML files and a HTML help project | ||||
| 	echo.  qthelp     to make HTML files and a qthelp project | ||||
| 	echo.  devhelp    to make HTML files and a Devhelp project | ||||
| 	echo.  epub       to make an epub | ||||
| 	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter | ||||
| 	echo.  text       to make text files | ||||
| 	echo.  man        to make manual pages | ||||
| 	echo.  texinfo    to make Texinfo files | ||||
| 	echo.  gettext    to make PO message catalogs | ||||
| 	echo.  changes    to make an overview over all changed/added/deprecated items | ||||
| 	echo.  xml        to make Docutils-native XML files | ||||
| 	echo.  pseudoxml  to make pseudoxml-XML files for display purposes | ||||
| 	echo.  linkcheck  to check all external links for integrity | ||||
| 	echo.  doctest    to run all doctests embedded in the documentation if enabled | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "clean" ( | ||||
| 	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i | ||||
| 	del /q /s %BUILDDIR%\* | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
|  | ||||
| %SPHINXBUILD% 2> nul | ||||
| if errorlevel 9009 ( | ||||
| 	echo. | ||||
| 	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx | ||||
| 	echo.installed, then set the SPHINXBUILD environment variable to point | ||||
| 	echo.to the full path of the 'sphinx-build' executable. Alternatively you | ||||
| 	echo.may add the Sphinx directory to PATH. | ||||
| 	echo. | ||||
| 	echo.If you don't have Sphinx installed, grab it from | ||||
| 	echo.http://sphinx-doc.org/ | ||||
| 	exit /b 1 | ||||
| ) | ||||
|  | ||||
| if "%1" == "html" ( | ||||
| 	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The HTML pages are in %BUILDDIR%/html. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "dirhtml" ( | ||||
| 	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "singlehtml" ( | ||||
| 	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "pickle" ( | ||||
| 	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished; now you can process the pickle files. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "json" ( | ||||
| 	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished; now you can process the JSON files. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "htmlhelp" ( | ||||
| 	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished; now you can run HTML Help Workshop with the ^ | ||||
| .hhp project file in %BUILDDIR%/htmlhelp. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "qthelp" ( | ||||
| 	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished; now you can run "qcollectiongenerator" with the ^ | ||||
| .qhcp project file in %BUILDDIR%/qthelp, like this: | ||||
| 	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-formtools.qhcp | ||||
| 	echo.To view the help file: | ||||
| 	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-formtools.ghc | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "devhelp" ( | ||||
| 	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "epub" ( | ||||
| 	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The epub file is in %BUILDDIR%/epub. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "latex" ( | ||||
| 	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "latexpdf" ( | ||||
| 	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | ||||
| 	cd %BUILDDIR%/latex | ||||
| 	make all-pdf | ||||
| 	cd %BUILDDIR%/.. | ||||
| 	echo. | ||||
| 	echo.Build finished; the PDF files are in %BUILDDIR%/latex. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "latexpdfja" ( | ||||
| 	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | ||||
| 	cd %BUILDDIR%/latex | ||||
| 	make all-pdf-ja | ||||
| 	cd %BUILDDIR%/.. | ||||
| 	echo. | ||||
| 	echo.Build finished; the PDF files are in %BUILDDIR%/latex. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "text" ( | ||||
| 	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The text files are in %BUILDDIR%/text. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "man" ( | ||||
| 	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The manual pages are in %BUILDDIR%/man. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "texinfo" ( | ||||
| 	%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "gettext" ( | ||||
| 	%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The message catalogs are in %BUILDDIR%/locale. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "changes" ( | ||||
| 	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.The overview file is in %BUILDDIR%/changes. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "linkcheck" ( | ||||
| 	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Link check complete; look for any errors in the above output ^ | ||||
| or in %BUILDDIR%/linkcheck/output.txt. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "doctest" ( | ||||
| 	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Testing of doctests in the sources finished, look at the ^ | ||||
| results in %BUILDDIR%/doctest/output.txt. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "xml" ( | ||||
| 	%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The XML files are in %BUILDDIR%/xml. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| if "%1" == "pseudoxml" ( | ||||
| 	%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml | ||||
| 	if errorlevel 1 exit /b 1 | ||||
| 	echo. | ||||
| 	echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. | ||||
| 	goto end | ||||
| ) | ||||
|  | ||||
| :end | ||||
							
								
								
									
										120
									
								
								docs/preview.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								docs/preview.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,120 @@ | ||||
| ============ | ||||
| Form preview | ||||
| ============ | ||||
|  | ||||
| .. module:: formtools.preview | ||||
|     :synopsis: Displays an HTML form, forces a preview, then does something | ||||
|                with the submission. | ||||
|  | ||||
| Django comes with an optional "form preview" application that helps automate | ||||
| the following workflow: | ||||
|  | ||||
| "Display an HTML form, force a preview, then do something with the submission." | ||||
|  | ||||
| To force a preview of a form submission, all you have to do is write a short | ||||
| Python class. | ||||
|  | ||||
| Overview | ||||
| ========= | ||||
|  | ||||
| Given a :class:`django.forms.Form` subclass that you define, this | ||||
| application takes care of the following workflow: | ||||
|  | ||||
| 1. Displays the form as HTML on a Web page. | ||||
| 2. Validates the form data when it's submitted via POST. | ||||
|    a. If it's valid, displays a preview page. | ||||
|    b. If it's not valid, redisplays the form with error messages. | ||||
| 3. When the "confirmation" form is submitted from the preview page, calls | ||||
|    a hook that you define -- a ``done()`` method that gets passed the valid | ||||
|    data. | ||||
|  | ||||
| The framework enforces the required preview by passing a shared-secret hash to | ||||
| the preview page via hidden form fields. If somebody tweaks the form parameters | ||||
| on the preview page, the form submission will fail the hash-comparison test. | ||||
|  | ||||
| How to use ``FormPreview`` | ||||
| ========================== | ||||
|  | ||||
| 1. Point Django at the default FormPreview templates. There are two ways to | ||||
|    do this: | ||||
|  | ||||
|    * Add ``'formtools'`` to your | ||||
|      :setting:`INSTALLED_APPS` setting. This will work if your | ||||
|      :setting:`TEMPLATE_LOADERS` setting includes the | ||||
|      ``app_directories`` template loader (which is the case by | ||||
|      default). See the :ref:`template loader docs <template-loaders>` | ||||
|      for more. | ||||
|  | ||||
|    * Otherwise, determine the full filesystem path to the | ||||
|      :file:`django/contrib/formtools/templates` directory, and add that | ||||
|      directory to your :setting:`TEMPLATE_DIRS` setting. | ||||
|  | ||||
| 2. Create a :class:`~formtools.preview.FormPreview` subclass that | ||||
|    overrides the ``done()`` method:: | ||||
|  | ||||
|        from django.http import HttpResponseRedirect | ||||
|        from formtools.preview import FormPreview | ||||
|        from myapp.models import SomeModel | ||||
|  | ||||
|        class SomeModelFormPreview(FormPreview): | ||||
|  | ||||
|            def done(self, request, cleaned_data): | ||||
|                # Do something with the cleaned_data, then redirect | ||||
|                # to a "success" page. | ||||
|                return HttpResponseRedirect('/form/success') | ||||
|  | ||||
|    This method takes an :class:`~django.http.HttpRequest` object and a | ||||
|    dictionary of the form data after it has been validated and cleaned. | ||||
|    It should return an :class:`~django.http.HttpResponseRedirect` that | ||||
|    is the end result of the form being submitted. | ||||
|  | ||||
| 3. Change your URLconf to point to an instance of your | ||||
|    :class:`~formtools.preview.FormPreview` subclass:: | ||||
|  | ||||
|        from myapp.preview import SomeModelFormPreview | ||||
|        from myapp.forms import SomeModelForm | ||||
|        from django import forms | ||||
|  | ||||
|    ...and add the following line to the appropriate model in your URLconf:: | ||||
|  | ||||
|        url(r'^post/$', SomeModelFormPreview(SomeModelForm)), | ||||
|  | ||||
|    where ``SomeModelForm`` is a Form or ModelForm class for the model. | ||||
|  | ||||
| 4. Run the Django server and visit :file:`/post/` in your browser. | ||||
|  | ||||
| ``FormPreview`` classes | ||||
| ======================= | ||||
|  | ||||
| .. class:: FormPreview | ||||
|  | ||||
| A :class:`~formtools.preview.FormPreview` class is a simple Python class | ||||
| that represents the preview workflow. | ||||
| :class:`~formtools.preview.FormPreview` classes must subclass | ||||
| ``formtools.preview.FormPreview`` and override the ``done()`` | ||||
| method. They can live anywhere in your codebase. | ||||
|  | ||||
| ``FormPreview`` templates | ||||
| ========================= | ||||
|  | ||||
| .. attribute:: FormPreview.form_template | ||||
| .. attribute:: FormPreview.preview_template | ||||
|  | ||||
| By default, the form is rendered via the template :file:`formtools/form.html`, | ||||
| and the preview page is rendered via the template :file:`formtools/preview.html`. | ||||
| These values can be overridden for a particular form preview by setting | ||||
| :attr:`~formtools.preview.FormPreview.preview_template` and | ||||
| :attr:`~formtools.preview.FormPreview.form_template` attributes on the | ||||
| FormPreview subclass. See :file:`django/contrib/formtools/templates` for the | ||||
| default templates. | ||||
|  | ||||
| Advanced ``FormPreview`` methods | ||||
| ================================ | ||||
|  | ||||
| .. method:: FormPreview.process_preview() | ||||
|  | ||||
|     Given a validated form, performs any extra processing before displaying the | ||||
|     preview page, and saves any extra data in context. | ||||
|  | ||||
|     By default, this method is empty.  It is called after the form is validated, | ||||
|     but before the context is modified with hash information and rendered. | ||||
							
								
								
									
										1
									
								
								docs/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| Django | ||||
							
								
								
									
										761
									
								
								docs/wizard.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										761
									
								
								docs/wizard.rst
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,761 @@ | ||||
| =========== | ||||
| Form wizard | ||||
| =========== | ||||
|  | ||||
| .. module:: formtools.wizard.views | ||||
|     :synopsis: Splits forms across multiple Web pages. | ||||
|  | ||||
| Django comes with an optional "form wizard" application that splits | ||||
| :mod:`forms <django.forms>` across multiple Web pages. It maintains | ||||
| state in one of the backends so that the full server-side processing can be | ||||
| delayed until the submission of the final form. | ||||
|  | ||||
| You might want to use this if you have a lengthy form that would be too | ||||
| unwieldy for display on a single page. The first page might ask the user for | ||||
| core information, the second page might ask for less important information, | ||||
| etc. | ||||
|  | ||||
| The term "wizard", in this context, is `explained on Wikipedia`_. | ||||
|  | ||||
| .. _explained on Wikipedia: http://en.wikipedia.org/wiki/Wizard_%28software%29 | ||||
|  | ||||
| How it works | ||||
| ============ | ||||
|  | ||||
| Here's the basic workflow for how a user would use a wizard: | ||||
|  | ||||
| 1. The user visits the first page of the wizard, fills in the form and | ||||
|    submits it. | ||||
| 2. The server validates the data. If it's invalid, the form is displayed | ||||
|    again, with error messages. If it's valid, the server saves the current | ||||
|    state of the wizard in the backend and redirects to the next step. | ||||
| 3. Step 1 and 2 repeat, for every subsequent form in the wizard. | ||||
| 4. Once the user has submitted all the forms and all the data has been | ||||
|    validated, the wizard processes the data -- saving it to the database, | ||||
|    sending an email, or whatever the application needs to do. | ||||
|  | ||||
| Usage | ||||
| ===== | ||||
|  | ||||
| This application handles as much machinery for you as possible. Generally, | ||||
| you just have to do these things: | ||||
|  | ||||
| 1. Define a number of :class:`~django.forms.Form` classes -- one per | ||||
|    wizard page. | ||||
|  | ||||
| 2. Create a :class:`WizardView` subclass that specifies what to do once | ||||
|    all of your forms have been submitted and validated. This also lets | ||||
|    you override some of the wizard's behavior. | ||||
|  | ||||
| 3. Create some templates that render the forms. You can define a single, | ||||
|    generic template to handle every one of the forms, or you can define a | ||||
|    specific template for each form. | ||||
|  | ||||
| 4. Add ``formtools`` to your :setting:`INSTALLED_APPS` list in your settings | ||||
|    file. | ||||
|  | ||||
| 5. Point your URLconf at your :class:`WizardView` :meth:`~WizardView.as_view` | ||||
|    method. | ||||
|  | ||||
| Defining ``Form`` classes | ||||
| ------------------------- | ||||
|  | ||||
| The first step in creating a form wizard is to create the | ||||
| :class:`~django.forms.Form` classes.  These should be standard | ||||
| :class:`django.forms.Form` classes, covered in the :mod:`forms documentation | ||||
| <django.forms>`.  These classes can live anywhere in your codebase, | ||||
| but convention is to put them in a file called :file:`forms.py` in your | ||||
| application. | ||||
|  | ||||
| For example, let's write a "contact form" wizard, where the first page's form | ||||
| collects the sender's email address and subject, and the second page collects | ||||
| the message itself. Here's what the :file:`forms.py` might look like:: | ||||
|  | ||||
|     from django import forms | ||||
|  | ||||
|     class ContactForm1(forms.Form): | ||||
|         subject = forms.CharField(max_length=100) | ||||
|         sender = forms.EmailField() | ||||
|  | ||||
|     class ContactForm2(forms.Form): | ||||
|         message = forms.CharField(widget=forms.Textarea) | ||||
|  | ||||
|  | ||||
| .. note:: | ||||
|  | ||||
|     In order to use :class:`~django.forms.FileField` in any form, see the | ||||
|     section :ref:`Handling files <wizard-files>` below to learn more about | ||||
|     what to do. | ||||
|  | ||||
| Creating a ``WizardView`` subclass | ||||
| ---------------------------------- | ||||
|  | ||||
| .. class:: SessionWizardView | ||||
| .. class:: CookieWizardView | ||||
|  | ||||
| The next step is to create a :class:`formtools.wizard.views.WizardView` | ||||
| subclass. You can also use the :class:`SessionWizardView` or | ||||
| :class:`CookieWizardView` classes which preselect the backend used for | ||||
| storing information during execution of the wizard (as their names indicate, | ||||
| server-side sessions and browser cookies respectively). | ||||
|  | ||||
| .. note:: | ||||
|  | ||||
|     To use the :class:`SessionWizardView` follow the instructions | ||||
|     in the :mod:`sessions documentation <django.contrib.sessions>` on | ||||
|     how to enable sessions. | ||||
|  | ||||
| We will use the :class:`SessionWizardView` in all examples but is completely | ||||
| fine to use the :class:`CookieWizardView` instead. As with your | ||||
| :class:`~django.forms.Form` classes, this :class:`WizardView` class can live | ||||
| anywhere in your codebase, but convention is to put it in :file:`views.py`. | ||||
|  | ||||
| The only requirement on this subclass is that it implement a | ||||
| :meth:`~WizardView.done()` method. | ||||
|  | ||||
| .. method:: WizardView.done(form_list, form_dict, **kwargs) | ||||
|  | ||||
|     This method specifies what should happen when the data for *every* form is | ||||
|     submitted and validated. This method is passed a list and dictionary of | ||||
|     validated :class:`~django.forms.Form` instances. | ||||
|  | ||||
|     In this simplistic example, rather than performing any database operation, | ||||
|     the method simply renders a template of the validated data:: | ||||
|  | ||||
|         from django.shortcuts import render_to_response | ||||
|         from formtools.wizard.views import SessionWizardView | ||||
|  | ||||
|         class ContactWizard(SessionWizardView): | ||||
|             def done(self, form_list, **kwargs): | ||||
|                 return render_to_response('done.html', { | ||||
|                     'form_data': [form.cleaned_data for form in form_list], | ||||
|                 }) | ||||
|  | ||||
|     Note that this method will be called via ``POST``, so it really ought to be a | ||||
|     good Web citizen and redirect after processing the data. Here's another | ||||
|     example:: | ||||
|  | ||||
|         from django.http import HttpResponseRedirect | ||||
|         from formtools.wizard.views import SessionWizardView | ||||
|  | ||||
|         class ContactWizard(SessionWizardView): | ||||
|             def done(self, form_list, **kwargs): | ||||
|                 do_something_with_the_form_data(form_list) | ||||
|                 return HttpResponseRedirect('/page-to-redirect-to-when-done/') | ||||
|  | ||||
|     In addition to ``form_list``, the :meth:`~WizardView.done` method | ||||
|     is passed a ``form_dict``, which allows you to access the wizard's | ||||
|     forms based on their step names. This is especially useful when using | ||||
|     :class:`NamedUrlWizardView`, for example:: | ||||
|  | ||||
|         def done(self, form_list, form_dict, **kwargs): | ||||
|             user = form_dict['user'].save() | ||||
|             credit_card = form_dict['credit_card'].save() | ||||
|             # ... | ||||
|  | ||||
|     .. versionchanged:: 1.7 | ||||
|  | ||||
|         Previously, the ``form_dict`` argument wasn't passed to the | ||||
|         ``done`` method. | ||||
|  | ||||
| See the section :ref:`Advanced WizardView methods <wizardview-advanced-methods>` | ||||
| below to learn about more :class:`WizardView` hooks. | ||||
|  | ||||
| Creating templates for the forms | ||||
| -------------------------------- | ||||
|  | ||||
| Next, you'll need to create a template that renders the wizard's forms. By | ||||
| default, every form uses a template called | ||||
| :file:`formtools/wizard/wizard_form.html`. You can change this template name | ||||
| by overriding either the | ||||
| :attr:`~django.views.generic.base.TemplateResponseMixin.template_name` attribute | ||||
| or the | ||||
| :meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()` | ||||
| method, which are documented in the | ||||
| :class:`~django.views.generic.base.TemplateResponseMixin` documentation.  The | ||||
| latter one allows you to use a different template for each form (:ref:`see the | ||||
| example below <wizard-template-for-each-form>`). | ||||
|  | ||||
| This template expects a ``wizard`` object that has various items attached to | ||||
| it: | ||||
|  | ||||
| * ``form`` -- The :class:`~django.forms.Form` or | ||||
|   :class:`~django.forms.formsets.BaseFormSet` instance for the current step | ||||
|   (either empty or with errors). | ||||
|  | ||||
| * ``steps`` -- A helper object to access the various steps related data: | ||||
|  | ||||
|   * ``step0`` -- The current step (zero-based). | ||||
|   * ``step1`` -- The current step (one-based). | ||||
|   * ``count`` -- The total number of steps. | ||||
|   * ``first`` -- The first step. | ||||
|   * ``last`` -- The last step. | ||||
|   * ``current`` -- The current (or first) step. | ||||
|   * ``next`` -- The next step. | ||||
|   * ``prev`` -- The previous step. | ||||
|   * ``index`` -- The index of the current step. | ||||
|   * ``all`` -- A list of all steps of the wizard. | ||||
|  | ||||
| You can supply additional context variables by using the | ||||
| :meth:`~WizardView.get_context_data` method of your :class:`WizardView` | ||||
| subclass. | ||||
|  | ||||
| Here's a full example template: | ||||
|  | ||||
| .. code-block:: html+django | ||||
|  | ||||
|     {% extends "base.html" %} | ||||
|     {% load i18n %} | ||||
|  | ||||
|     {% block head %} | ||||
|     {{ wizard.form.media }} | ||||
|     {% endblock %} | ||||
|  | ||||
|     {% block content %} | ||||
|     <p>Step {{ wizard.steps.step1 }} of {{ wizard.steps.count }}</p> | ||||
|     <form action="" method="post">{% csrf_token %} | ||||
|     <table> | ||||
|     {{ wizard.management_form }} | ||||
|     {% if wizard.form.forms %} | ||||
|         {{ wizard.form.management_form }} | ||||
|         {% for form in wizard.form.forms %} | ||||
|             {{ form }} | ||||
|         {% endfor %} | ||||
|     {% else %} | ||||
|         {{ wizard.form }} | ||||
|     {% endif %} | ||||
|     </table> | ||||
|     {% if wizard.steps.prev %} | ||||
|     <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.first }}">{% trans "first step" %}</button> | ||||
|     <button name="wizard_goto_step" type="submit" value="{{ wizard.steps.prev }}">{% trans "prev step" %}</button> | ||||
|     {% endif %} | ||||
|     <input type="submit" value="{% trans "submit" %}"/> | ||||
|     </form> | ||||
|     {% endblock %} | ||||
|  | ||||
| .. note:: | ||||
|  | ||||
|     Note that ``{{ wizard.management_form }}`` **must be used** for | ||||
|     the wizard to work properly. | ||||
|  | ||||
| .. _wizard-urlconf: | ||||
|  | ||||
| Hooking the wizard into a URLconf | ||||
| --------------------------------- | ||||
|  | ||||
| .. method:: WizardView.as_view() | ||||
|  | ||||
| Finally, we need to specify which forms to use in the wizard, and then | ||||
| deploy the new :class:`WizardView` object at a URL in the ``urls.py``. The | ||||
| wizard's ``as_view()`` method takes a list of your | ||||
| :class:`~django.forms.Form` classes as an argument during instantiation:: | ||||
|  | ||||
|     from django.conf.urls import url | ||||
|  | ||||
|     from myapp.forms import ContactForm1, ContactForm2 | ||||
|     from myapp.views import ContactWizard | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         url(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])), | ||||
|     ] | ||||
|  | ||||
| You can also pass the form list as a class attribute named ``form_list``:: | ||||
|  | ||||
|     class ContactWizard(WizardView): | ||||
|         form_list = [ContactForm1, ContactForm2] | ||||
|  | ||||
| .. _wizard-template-for-each-form: | ||||
|  | ||||
| Using a different template for each form | ||||
| ---------------------------------------- | ||||
|  | ||||
| As mentioned above, you may specify a different template for each form. | ||||
| Consider an example using a form wizard to implement a multi-step checkout | ||||
| process for an online store. In the first step, the user specifies a billing | ||||
| and shipping address. In the second step, the user chooses payment type. If | ||||
| they chose to pay by credit card, they will enter credit card information in | ||||
| the next step. In the final step, they will confirm the purchase. | ||||
|  | ||||
| Here's what the view code might look like:: | ||||
|  | ||||
|     from django.http import HttpResponseRedirect | ||||
|     from formtools.wizard.views import SessionWizardView | ||||
|  | ||||
|     FORMS = [("address", myapp.forms.AddressForm), | ||||
|              ("paytype", myapp.forms.PaymentChoiceForm), | ||||
|              ("cc", myapp.forms.CreditCardForm), | ||||
|              ("confirmation", myapp.forms.OrderForm)] | ||||
|  | ||||
|     TEMPLATES = {"address": "checkout/billingaddress.html", | ||||
|                  "paytype": "checkout/paymentmethod.html", | ||||
|                  "cc": "checkout/creditcard.html", | ||||
|                  "confirmation": "checkout/confirmation.html"} | ||||
|  | ||||
|     def pay_by_credit_card(wizard): | ||||
|         """Return true if user opts to pay by credit card""" | ||||
|         # Get cleaned data from payment step | ||||
|         cleaned_data = wizard.get_cleaned_data_for_step('paytype') or {'method': 'none'} | ||||
|         # Return true if the user selected credit card | ||||
|         return cleaned_data['method'] == 'cc' | ||||
|  | ||||
|  | ||||
|     class OrderWizard(SessionWizardView): | ||||
|         def get_template_names(self): | ||||
|             return [TEMPLATES[self.steps.current]] | ||||
|  | ||||
|         def done(self, form_list, **kwargs): | ||||
|             do_something_with_the_form_data(form_list) | ||||
|             return HttpResponseRedirect('/page-to-redirect-to-when-done/') | ||||
|             ... | ||||
|  | ||||
| The ``urls.py`` file would contain something like:: | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         url(r'^checkout/$', OrderWizard.as_view(FORMS, condition_dict={'cc': pay_by_credit_card})), | ||||
|     ] | ||||
|  | ||||
| The ``condition_dict`` can be passed as attribute for the ``as_view()` | ||||
| method or as a class attribute named ``condition_dict``:: | ||||
|  | ||||
|     class OrderWizard(WizardView): | ||||
|         condition_dict = {'cc': pay_by_credit_card} | ||||
|  | ||||
| Note that the ``OrderWizard`` object is initialized with a list of pairs. | ||||
| The first element in the pair is a string that corresponds to the name of the | ||||
| step and the second is the form class. | ||||
|  | ||||
| In this example, the | ||||
| :meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()` | ||||
| method returns a list containing a single template, which is selected based on | ||||
| the name of the current step. | ||||
|  | ||||
| .. _wizardview-advanced-methods: | ||||
|  | ||||
| Advanced ``WizardView`` methods | ||||
| =============================== | ||||
|  | ||||
| .. class:: WizardView | ||||
|  | ||||
|     Aside from the :meth:`~done()` method, :class:`WizardView` offers a few | ||||
|     advanced method hooks that let you customize how your wizard works. | ||||
|  | ||||
|     Some of these methods take an argument ``step``, which is a zero-based | ||||
|     counter as string representing the current step of the wizard. (E.g., the | ||||
|     first form is ``'0'`` and the second form is ``'1'``) | ||||
|  | ||||
| .. method:: WizardView.get_form_prefix(step=None, form=None) | ||||
|  | ||||
|     Returns the prefix which will be used when calling the form for the given | ||||
|     step. ``step`` contains the step name, ``form`` the form class which will | ||||
|     be called with the returned prefix. | ||||
|  | ||||
|     If no ``step`` is given, it will be determined automatically. By default, | ||||
|     this simply uses the step itself and the ``form`` parameter is not used. | ||||
|  | ||||
|     For more, see the :ref:`form prefix documentation <form-prefix>`. | ||||
|  | ||||
| .. method:: WizardView.get_form_initial(step) | ||||
|  | ||||
|     Returns a dictionary which will be passed as the | ||||
|     :attr:`~django.forms.Form.initial` argument when instantiating the Form | ||||
|     instance for step ``step``. If no initial data was provided while | ||||
|     initializing the form wizard, an empty dictionary should be returned. | ||||
|  | ||||
|     The default implementation:: | ||||
|  | ||||
|         def get_form_initial(self, step): | ||||
|             return self.initial_dict.get(step, {}) | ||||
|  | ||||
| .. method:: WizardView.get_form_kwargs(step) | ||||
|  | ||||
|     Returns a dictionary which will be used as the keyword arguments when | ||||
|     instantiating the form instance on given ``step``. | ||||
|  | ||||
|     The default implementation:: | ||||
|  | ||||
|         def get_form_kwargs(self, step): | ||||
|             return {} | ||||
|  | ||||
| .. method:: WizardView.get_form_instance(step) | ||||
|  | ||||
|     This method will be called only if a :class:`~django.forms.ModelForm` is | ||||
|     used as the form for step ``step``. | ||||
|  | ||||
|     Returns an :class:`~django.db.models.Model` object which will be passed as | ||||
|     the ``instance`` argument when instantiating the ``ModelForm`` for step | ||||
|     ``step``.  If no instance object was provided while initializing the form | ||||
|     wizard, ``None`` will be returned. | ||||
|  | ||||
|     The default implementation:: | ||||
|  | ||||
|         def get_form_instance(self, step): | ||||
|             return self.instance_dict.get(step, None) | ||||
|  | ||||
| .. method:: WizardView.get_context_data(form, **kwargs) | ||||
|  | ||||
|     Returns the template context for a step. You can overwrite this method | ||||
|     to add more data for all or some steps. This method returns a dictionary | ||||
|     containing the rendered form step. | ||||
|  | ||||
|     The default template context variables are: | ||||
|  | ||||
|     * Any extra data the storage backend has stored | ||||
|     * ``wizard`` -- a dictionary representation of the wizard instance with the | ||||
|       following key/values: | ||||
|  | ||||
|       * ``form`` -- :class:`~django.forms.Form` or | ||||
|         :class:`~django.forms.formsets.BaseFormSet` instance for the current step | ||||
|       * ``steps`` -- A helper object to access the various steps related data | ||||
|       * ``management_form`` -- all the management data for the current step | ||||
|  | ||||
|     Example to add extra variables for a specific step:: | ||||
|  | ||||
|         def get_context_data(self, form, **kwargs): | ||||
|             context = super(MyWizard, self).get_context_data(form=form, **kwargs) | ||||
|             if self.steps.current == 'my_step_name': | ||||
|                 context.update({'another_var': True}) | ||||
|             return context | ||||
|  | ||||
| .. method:: WizardView.get_prefix(*args, **kwargs) | ||||
|  | ||||
|     This method returns a prefix for use by the storage backends. Backends use | ||||
|     the prefix as a mechanism to allow data to be stored separately for each | ||||
|     wizard. This allows wizards to store their data in a single backend | ||||
|     without overwriting each other. | ||||
|  | ||||
|     You can change this method to make the wizard data prefix more unique to, | ||||
|     e.g. have multiple instances of one wizard in one session. | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def get_prefix(self, *args, **kwargs): | ||||
|             # use the lowercase underscore version of the class name | ||||
|             return normalize_name(self.__class__.__name__) | ||||
|  | ||||
| .. method:: WizardView.get_form(step=None, data=None, files=None) | ||||
|  | ||||
|     This method constructs the form for a given ``step``. If no ``step`` is | ||||
|     defined, the current step will be determined automatically. If you override | ||||
|     ``get_form``, however, you will need to set ``step`` yourself using | ||||
|     ``self.steps.current`` as in the example below. The method gets three | ||||
|     arguments: | ||||
|  | ||||
|     * ``step`` -- The step for which the form instance should be generated. | ||||
|     * ``data`` -- Gets passed to the form's data argument | ||||
|     * ``files`` -- Gets passed to the form's files argument | ||||
|  | ||||
|     You can override this method to add extra arguments to the form instance. | ||||
|  | ||||
|     Example code to add a user attribute to the form on step 2:: | ||||
|  | ||||
|         def get_form(self, step=None, data=None, files=None): | ||||
|             form = super(MyWizard, self).get_form(step, data, files) | ||||
|  | ||||
|             # determine the step if not given | ||||
|             if step is None: | ||||
|                 step = self.steps.current | ||||
|  | ||||
|             if step == '1': | ||||
|                 form.user = self.request.user | ||||
|             return form | ||||
|  | ||||
| .. method:: WizardView.process_step(form) | ||||
|  | ||||
|     Hook for modifying the wizard's internal state, given a fully validated | ||||
|     :class:`~django.forms.Form` object. The Form is guaranteed to have clean, | ||||
|     valid data. | ||||
|  | ||||
|     This method gives you a way to post-process the form data before the data | ||||
|     gets stored within the storage backend. By default it just returns the | ||||
|     ``form.data`` dictionary. You should not manipulate the data here but you | ||||
|     can use it to do some extra work if needed (e.g. set storage extra data). | ||||
|  | ||||
|     Note that this method is called every time a page is rendered for *all* | ||||
|     submitted steps. | ||||
|  | ||||
|     The default implementation:: | ||||
|  | ||||
|         def process_step(self, form): | ||||
|             return self.get_form_step_data(form) | ||||
|  | ||||
| .. method:: WizardView.process_step_files(form) | ||||
|  | ||||
|     This method gives you a way to post-process the form files before the | ||||
|     files gets stored within the storage backend. By default it just returns | ||||
|     the ``form.files`` dictionary. You should not manipulate the data here | ||||
|     but you can use it to do some extra work if needed (e.g. set storage | ||||
|     extra data). | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def process_step_files(self, form): | ||||
|             return self.get_form_step_files(form) | ||||
|  | ||||
| .. method:: WizardView.render_goto_step(step, goto_step, **kwargs) | ||||
|  | ||||
|     This method is called when the step should be changed to something else | ||||
|     than the next step. By default, this method just stores the requested | ||||
|     step ``goto_step`` in the storage and then renders the new step. | ||||
|  | ||||
|     If you want to store the entered data of the current step before rendering | ||||
|     the next step, you can overwrite this method. | ||||
|  | ||||
| .. method:: WizardView.render_revalidation_failure(step, form, **kwargs) | ||||
|  | ||||
|     When the wizard thinks all steps have passed it revalidates all forms with | ||||
|     the data from the backend storage. | ||||
|  | ||||
|     If any of the forms don't validate correctly, this method gets called. | ||||
|     This method expects two arguments, ``step`` and ``form``. | ||||
|  | ||||
|     The default implementation resets the current step to the first failing | ||||
|     form and redirects the user to the invalid form. | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def render_revalidation_failure(self, step, form, **kwargs): | ||||
|             self.storage.current_step = step | ||||
|             return self.render(form, **kwargs) | ||||
|  | ||||
| .. method:: WizardView.get_form_step_data(form) | ||||
|  | ||||
|     This method fetches the data from the ``form`` Form instance and returns the | ||||
|     dictionary. You can use this method to manipulate the values before the data | ||||
|     gets stored in the storage backend. | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def get_form_step_data(self, form): | ||||
|             return form.data | ||||
|  | ||||
| .. method:: WizardView.get_form_step_files(form) | ||||
|  | ||||
|     This method returns the form files. You can use this method to manipulate | ||||
|     the files before the data gets stored in the storage backend. | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def get_form_step_files(self, form): | ||||
|             return form.files | ||||
|  | ||||
| .. method:: WizardView.render(form, **kwargs) | ||||
|  | ||||
|     This method gets called after the GET or POST request has been handled. You | ||||
|     can hook in this method to, e.g. change the type of HTTP response. | ||||
|  | ||||
|     Default implementation:: | ||||
|  | ||||
|         def render(self, form=None, **kwargs): | ||||
|             form = form or self.get_form() | ||||
|             context = self.get_context_data(form=form, **kwargs) | ||||
|             return self.render_to_response(context) | ||||
|  | ||||
| .. method:: WizardView.get_cleaned_data_for_step(step) | ||||
|  | ||||
|     This method returns the cleaned data for a given ``step``. Before returning | ||||
|     the cleaned data, the stored values are revalidated through the form. If | ||||
|     the data doesn't validate, ``None`` will be returned. | ||||
|  | ||||
| .. method:: WizardView.get_all_cleaned_data() | ||||
|  | ||||
|     This method returns a merged dictionary of all form steps' ``cleaned_data`` | ||||
|     dictionaries. If a step contains a ``FormSet``, the key will be prefixed | ||||
|     with ``formset-`` and contain a list of the formset's ``cleaned_data`` | ||||
|     dictionaries. Note that if two or more steps have a field with the same | ||||
|     name, the value for that field from the latest step will overwrite the | ||||
|     value from any earlier steps. | ||||
|  | ||||
| Providing initial data for the forms | ||||
| ==================================== | ||||
|  | ||||
| .. attribute:: WizardView.initial_dict | ||||
|  | ||||
|     Initial data for a wizard's :class:`~django.forms.Form` objects can be | ||||
|     provided using the optional :attr:`~WizardView.initial_dict` keyword | ||||
|     argument. This argument should be a dictionary mapping the steps to | ||||
|     dictionaries containing the initial data for each step. The dictionary of | ||||
|     initial data will be passed along to the constructor of the step's | ||||
|     :class:`~django.forms.Form`:: | ||||
|  | ||||
|         >>> from myapp.forms import ContactForm1, ContactForm2 | ||||
|         >>> from myapp.views import ContactWizard | ||||
|         >>> initial = { | ||||
|         ...     '0': {'subject': 'Hello', 'sender': 'user@example.com'}, | ||||
|         ...     '1': {'message': 'Hi there!'} | ||||
|         ... } | ||||
|         >>> # This example is illustrative only and isn't meant to be run in | ||||
|         >>> # the shell since it requires an HttpRequest to pass to the view. | ||||
|         >>> wiz = ContactWizard.as_view([ContactForm1, ContactForm2], initial_dict=initial)(request) | ||||
|         >>> form1 = wiz.get_form('0') | ||||
|         >>> form2 = wiz.get_form('1') | ||||
|         >>> form1.initial | ||||
|         {'sender': 'user@example.com', 'subject': 'Hello'} | ||||
|         >>> form2.initial | ||||
|         {'message': 'Hi there!'} | ||||
|  | ||||
|     The ``initial_dict`` can also take a list of dictionaries for a specific | ||||
|     step if the step is a ``FormSet``. | ||||
|  | ||||
|     The ``initial_dict`` can also be added as a class attribute named | ||||
|     ``initial_dict`` to avoid having the initial data in the ``urls.py``. | ||||
|  | ||||
| .. _wizard-files: | ||||
|  | ||||
| Handling files | ||||
| ============== | ||||
|  | ||||
| .. attribute:: WizardView.file_storage | ||||
|  | ||||
| To handle :class:`~django.forms.FileField` within any step form of the wizard, | ||||
| you have to add a ``file_storage`` to your :class:`WizardView` subclass. | ||||
|  | ||||
| This storage will temporarily store the uploaded files for the wizard. The | ||||
| ``file_storage`` attribute should be a | ||||
| :class:`~django.core.files.storage.Storage` subclass. | ||||
|  | ||||
| Django provides a built-in storage class (see :ref:`the built-in filesystem | ||||
| storage class <builtin-fs-storage>`):: | ||||
|  | ||||
|     from django.conf import settings | ||||
|     from django.core.files.storage import FileSystemStorage | ||||
|  | ||||
|     class CustomWizardView(WizardView): | ||||
|         ... | ||||
|         file_storage = FileSystemStorage(location=os.path.join(settings.MEDIA_ROOT, 'photos')) | ||||
|  | ||||
| .. warning:: | ||||
|  | ||||
|     Please remember to take care of removing old temporary files, as the | ||||
|     :class:`WizardView` will only remove these files if the wizard finishes | ||||
|     correctly. | ||||
|  | ||||
| Conditionally view/skip specific steps | ||||
| ====================================== | ||||
|  | ||||
| .. attribute:: WizardView.condition_dict | ||||
|  | ||||
| The :meth:`~WizardView.as_view` method accepts a ``condition_dict`` argument. | ||||
| You can pass a dictionary of boolean values or callables. The key should match | ||||
| the steps names (e.g. '0', '1'). | ||||
|  | ||||
| If the value of a specific step is callable it will be called with the | ||||
| :class:`WizardView` instance as the only argument. If the return value is true, | ||||
| the step's form will be used. | ||||
|  | ||||
| This example provides a contact form including a condition. The condition is | ||||
| used to show a message form only if a checkbox in the first step was checked. | ||||
|  | ||||
| The steps are defined in a ``forms.py`` file:: | ||||
|  | ||||
|     from django import forms | ||||
|  | ||||
|     class ContactForm1(forms.Form): | ||||
|         subject = forms.CharField(max_length=100) | ||||
|         sender = forms.EmailField() | ||||
|         leave_message = forms.BooleanField(required=False) | ||||
|  | ||||
|     class ContactForm2(forms.Form): | ||||
|         message = forms.CharField(widget=forms.Textarea) | ||||
|  | ||||
| We define our wizard in a ``views.py``:: | ||||
|  | ||||
|     from django.shortcuts import render_to_response | ||||
|     from formtools.wizard.views import SessionWizardView | ||||
|  | ||||
|     def show_message_form_condition(wizard): | ||||
|         # try to get the cleaned data of step 1 | ||||
|         cleaned_data = wizard.get_cleaned_data_for_step('0') or {} | ||||
|         # check if the field ``leave_message`` was checked. | ||||
|         return cleaned_data.get('leave_message', True) | ||||
|  | ||||
|     class ContactWizard(SessionWizardView): | ||||
|  | ||||
|         def done(self, form_list, **kwargs): | ||||
|             return render_to_response('done.html', { | ||||
|                 'form_data': [form.cleaned_data for form in form_list], | ||||
|             }) | ||||
|  | ||||
| We need to add the ``ContactWizard`` to our ``urls.py`` file:: | ||||
|  | ||||
|     from django.conf.urls import url | ||||
|  | ||||
|     from myapp.forms import ContactForm1, ContactForm2 | ||||
|     from myapp.views import ContactWizard, show_message_form_condition | ||||
|  | ||||
|     contact_forms = [ContactForm1, ContactForm2] | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         url(r'^contact/$', ContactWizard.as_view(contact_forms, | ||||
|             condition_dict={'1': show_message_form_condition} | ||||
|         )), | ||||
|     ] | ||||
|  | ||||
| As you can see, we defined a ``show_message_form_condition`` next to our | ||||
| :class:`WizardView` subclass and added a ``condition_dict`` argument to the | ||||
| :meth:`~WizardView.as_view` method. The key refers to the second wizard step | ||||
| (because of the zero based step index). | ||||
|  | ||||
| How to work with ModelForm and ModelFormSet | ||||
| =========================================== | ||||
|  | ||||
| .. attribute:: WizardView.instance_dict | ||||
|  | ||||
| WizardView supports :mod:`ModelForms <django.forms.models>` and | ||||
| :ref:`ModelFormSets <model-formsets>`. Additionally to | ||||
| :attr:`~WizardView.initial_dict`, the :meth:`~WizardView.as_view` method takes | ||||
| an ``instance_dict`` argument that should contain model instances for steps | ||||
| based on ``ModelForm`` and querysets for steps based on ``ModelFormSet``. | ||||
|  | ||||
| Usage of ``NamedUrlWizardView`` | ||||
| =============================== | ||||
|  | ||||
| .. class:: NamedUrlWizardView | ||||
| .. class:: NamedUrlSessionWizardView | ||||
| .. class:: NamedUrlCookieWizardView | ||||
|  | ||||
| ``NamedUrlWizardView`` is a :class:`WizardView` subclass which adds named-urls | ||||
| support to the wizard. This allows you to have separate URLs for every step. | ||||
| You can also use the :class:`NamedUrlSessionWizardView` or :class:`NamedUrlCookieWizardView` | ||||
| classes which preselect the backend used for storing information (Django sessions and | ||||
| browser cookies respectively). | ||||
|  | ||||
| To use the named URLs, you should not only use the :class:`NamedUrlWizardView` instead of | ||||
| :class:`WizardView`, but you will also have to change your ``urls.py``. | ||||
|  | ||||
| The :meth:`~WizardView.as_view` method takes two additional arguments: | ||||
|  | ||||
| * a required ``url_name`` -- the name of the url (as provided in the ``urls.py``) | ||||
| * an optional ``done_step_name`` -- the name of the done step, to be used in the URL | ||||
|  | ||||
| This is an example of a ``urls.py`` for a contact wizard with two steps, step 1 named | ||||
| ``contactdata`` and step 2 named ``leavemessage``:: | ||||
|  | ||||
|     from django.conf.urls import url | ||||
|  | ||||
|     from myapp.forms import ContactForm1, ContactForm2 | ||||
|     from myapp.views import ContactWizard | ||||
|  | ||||
|     named_contact_forms = ( | ||||
|         ('contactdata', ContactForm1), | ||||
|         ('leavemessage', ContactForm2), | ||||
|     ) | ||||
|  | ||||
|     contact_wizard = ContactWizard.as_view(named_contact_forms, | ||||
|         url_name='contact_step', done_step_name='finished') | ||||
|  | ||||
|     urlpatterns = [ | ||||
|         url(r'^contact/(?P<step>.+)/$', contact_wizard, name='contact_step'), | ||||
|         url(r'^contact/$', contact_wizard, name='contact'), | ||||
|     ] | ||||
|  | ||||
| Advanced ``NamedUrlWizardView`` methods | ||||
| ======================================= | ||||
|  | ||||
| .. method:: NamedUrlWizardView.get_step_url(step) | ||||
|  | ||||
| This method returns the URL for a specific step. | ||||
|  | ||||
| Default implementation:: | ||||
|  | ||||
|     def get_step_url(self, step): | ||||
|         return reverse(self.url_name, kwargs={'step': step}) | ||||
		Reference in New Issue
	
	Block a user
	 Jannis Leidel
					Jannis Leidel