Added "svn:eol-style native" to every text file in the tree (*.txt, *.html,
*.py, *.xml and AUTHORS, etc). Added "svn:ignore *.pyc" to some directories in tests/regressiontests/ that were previously missing it. Fixed #6545, #6801. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7294 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5b8974c7b3
commit
9b52f35f35
|
@ -1,27 +1,27 @@
|
||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../">Home</a> › Documentation</div>{% endblock %}
|
||||||
{% block title %}Documentation{% endblock %}
|
{% block title %}Documentation{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h1>Documentation</h1>
|
<h1>Documentation</h1>
|
||||||
|
|
||||||
<div id="content-main">
|
<div id="content-main">
|
||||||
<h3><a href="tags/">Tags</a></h3>
|
<h3><a href="tags/">Tags</a></h3>
|
||||||
<p>List of all the template tags and their functions.</p>
|
<p>List of all the template tags and their functions.</p>
|
||||||
|
|
||||||
<h3><a href="filters/">Filters</a></h3>
|
<h3><a href="filters/">Filters</a></h3>
|
||||||
<p>Filters are actions which can be applied to variables in a template to alter the output.</p>
|
<p>Filters are actions which can be applied to variables in a template to alter the output.</p>
|
||||||
|
|
||||||
<h3><a href="models/">Models</a></h3>
|
<h3><a href="models/">Models</a></h3>
|
||||||
<p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
|
<p>Models are descriptions of all the objects in the system and their associated fields. Each model has a list of fields which can be accessed as template variables.</p>
|
||||||
|
|
||||||
<h3><a href="views/">Views</a></h3>
|
<h3><a href="views/">Views</a></h3>
|
||||||
<p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
|
<p>Each page on the public site is generated by a view. The view defines which template is used to generate the page and which objects are available to that template.</p>
|
||||||
|
|
||||||
<h3><a href="bookmarklets/">Bookmarklets</a></h3>
|
<h3><a href="bookmarklets/">Bookmarklets</a></h3>
|
||||||
<p>Tools for your browser to quickly access admin functionality.</p>
|
<p>Tools for your browser to quickly access admin functionality.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -1,42 +1,42 @@
|
||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block coltype %}colSM{% endblock %}
|
{% block coltype %}colSM{% endblock %}
|
||||||
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Views</div>{% endblock %}
|
{% block breadcrumbs %}<div class="breadcrumbs"><a href="../../">Home</a> › <a href="../">Documentation</a> › Views</div>{% endblock %}
|
||||||
{% block title %}Views{% endblock %}
|
{% block title %}Views{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<h1>View documentation</h1>
|
<h1>View documentation</h1>
|
||||||
|
|
||||||
{% regroup views|dictsort:"site_id" by site as views_by_site %}
|
{% regroup views|dictsort:"site_id" by site as views_by_site %}
|
||||||
|
|
||||||
<div id="content-related" class="sidebar">
|
<div id="content-related" class="sidebar">
|
||||||
<div class="module">
|
<div class="module">
|
||||||
<h2>Jump to site</h2>
|
<h2>Jump to site</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{% for site_views in views_by_site %}
|
{% for site_views in views_by_site %}
|
||||||
<li><a href="#site{{ site_views.grouper.id }}">{{ site_views.grouper.name }}</a></li>
|
<li><a href="#site{{ site_views.grouper.id }}">{{ site_views.grouper.name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="content-main">
|
<div id="content-main">
|
||||||
|
|
||||||
{% for site_views in views_by_site %}
|
{% for site_views in views_by_site %}
|
||||||
<div class="module">
|
<div class="module">
|
||||||
<h2 id="site{{ site_views.grouper.id }}">Views by URL on {{ site_views.grouper.name }}</h2>
|
<h2 id="site{{ site_views.grouper.id }}">Views by URL on {{ site_views.grouper.name }}</h2>
|
||||||
|
|
||||||
{% for view in site_views.list|dictsort:"url" %}
|
{% for view in site_views.list|dictsort:"url" %}
|
||||||
{% ifchanged %}
|
{% ifchanged %}
|
||||||
<h3><a href="{{ view.module }}.{{ view.name }}/">{{ view.url|escape }}</a></h3>
|
<h3><a href="{{ view.module }}.{{ view.name }}/">{{ view.url|escape }}</a></h3>
|
||||||
<p class="small quiet">View function: {{ view.module }}.{{ view.name }}</p>
|
<p class="small quiet">View function: {{ view.module }}.{{ view.name }}</p>
|
||||||
<p>{{ view.title }}</p>
|
<p>{{ view.title }}</p>
|
||||||
<hr />
|
<hr />
|
||||||
{% endifchanged %}
|
{% endifchanged %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,246 +1,246 @@
|
||||||
"""
|
"""
|
||||||
FormWizard class -- implements a multi-page form, validating between each
|
FormWizard class -- implements a multi-page form, validating between each
|
||||||
step and storing the form's state as HTML hidden fields so that no state is
|
step and storing the form's state as HTML hidden fields so that no state is
|
||||||
stored on the server side.
|
stored on the server side.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django import newforms as forms
|
from django import newforms as forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.template.context import RequestContext
|
from django.template.context import RequestContext
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
import md5
|
import md5
|
||||||
|
|
||||||
class FormWizard(object):
|
class FormWizard(object):
|
||||||
# Dictionary of extra template context variables.
|
# Dictionary of extra template context variables.
|
||||||
extra_context = {}
|
extra_context = {}
|
||||||
|
|
||||||
# The HTML (and POST data) field name for the "step" variable.
|
# The HTML (and POST data) field name for the "step" variable.
|
||||||
step_field_name="wizard_step"
|
step_field_name="wizard_step"
|
||||||
|
|
||||||
# METHODS SUBCLASSES SHOULDN'T OVERRIDE ###################################
|
# METHODS SUBCLASSES SHOULDN'T OVERRIDE ###################################
|
||||||
|
|
||||||
def __init__(self, form_list, initial=None):
|
def __init__(self, form_list, initial=None):
|
||||||
"form_list should be a list of Form classes (not instances)."
|
"form_list should be a list of Form classes (not instances)."
|
||||||
self.form_list = form_list[:]
|
self.form_list = form_list[:]
|
||||||
self.initial = initial or {}
|
self.initial = initial or {}
|
||||||
self.step = 0 # A zero-based counter keeping track of which step we're in.
|
self.step = 0 # A zero-based counter keeping track of which step we're in.
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "step: %d\nform_list: %s\ninitial_data: %s" % (self.step, self.form_list, self.initial)
|
return "step: %d\nform_list: %s\ninitial_data: %s" % (self.step, self.form_list, self.initial)
|
||||||
|
|
||||||
def get_form(self, step, data=None):
|
def get_form(self, step, data=None):
|
||||||
"Helper method that returns the Form instance for the given step."
|
"Helper method that returns the Form instance for the given step."
|
||||||
return self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None))
|
return self.form_list[step](data, prefix=self.prefix_for_step(step), initial=self.initial.get(step, None))
|
||||||
|
|
||||||
def num_steps(self):
|
def num_steps(self):
|
||||||
"Helper method that returns the number of steps."
|
"Helper method that returns the number of steps."
|
||||||
# You might think we should just set "self.form_list = len(form_list)"
|
# You might think we should just set "self.form_list = len(form_list)"
|
||||||
# in __init__(), but this calculation needs to be dynamic, because some
|
# in __init__(), but this calculation needs to be dynamic, because some
|
||||||
# hook methods might alter self.form_list.
|
# hook methods might alter self.form_list.
|
||||||
return len(self.form_list)
|
return len(self.form_list)
|
||||||
|
|
||||||
def __call__(self, request, *args, **kwargs):
|
def __call__(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Main method that does all the hard work, conforming to the Django view
|
Main method that does all the hard work, conforming to the Django view
|
||||||
interface.
|
interface.
|
||||||
"""
|
"""
|
||||||
if 'extra_context' in kwargs:
|
if 'extra_context' in kwargs:
|
||||||
self.extra_context.update(kwargs['extra_context'])
|
self.extra_context.update(kwargs['extra_context'])
|
||||||
current_step = self.determine_step(request, *args, **kwargs)
|
current_step = self.determine_step(request, *args, **kwargs)
|
||||||
self.parse_params(request, *args, **kwargs)
|
self.parse_params(request, *args, **kwargs)
|
||||||
|
|
||||||
# Sanity check.
|
# Sanity check.
|
||||||
if current_step >= self.num_steps():
|
if current_step >= self.num_steps():
|
||||||
raise Http404('Step %s does not exist' % current_step)
|
raise Http404('Step %s does not exist' % current_step)
|
||||||
|
|
||||||
# For each previous step, verify the hash and process.
|
# For each previous step, verify the hash and process.
|
||||||
# TODO: Move "hash_%d" to a method to make it configurable.
|
# TODO: Move "hash_%d" to a method to make it configurable.
|
||||||
for i in range(current_step):
|
for i in range(current_step):
|
||||||
form = self.get_form(i, request.POST)
|
form = self.get_form(i, request.POST)
|
||||||
if request.POST.get("hash_%d" % i, '') != self.security_hash(request, form):
|
if request.POST.get("hash_%d" % i, '') != self.security_hash(request, form):
|
||||||
return self.render_hash_failure(request, i)
|
return self.render_hash_failure(request, i)
|
||||||
self.process_step(request, form, i)
|
self.process_step(request, form, i)
|
||||||
|
|
||||||
# Process the current step. If it's valid, go to the next step or call
|
# Process the current step. If it's valid, go to the next step or call
|
||||||
# done(), depending on whether any steps remain.
|
# done(), depending on whether any steps remain.
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = self.get_form(current_step, request.POST)
|
form = self.get_form(current_step, request.POST)
|
||||||
else:
|
else:
|
||||||
form = self.get_form(current_step)
|
form = self.get_form(current_step)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
self.process_step(request, form, current_step)
|
self.process_step(request, form, current_step)
|
||||||
next_step = current_step + 1
|
next_step = current_step + 1
|
||||||
|
|
||||||
# If this was the last step, validate all of the forms one more
|
# If this was the last step, validate all of the forms one more
|
||||||
# time, as a sanity check, and call done().
|
# time, as a sanity check, and call done().
|
||||||
num = self.num_steps()
|
num = self.num_steps()
|
||||||
if next_step == num:
|
if next_step == num:
|
||||||
final_form_list = [self.get_form(i, request.POST) for i in range(num)]
|
final_form_list = [self.get_form(i, request.POST) for i in range(num)]
|
||||||
|
|
||||||
# Validate all the forms. If any of them fail validation, that
|
# Validate all the forms. If any of them fail validation, that
|
||||||
# must mean the validator relied on some other input, such as
|
# must mean the validator relied on some other input, such as
|
||||||
# an external Web site.
|
# an external Web site.
|
||||||
for i, f in enumerate(final_form_list):
|
for i, f in enumerate(final_form_list):
|
||||||
if not f.is_valid():
|
if not f.is_valid():
|
||||||
return self.render_revalidation_failure(request, i, f)
|
return self.render_revalidation_failure(request, i, f)
|
||||||
return self.done(request, final_form_list)
|
return self.done(request, final_form_list)
|
||||||
|
|
||||||
# Otherwise, move along to the next step.
|
# Otherwise, move along to the next step.
|
||||||
else:
|
else:
|
||||||
form = self.get_form(next_step)
|
form = self.get_form(next_step)
|
||||||
current_step = next_step
|
current_step = next_step
|
||||||
|
|
||||||
return self.render(form, request, current_step)
|
return self.render(form, request, current_step)
|
||||||
|
|
||||||
def render(self, form, request, step, context=None):
|
def render(self, form, request, step, context=None):
|
||||||
"Renders the given Form object, returning an HttpResponse."
|
"Renders the given Form object, returning an HttpResponse."
|
||||||
old_data = request.POST
|
old_data = request.POST
|
||||||
prev_fields = []
|
prev_fields = []
|
||||||
if old_data:
|
if old_data:
|
||||||
hidden = forms.HiddenInput()
|
hidden = forms.HiddenInput()
|
||||||
# Collect all data from previous steps and render it as HTML hidden fields.
|
# Collect all data from previous steps and render it as HTML hidden fields.
|
||||||
for i in range(step):
|
for i in range(step):
|
||||||
old_form = self.get_form(i, old_data)
|
old_form = self.get_form(i, old_data)
|
||||||
hash_name = 'hash_%s' % i
|
hash_name = 'hash_%s' % i
|
||||||
prev_fields.extend([bf.as_hidden() for bf in old_form])
|
prev_fields.extend([bf.as_hidden() for bf in old_form])
|
||||||
prev_fields.append(hidden.render(hash_name, old_data.get(hash_name, self.security_hash(request, old_form))))
|
prev_fields.append(hidden.render(hash_name, old_data.get(hash_name, self.security_hash(request, old_form))))
|
||||||
return self.render_template(request, form, ''.join(prev_fields), step, context)
|
return self.render_template(request, form, ''.join(prev_fields), step, context)
|
||||||
|
|
||||||
# METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
|
# METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
|
||||||
|
|
||||||
def prefix_for_step(self, step):
|
def prefix_for_step(self, step):
|
||||||
"Given the step, returns a Form prefix to use."
|
"Given the step, returns a Form prefix to use."
|
||||||
return str(step)
|
return str(step)
|
||||||
|
|
||||||
def render_hash_failure(self, request, step):
|
def render_hash_failure(self, request, step):
|
||||||
"""
|
"""
|
||||||
Hook for rendering a template if a hash check failed.
|
Hook for rendering a template if a hash check failed.
|
||||||
|
|
||||||
step is the step that failed. Any previous step is guaranteed to be
|
step is the step that failed. Any previous step is guaranteed to be
|
||||||
valid.
|
valid.
|
||||||
|
|
||||||
This default implementation simply renders the form for the given step,
|
This default implementation simply renders the form for the given step,
|
||||||
but subclasses may want to display an error message, etc.
|
but subclasses may want to display an error message, etc.
|
||||||
"""
|
"""
|
||||||
return self.render(self.get_form(step), request, step, context={'wizard_error': 'We apologize, but your form has expired. Please continue filling out the form from this page.'})
|
return self.render(self.get_form(step), request, step, context={'wizard_error': 'We apologize, but your form has expired. Please continue filling out the form from this page.'})
|
||||||
|
|
||||||
def render_revalidation_failure(self, request, step, form):
|
def render_revalidation_failure(self, request, step, form):
|
||||||
"""
|
"""
|
||||||
Hook for rendering a template if final revalidation failed.
|
Hook for rendering a template if final revalidation failed.
|
||||||
|
|
||||||
It is highly unlikely that this point would ever be reached, but See
|
It is highly unlikely that this point would ever be reached, but See
|
||||||
the comment in __call__() for an explanation.
|
the comment in __call__() for an explanation.
|
||||||
"""
|
"""
|
||||||
return self.render(form, request, step)
|
return self.render(form, request, step)
|
||||||
|
|
||||||
def security_hash(self, request, form):
|
def security_hash(self, request, form):
|
||||||
"""
|
"""
|
||||||
Calculates the security hash for the given HttpRequest and Form instances.
|
Calculates the security hash for the given HttpRequest and Form instances.
|
||||||
|
|
||||||
This creates a list of the form field names/values in a deterministic
|
This creates a list of the form field names/values in a deterministic
|
||||||
order, pickles the result with the SECRET_KEY setting and takes an md5
|
order, pickles the result with the SECRET_KEY setting and takes an md5
|
||||||
hash of that.
|
hash of that.
|
||||||
|
|
||||||
Subclasses may want to take into account request-specific information,
|
Subclasses may want to take into account request-specific information,
|
||||||
such as the IP address.
|
such as the IP address.
|
||||||
"""
|
"""
|
||||||
data = [(bf.name, bf.data or '') for bf in form] + [settings.SECRET_KEY]
|
data = [(bf.name, bf.data or '') for bf in form] + [settings.SECRET_KEY]
|
||||||
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
|
# Use HIGHEST_PROTOCOL because it's the most efficient. It requires
|
||||||
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
|
# Python 2.3, but Django requires 2.3 anyway, so that's OK.
|
||||||
pickled = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
|
pickled = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
|
||||||
return md5.new(pickled).hexdigest()
|
return md5.new(pickled).hexdigest()
|
||||||
|
|
||||||
def determine_step(self, request, *args, **kwargs):
|
def determine_step(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Given the request object and whatever *args and **kwargs were passed to
|
Given the request object and whatever *args and **kwargs were passed to
|
||||||
__call__(), returns the current step (which is zero-based).
|
__call__(), returns the current step (which is zero-based).
|
||||||
|
|
||||||
Note that the result should not be trusted. It may even be a completely
|
Note that the result should not be trusted. It may even be a completely
|
||||||
invalid number. It's not the job of this method to validate it.
|
invalid number. It's not the job of this method to validate it.
|
||||||
"""
|
"""
|
||||||
if not request.POST:
|
if not request.POST:
|
||||||
return 0
|
return 0
|
||||||
try:
|
try:
|
||||||
step = int(request.POST.get(self.step_field_name, 0))
|
step = int(request.POST.get(self.step_field_name, 0))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
return 0
|
return 0
|
||||||
return step
|
return step
|
||||||
|
|
||||||
def parse_params(self, request, *args, **kwargs):
|
def parse_params(self, request, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Hook for setting some state, given the request object and whatever
|
Hook for setting some state, given the request object and whatever
|
||||||
*args and **kwargs were passed to __call__(), sets some state.
|
*args and **kwargs were passed to __call__(), sets some state.
|
||||||
|
|
||||||
This is called at the beginning of __call__().
|
This is called at the beginning of __call__().
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_template(self, step):
|
def get_template(self, step):
|
||||||
"""
|
"""
|
||||||
Hook for specifying the name of the template to use for a given step.
|
Hook for specifying the name of the template to use for a given step.
|
||||||
|
|
||||||
Note that this can return a tuple of template names if you'd like to
|
Note that this can return a tuple of template names if you'd like to
|
||||||
use the template system's select_template() hook.
|
use the template system's select_template() hook.
|
||||||
"""
|
"""
|
||||||
return 'forms/wizard.html'
|
return 'forms/wizard.html'
|
||||||
|
|
||||||
def render_template(self, request, form, previous_fields, step, context=None):
|
def render_template(self, request, form, previous_fields, step, context=None):
|
||||||
"""
|
"""
|
||||||
Renders the template for the given step, returning an HttpResponse object.
|
Renders the template for the given step, returning an HttpResponse object.
|
||||||
|
|
||||||
Override this method if you want to add a custom context, return a
|
Override this method if you want to add a custom context, return a
|
||||||
different MIME type, etc. If you only need to override the template
|
different MIME type, etc. If you only need to override the template
|
||||||
name, use get_template() instead.
|
name, use get_template() instead.
|
||||||
|
|
||||||
The template will be rendered with the following context:
|
The template will be rendered with the following context:
|
||||||
step_field -- The name of the hidden field containing the step.
|
step_field -- The name of the hidden field containing the step.
|
||||||
step0 -- The current step (zero-based).
|
step0 -- The current step (zero-based).
|
||||||
step -- The current step (one-based).
|
step -- The current step (one-based).
|
||||||
step_count -- The total number of steps.
|
step_count -- The total number of steps.
|
||||||
form -- The Form instance for the current step (either empty
|
form -- The Form instance for the current step (either empty
|
||||||
or with errors).
|
or with errors).
|
||||||
previous_fields -- A string representing every previous data field,
|
previous_fields -- A string representing every previous data field,
|
||||||
plus hashes for completed forms, all in the form of
|
plus hashes for completed forms, all in the form of
|
||||||
hidden fields. Note that you'll need to run this
|
hidden fields. Note that you'll need to run this
|
||||||
through the "safe" template filter, to prevent
|
through the "safe" template filter, to prevent
|
||||||
auto-escaping, because it's raw HTML.
|
auto-escaping, because it's raw HTML.
|
||||||
"""
|
"""
|
||||||
context = context or {}
|
context = context or {}
|
||||||
context.update(self.extra_context)
|
context.update(self.extra_context)
|
||||||
return render_to_response(self.get_template(self.step), dict(context,
|
return render_to_response(self.get_template(self.step), dict(context,
|
||||||
step_field=self.step_field_name,
|
step_field=self.step_field_name,
|
||||||
step0=step,
|
step0=step,
|
||||||
step=step + 1,
|
step=step + 1,
|
||||||
step_count=self.num_steps(),
|
step_count=self.num_steps(),
|
||||||
form=form,
|
form=form,
|
||||||
previous_fields=previous_fields
|
previous_fields=previous_fields
|
||||||
), context_instance=RequestContext(request))
|
), context_instance=RequestContext(request))
|
||||||
|
|
||||||
def process_step(self, request, form, step):
|
def process_step(self, request, form, step):
|
||||||
"""
|
"""
|
||||||
Hook for modifying the FormWizard's internal state, given a fully
|
Hook for modifying the FormWizard's internal state, given a fully
|
||||||
validated Form object. The Form is guaranteed to have clean, valid
|
validated Form object. The Form is guaranteed to have clean, valid
|
||||||
data.
|
data.
|
||||||
|
|
||||||
This method should *not* modify any of that data. Rather, it might want
|
This method should *not* modify any of that data. Rather, it might want
|
||||||
to set self.extra_context or dynamically alter self.form_list, based on
|
to set self.extra_context or dynamically alter self.form_list, based on
|
||||||
previously submitted forms.
|
previously submitted forms.
|
||||||
|
|
||||||
Note that this method is called every time a page is rendered for *all*
|
Note that this method is called every time a page is rendered for *all*
|
||||||
submitted steps.
|
submitted steps.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
# METHODS SUBCLASSES MUST OVERRIDE ########################################
|
||||||
|
|
||||||
def done(self, request, form_list):
|
def done(self, request, form_list):
|
||||||
"""
|
"""
|
||||||
Hook for doing something with the validated data. This is responsible
|
Hook for doing something with the validated data. This is responsible
|
||||||
for the final processing.
|
for the final processing.
|
||||||
|
|
||||||
form_list is a list of Form instances, each containing clean, valid
|
form_list is a list of Form instances, each containing clean, valid
|
||||||
data.
|
data.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError("Your %s class has not defined a done() method, which is required." % self.__class__.__name__)
|
raise NotImplementedError("Your %s class has not defined a done() method, which is required." % self.__class__.__name__)
|
||||||
|
|
Loading…
Reference in New Issue