Commits

Anonymous committed 6d2cdee

per-object-permissions: Merged to trunk [4241]

Comments (0)

Files changed (64)

     Manuzhai
     Petar Marić
     mark@junklight.com
+    Yasushi Masuda <whosaysni@gmail.com>
     mattycakes@gmail.com
     Jason McBrayer <http://www.carcosa.net/jason/>
     mccutchen@gmail.com
     michael.mcewan@gmail.com
+    mitakummaa@gmail.com
     mmarshall
     Eric Moritz <http://eric.themoritzfamily.com/>
     Robin Munn <http://www.geekforgod.com/>
     SmileyChris <smileychris@gmail.com>
     sopel
     Thomas Steinacher <tom@eggdrop.ch>
+    nowell strite
     Radek Švarz <http://www.svarz.cz/translate/>
     Swaroop C H <http://www.swaroopch.info>
     Aaron Swartz <http://www.aaronsw.com/>
     Tom Insam
     Joe Topjian <http://joe.terrarum.net/geek/code/python/django/>
     Karen Tracey <graybark@bellsouth.net>
+    Makoto Tsuyuki <mtsuyuki@gmail.com>
     Amit Upadhyay
     Geert Vanderkelen
     Milton Waddams

django/conf/global_settings.py

 INTERNAL_IPS = ()
 
 # Local time zone for this installation. All choices can be found here:
-# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
+# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
 TIME_ZONE = 'America/Chicago'
 
 # Language code for this installation. All choices can be found here:

django/conf/project_template/settings.py

 DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.
 
 # Local time zone for this installation. All choices can be found here:
-# http://www.postgresql.org/docs/current/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
+# http://www.postgresql.org/docs/8.1/static/datetime-keywords.html#DATETIME-TIMEZONE-SET-TABLE
 TIME_ZONE = 'America/Chicago'
 
 # Language code for this installation. All choices can be found here:

django/conf/project_template/urls.py

 
 urlpatterns = patterns('',
     # Example:
-    # (r'^{{ project_name }}/', include('{{ project_name }}.apps.foo.urls.foo')),
+    # (r'^{{ project_name }}/', include('{{ project_name }}.foo.urls')),
 
     # Uncomment this for admin:
 #     (r'^admin/', include('django.contrib.admin.urls')),

django/contrib/admin/templates/admin/base.html

     <div id="content" class="{% block coltype %}colM{% endblock %}">
         {% block pretitle %}{% endblock %}
         {% block content_title %}{% if title %}<h1>{{ title|escape }}</h1>{% endif %}{% endblock %}
-        {% block content %}{{ content }}{% endblock %}
+        {% block content %}
+        {% block object-tools %}{% endblock %}
+        {{ content }}
+        {% endblock %}
         {% block sidebar %}{% endblock %}
         <br class="clear" />
     </div>

django/contrib/admin/templates/admin/change_form.html

 </div>
 {% endif %}{% endblock %}
 {% block content %}<div id="content-main">
+{% block object-tools %}
 {% if change %}{% if not is_popup %}
   <ul class="object-tools"><li><a href="history/" class="historylink">{% trans "History" %}</a></li>
   {% if object_has_row_level_permissions and has_row_level_permissions %}<li><a href="row_level_permissions/" class="rowlevelpermissions">{% trans "Edit Row Level Permissions" %}</a></li>{% endif %}
   {% if has_absolute_url %}<li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif%}
   </ul>
 {% endif %}{% endif %}
+{% endblock %}
 <form {% if has_file_field %}enctype="multipart/form-data" {% endif %}action="{{ form_url }}" method="post" id="{{ opts.module_name }}_form">{% block form_top %}{% endblock %}
 <div>
 {% if is_popup %}<input type="hidden" name="_popup" value="1" />{% endif %}

django/contrib/admin/templates/admin/change_list.html

 {% block coltype %}flex{% endblock %}
 {% block content %}
 <div id="content-main">
+{% block object-tools %}
 {% if has_add_permission %}
 <ul class="object-tools"><li><a href="add/{% if is_popup %}?_popup=1{% endif %}" class="addlink">{% blocktrans with cl.opts.verbose_name|escape as name %}Add {{ name }}{% endblocktrans %}</a></li></ul>
 {% endif %}
+{% endblock %}
 <div class="module{% if cl.has_filters %} filtered{% endif %}" id="changelist">
 {% block search %}{% search_form cl %}{% endblock %}
 {% block date_hierarchy %}{% date_hierarchy cl %}{% endblock %}

django/contrib/admin/templates/admin/search_form.html

 <input type="text" size="40" name="{{ search_var }}" value="{{ cl.query|escape }}" id="searchbar" />
 <input type="submit" value="{% trans 'Go' %}" />
 {% if show_result_count %}
-    <span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
+    <span class="small quiet">{% blocktrans count cl.result_count as counter %}1 result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}pop=1{% endif %}">{% blocktrans with cl.full_result_count as full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
 {% endif %}
 {% for pair in cl.params.items %}
     {% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0|escape }}" value="{{ pair.1|escape }}"/>{% endifnotequal %}

django/contrib/admin/views/auth.py

 from django.contrib.auth.forms import UserCreationForm
 from django.contrib.auth.models import User
 from django.core.exceptions import PermissionDenied
-from django import forms, template
+from django import oldforms, template
 from django.shortcuts import render_to_response
 from django.http import HttpResponseRedirect
 
                 return HttpResponseRedirect('../%s/' % new_user.id)
     else:
         errors = new_data = {}
-    form = forms.FormWrapper(manipulator, new_data, errors)
+    form = oldforms.FormWrapper(manipulator, new_data, errors)
     return render_to_response('admin/auth/user/add_form.html', {
         'title': _('Add user'),
         'form': form,

django/contrib/admin/views/main.py

-from django import forms, template
+from django import oldforms, template
 from django.conf import settings
 from django.contrib.admin.filterspecs import FilterSpec
 from django.contrib.admin.views.decorators import staff_member_required
 def add_stage(request, app_label, model_name, show_delete=False, form_url='', post_url=None, post_url_continue='../%s/', object_id_override=None):
     model = models.get_model(app_label, model_name)
     if model is None:
-        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
+        raise Http404("App %r, model %r, not found" % (app_label, model_name))
     opts = model._meta
 
     if not request.user.has_perm(app_label + '.' + opts.get_add_permission()):
         errors = {}
 
     # Populate the FormWrapper.
-    form = forms.FormWrapper(manipulator, new_data, errors)
+    form = oldforms.FormWrapper(manipulator, new_data, errors)
 
     c = template.RequestContext(request, {
         'title': _('Add %s') % opts.verbose_name,
     model = models.get_model(app_label, model_name)
     object_id = unquote(object_id)
     if model is None:
-        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
+        raise Http404("App %r, model %r, not found" % (app_label, model_name))
     opts = model._meta
 
     try:
         manipulator = model.ChangeManipulator(object_id)
     except ObjectDoesNotExist:
-        raise Http404
+        raise Http404('%s object with primary key %r does not exist' % (model_name, escape(object_id)))
 
     if not request.user.has_perm(app_label + '.' + opts.get_change_permission(), object=manipulator.original_object):
         raise PermissionDenied
     if request.POST and request.POST.has_key("_saveasnew"):
         return add_stage(request, app_label, model_name, form_url='../../add/')
 
-
-
     if request.POST:
         new_data = request.POST.copy()
 
         errors = {}
 
     # Populate the FormWrapper.
-    form = forms.FormWrapper(manipulator, new_data, errors)
+    form = oldforms.FormWrapper(manipulator, new_data, errors)
     form.original = manipulator.original_object
     form.order_objects = []
 
     model = models.get_model(app_label, model_name)
     object_id = unquote(object_id)
     if model is None:
-        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
+        raise Http404("App %r, model %r, not found" % (app_label, model_name))
     opts = model._meta
 
     obj = get_object_or_404(model, pk=object_id)
     model = models.get_model(app_label, model_name)
     object_id = unquote(object_id)
     if model is None:
-        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
+        raise Http404("App %r, model %r, not found" % (app_label, model_name))
     action_list = LogEntry.objects.filter(object_id=object_id,
         content_type__id__exact=ContentType.objects.get_for_model(model).id).select_related().order_by('action_time')
     # If no history was found, see whether this object even exists.
 def change_list(request, app_label, model_name):
     model = models.get_model(app_label, model_name)
     if model is None:
-        raise Http404, "App %r, model %r, not found" % (app_label, model_name)
+        raise Http404("App %r, model %r, not found" % (app_label, model_name))
     if not request.user.contains_permission(app_label + '.' + model._meta.get_change_permission(), model):
         raise PermissionDenied
     try:

django/contrib/admin/views/template.py

 from django.contrib.admin.views.decorators import staff_member_required
 from django.core import validators
-from django import template, forms
+from django import template, oldforms
 from django.template import loader
 from django.shortcuts import render_to_response
 from django.contrib.sites.models import Site
             request.user.message_set.create(message='The template is valid.')
     return render_to_response('admin/template_validator.html', {
         'title': 'Template validator',
-        'form': forms.FormWrapper(manipulator, new_data, errors),
+        'form': oldforms.FormWrapper(manipulator, new_data, errors),
     }, context_instance=template.RequestContext(request))
 template_validator = staff_member_required(template_validator)
 
-class TemplateValidator(forms.Manipulator):
+class TemplateValidator(oldforms.Manipulator):
     def __init__(self, settings_modules):
         self.settings_modules = settings_modules
         site_list = Site.objects.in_bulk(settings_modules.keys()).values()
         self.fields = (
-            forms.SelectField('site', is_required=True, choices=[(s.id, s.name) for s in site_list]),
-            forms.LargeTextField('template', is_required=True, rows=25, validator_list=[self.isValidTemplate]),
+            oldforms.SelectField('site', is_required=True, choices=[(s.id, s.name) for s in site_list]),
+            oldforms.LargeTextField('template', is_required=True, rows=25, validator_list=[self.isValidTemplate]),
         )
 
     def isValidTemplate(self, field_data, all_data):

django/contrib/auth/forms.py

 from django.contrib.sites.models import Site
 from django.template import Context, loader
 from django.core import validators
-from django import forms
+from django import oldforms
 
-class UserCreationForm(forms.Manipulator):
+class UserCreationForm(oldforms.Manipulator):
     "A form that creates a user, with no privileges, from the given username and password."
     def __init__(self):
         self.fields = (
-            forms.TextField(field_name='username', length=30, maxlength=30, is_required=True,
+            oldforms.TextField(field_name='username', length=30, maxlength=30, is_required=True,
                 validator_list=[validators.isAlphaNumeric, self.isValidUsername]),
-            forms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
-            forms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
+            oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
+            oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
                 validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
         )
 
         "Creates the user."
         return User.objects.create_user(new_data['username'], '', new_data['password1'])
 
-class AuthenticationForm(forms.Manipulator):
+class AuthenticationForm(oldforms.Manipulator):
     """
     Base class for authenticating users. Extend this to get a form that accepts
     username/password logins.
         """
         self.request = request
         self.fields = [
-            forms.TextField(field_name="username", length=15, maxlength=30, is_required=True,
+            oldforms.TextField(field_name="username", length=15, maxlength=30, is_required=True,
                 validator_list=[self.isValidUser, self.hasCookiesEnabled]),
-            forms.PasswordField(field_name="password", length=15, maxlength=30, is_required=True),
+            oldforms.PasswordField(field_name="password", length=15, maxlength=30, is_required=True),
         ]
         self.user_cache = None
 
     def get_user(self):
         return self.user_cache
 
-class PasswordResetForm(forms.Manipulator):
+class PasswordResetForm(oldforms.Manipulator):
     "A form that lets a user request a password reset"
     def __init__(self):
         self.fields = (
-            forms.EmailField(field_name="email", length=40, is_required=True,
+            oldforms.EmailField(field_name="email", length=40, is_required=True,
                 validator_list=[self.isValidUserEmail]),
         )
 
         }
         send_mail('Password reset on %s' % site_name, t.render(Context(c)), None, [self.user_cache.email])
 
-class PasswordChangeForm(forms.Manipulator):
+class PasswordChangeForm(oldforms.Manipulator):
     "A form that lets a user change his password."
     def __init__(self, user):
         self.user = user
         self.fields = (
-            forms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True,
+            oldforms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True,
                 validator_list=[self.isValidOldPassword]),
-            forms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True,
+            oldforms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True,
                 validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]),
-            forms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True),
+            oldforms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True),
         )
 
     def isValidOldPassword(self, new_data, all_data):

django/contrib/auth/views.py

 from django.contrib.auth.forms import AuthenticationForm
 from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm
-from django import forms
+from django import oldforms
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.contrib.sites.models import Site
         errors = {}
     request.session.set_test_cookie()
     return render_to_response(template_name, {
-        'form': forms.FormWrapper(manipulator, request.POST, errors),
+        'form': oldforms.FormWrapper(manipulator, request.POST, errors),
         REDIRECT_FIELD_NAME: redirect_to,
         'site_name': Site.objects.get_current().name,
     }, context_instance=RequestContext(request))
             else:
                 form.save(email_template_name=email_template_name)
             return HttpResponseRedirect('%sdone/' % request.path)
-    return render_to_response(template_name, {'form': forms.FormWrapper(form, new_data, errors)},
+    return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)},
         context_instance=RequestContext(request))
 
 def password_reset_done(request, template_name='registration/password_reset_done.html'):
         if not errors:
             form.save(new_data)
             return HttpResponseRedirect('%sdone/' % request.path)
-    return render_to_response(template_name, {'form': forms.FormWrapper(form, new_data, errors)},
+    return render_to_response(template_name, {'form': oldforms.FormWrapper(form, new_data, errors)},
         context_instance=RequestContext(request))
 password_change = login_required(password_change)
 

django/contrib/comments/views/comments.py

 from django.core import validators
-from django import forms
+from django import oldforms
 from django.core.mail import mail_admins, mail_managers
 from django.http import Http404
 from django.core.exceptions import ObjectDoesNotExist
             else:
                 return []
         self.fields.extend([
-            forms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
+            oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
                 validator_list=[self.hasNoProfanities]),
-            forms.RadioSelectField(field_name="rating1", choices=choices,
+            oldforms.RadioSelectField(field_name="rating1", choices=choices,
                 is_required=ratings_required and num_rating_choices > 0,
                 validator_list=get_validator_list(1),
             ),
-            forms.RadioSelectField(field_name="rating2", choices=choices,
+            oldforms.RadioSelectField(field_name="rating2", choices=choices,
                 is_required=ratings_required and num_rating_choices > 1,
                 validator_list=get_validator_list(2),
             ),
-            forms.RadioSelectField(field_name="rating3", choices=choices,
+            oldforms.RadioSelectField(field_name="rating3", choices=choices,
                 is_required=ratings_required and num_rating_choices > 2,
                 validator_list=get_validator_list(3),
             ),
-            forms.RadioSelectField(field_name="rating4", choices=choices,
+            oldforms.RadioSelectField(field_name="rating4", choices=choices,
                 is_required=ratings_required and num_rating_choices > 3,
                 validator_list=get_validator_list(4),
             ),
-            forms.RadioSelectField(field_name="rating5", choices=choices,
+            oldforms.RadioSelectField(field_name="rating5", choices=choices,
                 is_required=ratings_required and num_rating_choices > 4,
                 validator_list=get_validator_list(5),
             ),
-            forms.RadioSelectField(field_name="rating6", choices=choices,
+            oldforms.RadioSelectField(field_name="rating6", choices=choices,
                 is_required=ratings_required and num_rating_choices > 5,
                 validator_list=get_validator_list(6),
             ),
-            forms.RadioSelectField(field_name="rating7", choices=choices,
+            oldforms.RadioSelectField(field_name="rating7", choices=choices,
                 is_required=ratings_required and num_rating_choices > 6,
                 validator_list=get_validator_list(7),
             ),
-            forms.RadioSelectField(field_name="rating8", choices=choices,
+            oldforms.RadioSelectField(field_name="rating8", choices=choices,
                 is_required=ratings_required and num_rating_choices > 7,
                 validator_list=get_validator_list(8),
             ),
             mail_managers("Comment posted by sketchy user (%s)" % self.user_cache.username, c.get_as_text())
         return c
 
-class PublicFreeCommentManipulator(forms.Manipulator):
+class PublicFreeCommentManipulator(oldforms.Manipulator):
     "Manipulator that handles public free (unregistered) comments"
     def __init__(self):
         self.fields = (
-            forms.TextField(field_name="person_name", maxlength=50, is_required=True,
+            oldforms.TextField(field_name="person_name", maxlength=50, is_required=True,
                 validator_list=[self.hasNoProfanities]),
-            forms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
+            oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
                 validator_list=[self.hasNoProfanities]),
         )
 
         from django.contrib.auth import login
         login(request, manipulator.get_user())
     if errors or request.POST.has_key('preview'):
-        class CommentFormWrapper(forms.FormWrapper):
+        class CommentFormWrapper(oldforms.FormWrapper):
             def __init__(self, manipulator, new_data, errors, rating_choices):
-                forms.FormWrapper.__init__(self, manipulator, new_data, errors)
+                oldforms.FormWrapper.__init__(self, manipulator, new_data, errors)
                 self.rating_choices = rating_choices
             def ratings(self):
                 field_list = [self['rating%d' % (i+1)] for i in range(len(rating_choices))]
         comment = errors and '' or manipulator.get_comment(new_data)
         return render_to_response('comments/free_preview.html', {
             'comment': comment,
-            'comment_form': forms.FormWrapper(manipulator, new_data, errors),
+            'comment_form': oldforms.FormWrapper(manipulator, new_data, errors),
             'options': options,
             'target': target,
             'hash': security_hash,

django/contrib/contenttypes/management.py

 """
 
 from django.dispatch import dispatcher
-from django.db.models import get_models, signals
+from django.db.models import get_apps, get_models, signals
 
-def create_contenttypes(app, created_models, verbosity):
+def create_contenttypes(app, created_models, verbosity=2):
     from django.contrib.contenttypes.models import ContentType
     app_models = get_models(app)
     if not app_models:
             if verbosity >= 2:
                 print "Adding content type '%s | %s'" % (ct.app_label, ct.model)
 
+def create_all_contenttypes(verbosity=2):
+    for app in get_apps():
+        create_contenttypes(app, None, verbosity)
+
 dispatcher.connect(create_contenttypes, signal=signals.post_syncdb)
+
+if __name__ == "__main__":
+    create_all_contenttypes()

django/contrib/csrf/middleware.py

 import re
 import itertools
 
-_ERROR_MSG = "<h1>403 Forbidden</h1><p>Cross Site Request Forgery detected.  Request aborted.</p>"
+_ERROR_MSG = '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><body><h1>403 Forbidden</h1><p>Cross Site Request Forgery detected. Request aborted.</p></body></html>'
 
 _POST_FORM_RE = \
     re.compile(r'(<form\W[^>]*\bmethod=(\'|"|)POST(\'|"|)\b[^>]*>)', re.IGNORECASE)

django/contrib/formtools/__init__.py

Empty file added.

django/contrib/formtools/preview.py

+"""
+Formtools Preview application.
+
+This is an abstraction of the following workflow:
+
+    "Display an HTML form, force a preview, then do something with the submission."
+
+Given a django.newforms.Form object that you define, this takes care of the
+following:
+
+    * Displays the form as HTML on a Web page.
+    * Validates the form data once it's submitted via POST.
+        * If it's valid, displays a preview page.
+        * If it's not valid, redisplays the form with error messages.
+    * At the preview page, if the preview confirmation button is pressed, calls
+      a hook that you define -- a done() method.
+
+The framework enforces the required preview by passing a shared-secret hash to
+the preview page. If somebody tweaks the form parameters on the preview page,
+the form submission will fail the hash comparison test.
+
+Usage
+=====
+
+Subclass FormPreview and define a done() method:
+
+    def done(self, request, clean_data):
+        # ...
+
+This method takes an HttpRequest object and a dictionary of the form data after
+it has been validated and cleaned. It should return an HttpResponseRedirect.
+
+Then, just instantiate your FormPreview subclass by passing it a Form class,
+and pass that to your URLconf, like so:
+
+    (r'^post/$', MyFormPreview(MyForm)),
+
+The FormPreview class has a few other hooks. See the docstrings in the source
+code below.
+
+The framework also uses two templates: 'formtools/preview.html' and
+'formtools/form.html'. You can override these by setting 'preview_template' and
+'form_template' attributes on your FormPreview subclass. See
+django/contrib/formtools/templates for the default templates.
+"""
+
+from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+from django.http import Http404
+from django.shortcuts import render_to_response
+import cPickle as pickle
+import md5
+
+AUTO_ID = 'formtools_%s' # Each form here uses this as its auto_id parameter.
+
+class FormPreview(object):
+    preview_template = 'formtools/preview.html'
+    form_template = 'formtools/form.html'
+
+    # METHODS SUBCLASSES SHOULDN'T OVERRIDE ###################################
+
+    def __init__(self, form):
+        # form should be a Form class, not an instance.
+        self.form, self.state = form, {}
+
+    def __call__(self, request, *args, **kwargs):
+        stage = {'1': 'preview', '2': 'post'}.get(request.POST.get(self.unused_name('stage')), 'preview')
+        self.parse_params(*args, **kwargs)
+        try:
+            method = getattr(self, stage + '_' + request.method.lower())
+        except AttributeError:
+            raise Http404
+        return method(request)
+
+    def unused_name(self, name):
+        """
+        Given a first-choice name, adds an underscore to the name until it
+        reaches a name that isn't claimed by any field in the form.
+
+        This is calculated rather than being hard-coded so that no field names
+        are off-limits for use in the form.
+        """
+        while 1:
+            try:
+                f = self.form.fields[name]
+            except KeyError:
+                break # This field name isn't being used by the form.
+            name += '_'
+        return name
+
+    def preview_get(self, request):
+        "Displays the form"
+        f = self.form(auto_id=AUTO_ID)
+        return render_to_response(self.form_template, {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state})
+
+    def preview_post(self, request):
+        "Validates the POST data. If valid, displays the preview page. Else, redisplays form."
+        f = self.form(request.POST, auto_id=AUTO_ID)
+        context = {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state}
+        if f.is_valid():
+            context['hash_field'] = self.unused_name('hash')
+            context['hash_value'] = self.security_hash(request, f)
+            return render_to_response(self.preview_template, context)
+        else:
+            return render_to_response(self.form_template, context)
+
+    def post_post(self, request):
+        "Validates the POST data. If valid, calls done(). Else, redisplays form."
+        f = self.form(request.POST, auto_id=AUTO_ID)
+        if f.is_valid():
+            if self.security_hash(request, f) != request.POST.get(self.unused_name('hash')):
+                return self.failed_hash(request) # Security hash failed.
+            return self.done(request, f.clean_data)
+        else:
+            return render_to_response(self.form_template, {'form': f, 'stage_field': self.unused_name('stage'), 'state': self.state})
+
+    # METHODS SUBCLASSES MIGHT OVERRIDE IF APPROPRIATE ########################
+
+    def parse_params(self, *args, **kwargs):
+        """
+        Given captured args and kwargs from the URLconf, saves something in
+        self.state and/or raises Http404 if necessary.
+
+        For example, this URLconf captures a user_id variable:
+
+            (r'^contact/(?P<user_id>\d{1,6})/$', MyFormPreview(MyForm)),
+
+        In this case, the kwargs variable in parse_params would be
+        {'user_id': 32} for a request to '/contact/32/'. You can use that
+        user_id to make sure it's a valid user and/or save it for later, for
+        use in done().
+        """
+        pass
+
+    def security_hash(self, request, form):
+        """
+        Calculates the security hash for the given Form instance.
+
+        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
+        hash of that.
+
+        Subclasses may want to take into account request-specific information
+        such as the IP address.
+        """
+        data = [(bf.name, bf.data) for bf in form] + [settings.SECRET_KEY]
+        # Use HIGHEST_PROTOCOL because it's the most efficient. It requires
+        # Python 2.3, but Django requires 2.3 anyway, so that's OK.
+        pickled = pickle.dumps(data, protocol=pickle.HIGHEST_PROTOCOL)
+        return md5.new(pickled).hexdigest()
+
+    def failed_hash(self, request):
+        "Returns an HttpResponse in the case of an invalid security hash."
+        return self.preview_post(request)
+
+    # METHODS SUBCLASSES MUST OVERRIDE ########################################
+
+    def done(self, request, clean_data):
+        "Does something with the clean_data and returns an HttpResponseRedirect."
+        raise NotImplementedError('You must define a done() method on your %s subclass.' % self.__class__.__name__)

django/contrib/formtools/templates/formtools/form.html

+{% extends "base.html" %}
+
+{% block content %}
+
+{% if form.errors %}<h1>Please correct the following errors</h1>{% else %}<h1>Submit</h1>{% endif %}
+
+<form action="" method="post">
+<table>
+{{ form }}
+</table>
+<input type="hidden" name="{{ stage_field }}" value="1" />
+<p><input type="submit" value="Submit" /></p>
+</form>
+
+{% endblock %}

django/contrib/formtools/templates/formtools/preview.html

+{% extends "base.html" %}
+
+{% block content %}
+
+<h1>Preview your submission</h1>
+
+<table>
+{% for field in form %}
+<tr>
+<th>{{ field.verbose_name }}:</th>
+<td>{{ field.data|escape }}</td>
+</tr>
+{% endfor %}
+</table>
+
+<p>Security hash: {{ hash_value }}</p>
+
+<form action="" method="post">
+{% for field in form %}{{ field.as_hidden }}
+{% endfor %}
+<input type="hidden" name="{{ stage_field }}" value="2" />
+<input type="hidden" name="{{ hash_field }}" value="{{ hash_value }}" />
+<p><input type="submit" value="Submit" /></p>
+</form>
+
+<h1>Or edit it again</h1>
+
+<form action="" method="post">
+<table>
+{{ form }}
+</table>
+<input type="hidden" name="{{ stage_field }}" value="1" />
+<p><input type="submit" value="Submit changes" /></p>
+</form>
+
+{% endblock %}

django/contrib/sitemaps/__init__.py

 
     from django.contrib.sites.models import Site
     current_site = Site.objects.get_current()
-    url = "%s%s" % (current_site.domain, sitemap)
+    url = "%s%s" % (current_site.domain, sitemap_url)
     params = urllib.urlencode({'sitemap':url})
     urllib.urlopen("%s?%s" % (ping_url, params))
 

django/core/handlers/base.py

             if response:
                 return response
 
-        resolver = urlresolvers.RegexURLResolver(r'^/', settings.ROOT_URLCONF)
+        # Get urlconf from request object, if available.  Otherwise use default.
+        urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)
+
+        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
         try:
             callback, callback_args, callback_kwargs = resolver.resolve(request.path)
 
 
             # Complain if the view returned None (a common error).
             if response is None:
-                raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, callback.func_name)
+                try:
+                    view_name = callback.func_name # If it's a function
+                except AttributeError:
+                    view_name = callback.__class__.__name__ + '.__call__' # If it's a class
+                raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)
 
             return response
         except http.Http404, e:

django/core/handlers/wsgi.py

     data in the body.
     """
     if not size:
-        return copyfileobj(fsrc, fdst, length)
+        return
     while size > 0:
         buf = fsrc.read(min(length, size))
         if not buf:
             return self._raw_post_data
         except AttributeError:
             buf = StringIO()
-            # CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd)
-            content_length = int(self.environ.get('CONTENT_LENGTH', 0))
+            try:
+                # CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd)
+                content_length = int(self.environ.get('CONTENT_LENGTH', 0))
+            except ValueError: # if CONTENT_LENGTH was empty string or not an integer
+                content_length = 0
             safe_copyfileobj(self.environ['wsgi.input'], buf, size=content_length)
             self._raw_post_data = buf.getvalue()
             buf.close()

django/core/servers/fastcgi.py

     else:
         return fastcgi_help("ERROR: Implementation must be one of prefork or thread.")
 
+    wsgi_opts['debug'] = False # Turn off flup tracebacks
+
     # Prep up and go
     from django.core.handlers.wsgi import WSGIHandler
 

django/db/backends/postgresql/base.py

 try:
     Database.register_type(Database.new_type((1082,), "DATE", util.typecast_date))
 except AttributeError:
-    raise Exception, "You appear to be using psycopg version 2, which isn't supported yet, because it's still in beta. Use psycopg version 1 instead: http://initd.org/projects/psycopg1"
+    raise Exception, "You appear to be using psycopg version 2. Set your DATABASE_ENGINE to 'postgresql_psycopg2' instead of 'postgresql'."
 Database.register_type(Database.new_type((1083,1266), "TIME", util.typecast_time))
 Database.register_type(Database.new_type((1114,1184), "TIMESTAMP", util.typecast_timestamp))
 Database.register_type(Database.new_type((16,), "BOOLEAN", util.typecast_boolean))

django/db/models/fields/__init__.py

 from django.dispatch import dispatcher
 from django.conf import settings
 from django.core import validators
-from django import forms
+from django import oldforms
+from django import newforms as forms
 from django.core.exceptions import ObjectDoesNotExist
 from django.utils.functional import curry
 from django.utils.itercompat import tee
 
         if self.choices:
             if self.radio_admin:
-                field_objs = [forms.RadioSelectField]
+                field_objs = [oldforms.RadioSelectField]
                 params['ul_class'] = get_ul_class(self.radio_admin)
             else:
-                field_objs = [forms.SelectField]
+                field_objs = [oldforms.SelectField]
 
             params['choices'] = self.get_choices_default()
         else:
 
     def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
         """
-        Returns a list of forms.FormField instances for this field. It
+        Returns a list of oldforms.FormField instances for this field. It
         calculates the choices at runtime, not at compile time.
 
         name_prefix is a prefix to prepend to the "field_name" argument.
             return self._choices
     choices = property(_get_choices)
 
+    def formfield(self):
+        "Returns a django.newforms.Field instance for this database Field."
+        # TODO: This is just a temporary default during development.
+        return forms.CharField(required=not self.blank, label=capfirst(self.verbose_name))
+
 class AutoField(Field):
     empty_strings_allowed = False
     def __init__(self, *args, **kwargs):
         return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
 
     def get_manipulator_field_objs(self):
-        return [forms.HiddenField]
+        return [oldforms.HiddenField]
 
     def get_manipulator_new_data(self, new_data, rel=False):
         # Never going to be called
         super(AutoField, self).contribute_to_class(cls, name)
         cls._meta.has_auto_field = True
 
+    def formfield(self):
+        return None
+
 class BooleanField(Field):
     def __init__(self, *args, **kwargs):
         kwargs['blank'] = True
         raise validators.ValidationError, gettext("This value must be either True or False.")
 
     def get_manipulator_field_objs(self):
-        return [forms.CheckboxField]
+        return [oldforms.CheckboxField]
+
+    def formfield(self):
+        return forms.BooleanField(required=not self.blank, label=capfirst(self.verbose_name))
 
 class CharField(Field):
     def get_manipulator_field_objs(self):
-        return [forms.TextField]
+        return [oldforms.TextField]
 
     def to_python(self, value):
         if isinstance(value, basestring):
                 raise validators.ValidationError, gettext_lazy("This field cannot be null.")
         return str(value)
 
+    def formfield(self):
+        return forms.CharField(max_length=self.maxlength, required=not self.blank, label=capfirst(self.verbose_name))
+
 # TODO: Maybe move this into contrib, because it's specialized.
 class CommaSeparatedIntegerField(CharField):
     def get_manipulator_field_objs(self):
-        return [forms.CommaSeparatedIntegerField]
+        return [oldforms.CommaSeparatedIntegerField]
 
 class DateField(Field):
     empty_strings_allowed = False
 
     def get_db_prep_save(self, value):
         # Casts dates into string format for entry into database.
-        if isinstance(value, datetime.datetime):
-            value = value.date().strftime('%Y-%m-%d')
-        elif isinstance(value, datetime.date):
+        if value is not None:
             value = value.strftime('%Y-%m-%d')
         return Field.get_db_prep_save(self, value)
 
     def get_manipulator_field_objs(self):
-        return [forms.DateField]
+        return [oldforms.DateField]
 
     def flatten_data(self, follow, obj = None):
         val = self._get_val_from_obj(obj)
         return {self.attname: (val is not None and val.strftime("%Y-%m-%d") or '')}
 
+    def formfield(self):
+        return forms.DateField(required=not self.blank, label=capfirst(self.verbose_name))
+
 class DateTimeField(DateField):
     def to_python(self, value):
         if isinstance(value, datetime.datetime):
 
     def get_db_prep_save(self, value):
         # Casts dates into string format for entry into database.
-        if isinstance(value, datetime.datetime):
+        if value is not None:
             # MySQL will throw a warning if microseconds are given, because it
             # doesn't support microseconds.
             if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
                 value = value.replace(microsecond=0)
             value = str(value)
-        elif isinstance(value, datetime.date):
-            # MySQL will throw a warning if microseconds are given, because it
-            # doesn't support microseconds.
-            if settings.DATABASE_ENGINE == 'mysql' and hasattr(value, 'microsecond'):
-                value = datetime.datetime(value.year, value.month, value.day, microsecond=0)
-            value = str(value)
-            
         return Field.get_db_prep_save(self, value)
 
     def get_db_prep_lookup(self, lookup_type, value):
         return Field.get_db_prep_lookup(self, lookup_type, value)
 
     def get_manipulator_field_objs(self):
-        return [forms.DateField, forms.TimeField]
+        return [oldforms.DateField, oldforms.TimeField]
 
     def get_manipulator_field_names(self, name_prefix):
         return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
         return {date_field: (val is not None and val.strftime("%Y-%m-%d") or ''),
                 time_field: (val is not None and val.strftime("%H:%M:%S") or '')}
 
+    def formfield(self):
+        return forms.DateTimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
 class EmailField(CharField):
     def __init__(self, *args, **kwargs):
         kwargs['maxlength'] = 75
         return "CharField"
 
     def get_manipulator_field_objs(self):
-        return [forms.EmailField]
+        return [oldforms.EmailField]
 
     def validate(self, field_data, all_data):
         validators.isValidEmail(field_data, all_data)
 
+    def formfield(self):
+        return forms.EmailField(required=not self.blank, label=capfirst(self.verbose_name))
+
 class FileField(Field):
     def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs):
         self.upload_to = upload_to
                 os.remove(file_name)
 
     def get_manipulator_field_objs(self):
-        return [forms.FileUploadField, forms.HiddenField]
+        return [oldforms.FileUploadField, oldforms.HiddenField]
 
     def get_manipulator_field_names(self, name_prefix):
         return [name_prefix + self.name + '_file', name_prefix + self.name]
         Field.__init__(self, verbose_name, name, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [curry(forms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
+        return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
 
 class FloatField(Field):
     empty_strings_allowed = False
         Field.__init__(self, verbose_name, name, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [curry(forms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
+        return [curry(oldforms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
 
 class ImageField(FileField):
     def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
         FileField.__init__(self, verbose_name, name, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [forms.ImageUploadField, forms.HiddenField]
+        return [oldforms.ImageUploadField, oldforms.HiddenField]
 
     def contribute_to_class(self, cls, name):
         super(ImageField, self).contribute_to_class(cls, name)
 class IntegerField(Field):
     empty_strings_allowed = False
     def get_manipulator_field_objs(self):
-        return [forms.IntegerField]
+        return [oldforms.IntegerField]
+
+    def formfield(self):
+        return forms.IntegerField(required=not self.blank, label=capfirst(self.verbose_name))
 
 class IPAddressField(Field):
     def __init__(self, *args, **kwargs):
         Field.__init__(self, *args, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [forms.IPAddressField]
+        return [oldforms.IPAddressField]
 
     def validate(self, field_data, all_data):
         validators.isValidIPAddress4(field_data, None)
         Field.__init__(self, *args, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [forms.NullBooleanField]
+        return [oldforms.NullBooleanField]
 
 class PhoneNumberField(IntegerField):
     def get_manipulator_field_objs(self):
-        return [forms.PhoneNumberField]
+        return [oldforms.PhoneNumberField]
 
     def validate(self, field_data, all_data):
         validators.isValidPhone(field_data, all_data)
 
 class PositiveIntegerField(IntegerField):
     def get_manipulator_field_objs(self):
-        return [forms.PositiveIntegerField]
+        return [oldforms.PositiveIntegerField]
 
 class PositiveSmallIntegerField(IntegerField):
     def get_manipulator_field_objs(self):
-        return [forms.PositiveSmallIntegerField]
+        return [oldforms.PositiveSmallIntegerField]
 
 class SlugField(Field):
     def __init__(self, *args, **kwargs):
         Field.__init__(self, *args, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [forms.TextField]
+        return [oldforms.TextField]
 
 class SmallIntegerField(IntegerField):
     def get_manipulator_field_objs(self):
-        return [forms.SmallIntegerField]
+        return [oldforms.SmallIntegerField]
 
 class TextField(Field):
     def get_manipulator_field_objs(self):
-        return [forms.LargeTextField]
+        return [oldforms.LargeTextField]
 
 class TimeField(Field):
     empty_strings_allowed = False
         return Field.get_db_prep_save(self, value)
 
     def get_manipulator_field_objs(self):
-        return [forms.TimeField]
+        return [oldforms.TimeField]
 
     def flatten_data(self,follow, obj = None):
         val = self._get_val_from_obj(obj)
         return {self.attname: (val is not None and val.strftime("%H:%M:%S") or '')}
 
+    def formfield(self):
+        return forms.TimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
 class URLField(Field):
     def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
         if verify_exists:
             kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
+        self.verify_exists = verify_exists
         Field.__init__(self, verbose_name, name, **kwargs)
 
     def get_manipulator_field_objs(self):
-        return [forms.URLField]
+        return [oldforms.URLField]
+
+    def formfield(self):
+        return forms.URLField(required=not self.blank, verify_exists=self.verify_exists, label=capfirst(self.verbose_name))
 
 class USStateField(Field):
     def get_manipulator_field_objs(self):
-        return [forms.USStateField]
+        return [oldforms.USStateField]
 
 class XMLField(TextField):
     def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs):
         return "TextField"
 
     def get_manipulator_field_objs(self):
-        return [curry(forms.XMLLargeTextField, schema_path=self.schema_path)]
+        return [curry(oldforms.XMLLargeTextField, schema_path=self.schema_path)]
 
 class OrderingField(IntegerField):
     empty_strings_allowed=False
         return "IntegerField"
 
     def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
-        return [forms.HiddenField(name_prefix + self.name)]
+        return [oldforms.HiddenField(name_prefix + self.name)]

django/db/models/fields/generic.py

 Classes allowing "generic" relations through ContentType and object-id fields.
 """
 
-from django import forms
+from django import oldforms
 from django.core.exceptions import ObjectDoesNotExist
 from django.db import backend
 from django.db.models import signals
 
     def get_manipulator_field_objs(self):
         choices = self.get_choices_default()
-        return [curry(forms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
+        return [curry(oldforms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
 
     def get_choices_default(self):
         return Field.get_choices(self, include_blank=False)

django/db/models/fields/related.py

 from django.utils.translation import gettext_lazy, string_concat, ngettext
 from django.utils.functional import curry
 from django.core import validators
-from django import forms
+from django import oldforms
 from django.dispatch import dispatcher
 
 # For Python 2.3
         # Otherwise, just move the named objects into the set.
         if self.related.field.null:
             manager.clear()
-        for obj in value:
-            manager.add(obj)
+        manager.add(*value)
 
 def create_many_related_manager(superclass):
     """Creates a manager that subclasses 'superclass' (which is a Manager)
             # *objs - objects to add
             from django.db import connection
 
-            # Add the newly created or already existing objects to the join table.
-            # First find out which items are already added, to avoid adding them twice
-            new_ids = set([obj._get_pk_val() for obj in objs])
-            cursor = connection.cursor()
-            cursor.execute("SELECT %s FROM %s WHERE %s = %%s AND %s IN (%s)" % \
-                (target_col_name, self.join_table, source_col_name,
-                target_col_name, ",".join(['%s'] * len(new_ids))),
-                [self._pk_val] + list(new_ids))
-            if cursor.rowcount is not None and cursor.rowcount != 0:
-                existing_ids = set([row[0] for row in cursor.fetchmany(cursor.rowcount)])
-            else:
-                existing_ids = set()
+            # If there aren't any objects, there is nothing to do.
+            if objs:
+                # Check that all the objects are of the right type
+                for obj in objs:
+                    if not isinstance(obj, self.model):
+                        raise ValueError, "objects to add() must be %s instances" % self.model._meta.object_name
+                # Add the newly created or already existing objects to the join table.
+                # First find out which items are already added, to avoid adding them twice
+                new_ids = set([obj._get_pk_val() for obj in objs])
+                cursor = connection.cursor()
+                cursor.execute("SELECT %s FROM %s WHERE %s = %%s AND %s IN (%s)" % \
+                    (target_col_name, self.join_table, source_col_name,
+                    target_col_name, ",".join(['%s'] * len(new_ids))),
+                    [self._pk_val] + list(new_ids))
+                if cursor.rowcount is not None and cursor.rowcount != 0:
+                    existing_ids = set([row[0] for row in cursor.fetchmany(cursor.rowcount)])
+                else:
+                    existing_ids = set()
 
-            # Add the ones that aren't there already
-            for obj_id in (new_ids - existing_ids):
-                cursor.execute("INSERT INTO %s (%s, %s) VALUES (%%s, %%s)" % \
-                    (self.join_table, source_col_name, target_col_name),
-                    [self._pk_val, obj_id])
-            transaction.commit_unless_managed()
+                # Add the ones that aren't there already
+                for obj_id in (new_ids - existing_ids):
+                    cursor.execute("INSERT INTO %s (%s, %s) VALUES (%%s, %%s)" % \
+                        (self.join_table, source_col_name, target_col_name),
+                        [self._pk_val, obj_id])
+                transaction.commit_unless_managed()
 
         def _remove_items(self, source_col_name, target_col_name, *objs):
             # source_col_name: the PK colname in join_table for the source object
             # *objs - objects to remove
             from django.db import connection
 
-            for obj in objs:
-                if not isinstance(obj, self.model):
-                    raise ValueError, "objects to remove() must be %s instances" % self.model._meta.object_name
-            # Remove the specified objects from the join table
-            cursor = connection.cursor()
-            for obj in objs:
-                cursor.execute("DELETE FROM %s WHERE %s = %%s AND %s = %%s" % \
-                    (self.join_table, source_col_name, target_col_name),
-                    [self._pk_val, obj._get_pk_val()])
-            transaction.commit_unless_managed()
+            # If there aren't any objects, there is nothing to do.
+            if objs:
+                # Check that all the objects are of the right type
+                for obj in objs:
+                    if not isinstance(obj, self.model):
+                        raise ValueError, "objects to remove() must be %s instances" % self.model._meta.object_name
+                # Remove the specified objects from the join table
+                old_ids = set([obj._get_pk_val() for obj in objs])
+                cursor = connection.cursor()
+                cursor.execute("DELETE FROM %s WHERE %s = %%s AND %s IN (%s)" % \
+                    (self.join_table, source_col_name, 
+                    target_col_name, ",".join(['%s'] * len(old_ids))),
+                    [self._pk_val] + list(old_ids))
+                transaction.commit_unless_managed()
 
         def _clear_items(self, source_col_name):
             # source_col_name: the PK colname in join_table for the source object
 
         manager = self.__get__(instance)
         manager.clear()
-        for obj in value:
-            manager.add(obj)
+        manager.add(*value)
 
 class ReverseManyRelatedObjectsDescriptor(object):
     # This class provides the functionality that makes the related-object
 
         manager = self.__get__(instance)
         manager.clear()
-        for obj in value:
-            manager.add(obj)
+        manager.add(*value)
 
 class ForeignKey(RelatedField, Field):
     empty_strings_allowed = False
             params['validator_list'].append(curry(manipulator_valid_rel_key, self, manipulator))
         else:
             if self.radio_admin:
-                field_objs = [forms.RadioSelectField]
+                field_objs = [oldforms.RadioSelectField]
                 params['ul_class'] = get_ul_class(self.radio_admin)
             else:
                 if self.null:
-                    field_objs = [forms.NullSelectField]
+                    field_objs = [oldforms.NullSelectField]
                 else:
-                    field_objs = [forms.SelectField]
+                    field_objs = [oldforms.SelectField]
             params['choices'] = self.get_choices_default()
         return field_objs, params
 
         if self.rel.raw_id_admin and not isinstance(rel_field, AutoField):
             return rel_field.get_manipulator_field_objs()
         else:
-            return [forms.IntegerField]
+            return [oldforms.IntegerField]
 
     def get_db_prep_save(self, value):
         if value == '' or value == None:
             params['validator_list'].append(curry(manipulator_valid_rel_key, self, manipulator))
         else:
             if self.radio_admin:
-                field_objs = [forms.RadioSelectField]
+                field_objs = [oldforms.RadioSelectField]
                 params['ul_class'] = get_ul_class(self.radio_admin)
             else:
                 if self.null:
-                    field_objs = [forms.NullSelectField]
+                    field_objs = [oldforms.NullSelectField]
                 else:
-                    field_objs = [forms.SelectField]
+                    field_objs = [oldforms.SelectField]
             params['choices'] = self.get_choices_default()
         return field_objs, params
 
 
     def get_manipulator_field_objs(self):
         if self.rel.raw_id_admin:
-            return [forms.RawIdAdminField]
+            return [oldforms.RawIdAdminField]
         else:
             choices = self.get_choices_default()
-            return [curry(forms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
+            return [curry(oldforms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
 
     def get_choices_default(self):
         return Field.get_choices(self, include_blank=False)

django/db/models/manipulators.py

 from django.core.exceptions import ObjectDoesNotExist
-from django import forms
+from django import oldforms
 from django.core import validators
 from django.db.models.fields import FileField, AutoField
 from django.dispatch import dispatcher
                 self.man._prepare(model)
             return self.man
 
-class AutomaticManipulator(forms.Manipulator):
+class AutomaticManipulator(oldforms.Manipulator):
     def _prepare(cls, model):
         cls.model = model
         cls.manager = model._default_manager
 
         # Add field for ordering.
         if self.change and self.opts.get_ordered_objects():
-            self.fields.append(forms.CommaSeparatedIntegerField(field_name="order_"))
+            self.fields.append(oldforms.CommaSeparatedIntegerField(field_name="order_"))
 
     def save(self, new_data):
         # TODO: big cleanup when core fields go -> use recursive manipulators.
 def manipulator_validator_unique_for_date(from_field, date_field, opts, lookup_type, self, field_data, all_data):
     from django.db.models.fields.related import ManyToOneRel
     date_str = all_data.get(date_field.get_manipulator_field_names('')[0], None)
-    date_val = forms.DateField.html2python(date_str)
+    date_val = oldforms.DateField.html2python(date_str)
     if date_val is None:
         return # Date was invalid. This will be caught by another validator.
     lookup_kwargs = {'%s__year' % date_field.name: date_val.year}

django/forms/__init__.py

-from django.core import validators
-from django.core.exceptions import PermissionDenied
-from django.utils.html import escape
-from django.conf import settings
-from django.utils.translation import gettext, ngettext
-
-FORM_FIELD_ID_PREFIX = 'id_'
-
-class EmptyValue(Exception):
-    "This is raised when empty data is provided"
-    pass
-
-class Manipulator(object):
-    # List of permission strings. User must have at least one to manipulate.
-    # None means everybody has permission.
-    required_permission = ''
-
-    def __init__(self):
-        # List of FormField objects
-        self.fields = []
-
-    def __getitem__(self, field_name):
-        "Looks up field by field name; raises KeyError on failure"
-        for field in self.fields:
-            if field.field_name == field_name:
-                return field
-        raise KeyError, "Field %s not found\n%s" % (field_name, repr(self.fields))
-
-    def __delitem__(self, field_name):
-        "Deletes the field with the given field name; raises KeyError on failure"
-        for i, field in enumerate(self.fields):
-            if field.field_name == field_name:
-                del self.fields[i]
-                return
-        raise KeyError, "Field %s not found" % field_name
-
-    def check_permissions(self, user):
-        """Confirms user has required permissions to use this manipulator; raises
-        PermissionDenied on failure."""
-        if self.required_permission is None:
-            return
-        if user.has_perm(self.required_permission):
-            return
-        raise PermissionDenied
-
-    def prepare(self, new_data):
-        """
-        Makes any necessary preparations to new_data, in place, before data has
-        been validated.
-        """
-        for field in self.fields:
-            field.prepare(new_data)
-
-    def get_validation_errors(self, new_data):
-        "Returns dictionary mapping field_names to error-message lists"
-        errors = {}
-        self.prepare(new_data)
-        for field in self.fields:
-            errors.update(field.get_validation_errors(new_data))
-            val_name = 'validate_%s' % field.field_name
-            if hasattr(self, val_name):
-                val = getattr(self, val_name)
-                try:
-                    field.run_validator(new_data, val)
-                except (validators.ValidationError, validators.CriticalValidationError), e:
-                    errors.setdefault(field.field_name, []).extend(e.messages)
-
-#            if field.is_required and not new_data.get(field.field_name, False):
-#                errors.setdefault(field.field_name, []).append(gettext_lazy('This field is required.'))
-#                continue
-#            try:
-#                validator_list = field.validator_list
-#                if hasattr(self, 'validate_%s' % field.field_name):
-#                    validator_list.append(getattr(self, 'validate_%s' % field.field_name))
-#                for validator in validator_list:
-#                    if field.is_required or new_data.get(field.field_name, False) or hasattr(validator, 'always_test'):
-#                        try:
-#                            if hasattr(field, 'requires_data_list'):
-#                                validator(new_data.getlist(field.field_name), new_data)
-#                            else:
-#                                validator(new_data.get(field.field_name, ''), new_data)
-#                        except validators.ValidationError, e:
-#                            errors.setdefault(field.field_name, []).extend(e.messages)
-#            # If a CriticalValidationError is raised, ignore any other ValidationErrors
-#            # for this particular field
-#            except validators.CriticalValidationError, e:
-#                errors.setdefault(field.field_name, []).extend(e.messages)
-        return errors
-
-    def save(self, new_data):
-        "Saves the changes and returns the new object"
-        # changes is a dictionary-like object keyed by field_name
-        raise NotImplementedError
-
-    def do_html2python(self, new_data):
-        """
-        Convert the data from HTML data types to Python datatypes, changing the
-        object in place. This happens after validation but before storage. This
-        must happen after validation because html2python functions aren't
-        expected to deal with invalid input.
-        """
-        for field in self.fields:
-            field.convert_post_data(new_data)
-
-class FormWrapper(object):
-    """
-    A wrapper linking a Manipulator to the template system.
-    This allows dictionary-style lookups of formfields. It also handles feeding
-    prepopulated data and validation error messages to the formfield objects.
-    """
-    def __init__(self, manipulator, data=None, error_dict=None, edit_inline=True):
-        self.manipulator = manipulator
-        if data is None:
-            data = {}
-        if error_dict is None:
-            error_dict = {}
-        self.data = data
-        self.error_dict = error_dict
-        self._inline_collections = None
-        self.edit_inline = edit_inline
-
-    def __repr__(self):
-        return repr(self.__dict__)
-
-    def __getitem__(self, key):
-        for field in self.manipulator.fields:
-            if field.field_name == key:
-                data = field.extract_data(self.data)
-                return FormFieldWrapper(field, data, self.error_dict.get(field.field_name, []))
-        if self.edit_inline:
-            self.fill_inline_collections()
-            for inline_collection in self._inline_collections:
-                if inline_collection.name == key:
-                    return inline_collection
-        raise KeyError, "Could not find Formfield or InlineObjectCollection named %r" % key
-
-    def fill_inline_collections(self):
-        if not self._inline_collections:
-            ic = []
-            related_objects = self.manipulator.get_related_objects()
-            for rel_obj in related_objects:
-                data = rel_obj.extract_data(self.data)
-                inline_collection = InlineObjectCollection(self.manipulator, rel_obj, data, self.error_dict)
-                ic.append(inline_collection)
-            self._inline_collections = ic
-
-    def has_errors(self):
-        return self.error_dict != {}
-
-    def _get_fields(self):
-        try:
-            return self._fields
-        except AttributeError:
-            self._fields = [self.__getitem__(field.field_name) for field in self.manipulator.fields]
-            return self._fields
-
-    fields = property(_get_fields)
-
-class FormFieldWrapper(object):
-    "A bridge between the template system and an individual form field. Used by FormWrapper."
-    def __init__(self, formfield, data, error_list):
-        self.formfield, self.data, self.error_list = formfield, data, error_list
-        self.field_name = self.formfield.field_name # for convenience in templates
-
-    def __str__(self):
-        "Renders the field"
-        return str(self.formfield.render(self.data))
-
-    def __repr__(self):
-        return '<FormFieldWrapper for "%s">' % self.formfield.field_name
-
-    def field_list(self):
-        """
-        Like __str__(), but returns a list. Use this when the field's render()
-        method returns a list.
-        """
-        return self.formfield.render(self.data)
-
-    def errors(self):
-        return self.error_list
-
-    def html_error_list(self):
-        if self.errors():
-            return '<ul class="errorlist"><li>%s</li></ul>' % '</li><li>'.join([escape(e) for e in self.errors()])
-        else:
-            return ''
-
-    def get_id(self):
-        return self.formfield.get_id()
-
-class FormFieldCollection(FormFieldWrapper):
-    "A utility class that gives the template access to a dict of FormFieldWrappers"
-    def __init__(self, formfield_dict):
-        self.formfield_dict = formfield_dict
-
-    def __str__(self):
-        return str(self.formfield_dict)
-
-    def __getitem__(self, template_key):
-        "Look up field by template key; raise KeyError on failure"
-        return self.formfield_dict[template_key]
-
-    def __repr__(self):
-        return "<FormFieldCollection: %s>" % self.formfield_dict
-
-    def errors(self):
-        "Returns list of all errors in this collection's formfields"
-        errors = []
-        for field in self.formfield_dict.values():
-            if hasattr(field, 'errors'):
-                errors.extend(field.errors())
-        return errors
-
-    def has_errors(self):
-        return bool(len(self.errors()))
-
-    def html_combined_error_list(self):
-        return ''.join([field.html_error_list() for field in self.formfield_dict.values() if hasattr(field, 'errors')])
-
-class InlineObjectCollection(object):
-    "An object that acts like a sparse list of form field collections."
-    def __init__(self, parent_manipulator, rel_obj, data, errors):
-        self.parent_manipulator = parent_manipulator
-        self.rel_obj = rel_obj
-        self.data = data
-        self.errors = errors
-        self._collections = None
-        self.name = rel_obj.name
-
-    def __len__(self):
-        self.fill()
-        return self._collections.__len__()
-
-    def __getitem__(self, k):
-        self.fill()
-        return self._collections.__getitem__(k)
-
-    def __setitem__(self, k, v):
-        self.fill()
-        return self._collections.__setitem__(k,v)
-
-    def __delitem__(self, k):
-        self.fill()
-        return self._collections.__delitem__(k)
-
-    def __iter__(self):
-        self.fill()
-        return iter(self._collections.values())
-
-    def items(self):
-        self.fill()
-        return self._collections.items()
-
-    def fill(self):
-        if self._collections:
-            return
-        else:
-            var_name = self.rel_obj.opts.object_name.lower()
-            collections = {}
-            orig = None
-            if hasattr(self.parent_manipulator, 'original_object'):
-                orig = self.parent_manipulator.original_object
-            orig_list = self.rel_obj.get_list(orig)
-
-            for i, instance in enumerate(orig_list):
-                collection = {'original': instance}
-                for f in self.rel_obj.editable_fields():
-                    for field_name in f.get_manipulator_field_names(''):
-                        full_field_name = '%s.%d.%s' % (var_name, i, field_name)
-                        field = self.parent_manipulator[full_field_name]
-                        data = field.extract_data(self.data)
-                        errors = self.errors.get(full_field_name, [])
-                        collection[field_name] = FormFieldWrapper(field, data, errors)
-                collections[i] = FormFieldCollection(collection)
-            self._collections = collections
-
-
-class FormField(object):
-    """Abstract class representing a form field.
-
-    Classes that extend FormField should define the following attributes:
-        field_name
-            The field's name for use by programs.
-        validator_list
-            A list of validation tests (callback functions) that the data for
-            this field must pass in order to be added or changed.
-        is_required
-            A Boolean. Is it a required field?
-    Subclasses should also implement a render(data) method, which is responsible
-    for rending the form field in XHTML.
-    """
-    def __str__(self):
-        return self.render('')
-
-    def __repr__(self):
-        return 'FormField "%s"' % self.field_name
-
-    def prepare(self, new_data):
-        "Hook for doing something to new_data (in place) before validation."
-        pass
-
-    def html2python(data):
-        "Hook for converting an HTML datatype (e.g. 'on' for checkboxes) to a Python type"
-        return data
-    html2python = staticmethod(html2python)
-
-    def render(self, data):
-        raise NotImplementedError
-
-    def get_member_name(self):
-        if hasattr(self, 'member_name'):
-            return self.member_name
-        else:
-            return self.field_name
-
-    def extract_data(self, data_dict):
-        if hasattr(self, 'requires_data_list') and hasattr(data_dict, 'getlist'):
-            data = data_dict.getlist(self.get_member_name())
-        else:
-            data = data_dict.get(self.get_member_name(), None)
-        if data is None:
-            data = ''
-        return data
-
-    def convert_post_data(self, new_data):
-        name = self.get_member_name()
-        if new_data.has_key(self.field_name):
-            d = new_data.getlist(self.field_name)
-            try:
-                converted_data = [self.__class__.html2python(data) for data in d]
-            except ValueError:
-                converted_data = d
-            new_data.setlist(name, converted_data)
-        else:
-            try:
-                #individual fields deal with None values themselves
-                new_data.setlist(name, [self.__class__.html2python(None)])
-            except EmptyValue:
-                new_data.setlist(name, [])
-
-
-    def run_validator(self, new_data, validator):
-        if self.is_required or new_data.get(self.field_name, False) or hasattr(validator, 'always_test'):
-            if hasattr(self, 'requires_data_list'):
-                validator(new_data.getlist(self.field_name), new_data)
-            else:
-                validator(new_data.get(self.field_name, ''), new_data)
-
-    def get_validation_errors(self, new_data):
-        errors = {}
-        if self.is_required and not new_data.get(self.field_name, False):
-            errors.setdefault(self.field_name, []).append(gettext('This field is required.'))
-            return errors
-        try:
-            for validator in self.validator_list:
-                try:
-                    self.run_validator(new_data, validator)
-                except validators.ValidationError, e:
-                    errors.setdefault(self.field_name, []).extend(e.messages)
-        # If a CriticalValidationError is raised, ignore any other ValidationErrors
-        # for this particular field
-        except validators.CriticalValidationError, e:
-            errors.setdefault(self.field_name, []).extend(e.messages)
-        return errors
-
-    def get_id(self):
-        "Returns the HTML 'id' attribute for this form field."
-        return FORM_FIELD_ID_PREFIX + self.field_name
-
-####################
-# GENERIC WIDGETS  #
-####################
-
-class TextField(FormField):
-    input_type = "text"
-    def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=None, member_name=None):
-        if validator_list is None: validator_list = []
-        self.field_name = field_name
-        self.length, self.maxlength = length, maxlength
-        self.is_required = is_required
-        self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
-        if member_name != None:
-            self.member_name = member_name
-
-    def isValidLength(self, data, form):
-        if data and self.maxlength and len(data.decode(settings.DEFAULT_CHARSET)) > self.maxlength:
-            raise validators.ValidationError, ngettext("Ensure your text is less than %s character.",
-                "Ensure your text is less than %s characters.", self.maxlength) % self.maxlength
-
-    def hasNoNewlines(self, data, form):
-        if data and '\n' in data:
-            raise validators.ValidationError, gettext("Line breaks are not allowed here.")
-
-    def render(self, data):
-        if data is None:
-            data = ''
-        maxlength = ''
-        if self.maxlength:
-            maxlength = 'maxlength="%s" ' % self.maxlength
-        if isinstance(data, unicode):
-            data = data.encode(settings.DEFAULT_CHARSET)
-        return '<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
-            (self.input_type, self.get_id(), self.__class__.__name__, self.is_required and ' required' or '',
-            self.field_name, self.length, escape(data), maxlength)
-
-    def html2python(data):
-        return data
-    html2python = staticmethod(html2python)
-
-class PasswordField(TextField):
-    input_type = "password"
-
-class LargeTextField(TextField):
-    def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_list=None, maxlength=None):
-        if validator_list is None: validator_list = []
-        self.field_name = field_name
-        self.rows, self.cols, self.is_required = rows, cols, is_required
-        self.validator_list = validator_list[:]
-        if maxlength:
-            self.validator_list.append(self.isValidLength)
-            self.maxlength = maxlength
-
-    def render(self, data):
-        if data is None:
-            data = ''
-        if isinstance(data, unicode):
-            data = data.encode(settings.DEFAULT_CHARSET)
-        return '<textarea id="%s" class="v%s%s" name="%s" rows="%s" cols="%s">%s</textarea>' % \
-            (self.get_id(), self.__class__.__name__, self.is_required and ' required' or '',
-            self.field_name, self.rows, self.cols, escape(data))
-
-class HiddenField(FormField):
-    def __init__(self, field_name, is_required=False, validator_list=None):
-        if validator_list is None: validator_list = []
-        self.field_name, self.is_required = field_name, is_required
-        self.validator_list = validator_list[:]
-
-    def render(self, data):
-        return '<input type="hidden" id="%s" name="%s" value="%s" />' % \
-            (self.get_id(), self.field_name, escape(data))
-
-class CheckboxField(FormField):
-    def __init__(self, field_name, checked_by_default=False, validator_list=None, is_required=False):
-        if validator_list is None: validator_list = []
-        self.field_name = field_name
-        self.checked_by_default = checked_by_default
-        self.is_required = is_required
-        self.validator_list = validator_list[:]
-
-    def render(self, data):
-        checked_html = ''
-        if data or (data is '' and self.checked_by_default):
-            checked_html = ' checked="checked"'
-        return '<input type="checkbox" id="%s" class="v%s" name="%s"%s />' % \
-            (self.get_id(), self.__class__.__name__,
-            self.field_name, checked_html)
-
-    def html2python(data):
-        "Convert value from browser ('on' or '') to a Python boolean"
-        if data == 'on':
-            return True
-        return False
-    html2python = staticmethod(html2python)
-
-class SelectField(FormField):
-    def __init__(self, field_name, choices=None, size=1, is_required=False, validator_list=None, member_name=None):
-        if validator_list is None: validator_list = []
-        if choices is None: choices = []
-        self.field_name = field_name
-        # choices is a list of (value, human-readable key) tuples because order matters
-        self.choices, self.size, self.is_required = choices, size, is_required
-        self.validator_list = [self.isValidChoice] + validator_list
-        if member_name != None:
-            self.member_name = member_name
-
-    def render(self, data):
-        output = ['<select id="%s" class="v%s%s" name="%s" size="%s">' % \
-            (self.get_id(), self.__class__.__name__,
-             self.is_required and ' required' or '', self.field_name, self.size)]
-        str_data = str(data) # normalize to string
-        for value, display_name in self.choices:
-            selected_html = ''
-            if str(value) == str_data:
-                selected_html = ' selected="selected"'
-            output.append('    <option value="%s"%s>%s</option>' % (escape(value), selected_html, escape(display_name)))
-        output.append('  </select>')
-        return '\n'.join(output)
-
-    def isValidChoice(self, data, form):
-        str_data = str(data)
-        str_choices = [str(item[0]) for item in self.choices]
-        if str_data not in str_choices:
-            raise validators.ValidationError, gettext("Select a valid choice; '%(data)s' is not in %(choices)s.") % {'data': str_data, 'choices': str_choices}
-
-class NullSelectField(SelectField):
-    "This SelectField converts blank fields to None"
-    def html2python(data):
-        if not data:
-            return None
-        return data
-    html2python = staticmethod(html2python)
-
-class RadioSelectField(FormField):
-    def __init__(self, field_name, choices=None, ul_class='', is_required=False, validator_list=None, member_name=None):
-        if validator_list is None: validator_list = []
-        if choices is None: choices = []
-        self.field_name = field_name
-        # choices is a list of (value, human-readable key) tuples because order matters
-        self.choices, self.is_required = choices, is_required
-        self.validator_list = [self.isValidChoice] + validator_list
-        self.ul_class = ul_class
-        if member_name != None:
-            self.member_name = member_name
-
-    def render(self, data):
-        """
-        Returns a special object, RadioFieldRenderer, that is iterable *and*
-        has a default str() rendered output.
-
-        This allows for flexible use in templates. You can just use the default
-        rendering:
-
-            {{ field_name }}
-
-        ...which will output the radio buttons in an unordered list.
-        Or, you can manually traverse each radio option for special layout:
-
-            {% for option in field_name.field_list %}
-                {{ option.field }} {{ option.label }}<br />
-            {% endfor %}
-        """
-        class RadioFieldRenderer:
-            def __init__(self, datalist, ul_class):
-                self.datalist, self.ul_class = datalist, ul_class
-            def __str__(self):
-                "Default str() output for this radio field -- a <ul>"
-                output = ['<ul%s>' % (self.ul_class and ' class="%s"' % self.ul_class or '')]
-                output.extend(['<li>%s %s</li>' % (d['field'], d['label']) for d in self.datalist])
-                output.append('</ul>')
-                return ''.join(output)
-            def __iter__(self):
-                for d in self.datalist:
-                    yield d
-            def __len__(self):
-                return len(self.datalist)
-        datalist = []
-        str_data = str(data) # normalize to string
-        for i, (value, display_name) in enumerate(self.choices):
-            selected_html = ''
-            if str(value) == str_data:
-                selected_html = ' checked="checked"'
-            datalist.append({
-                'value': value,
-                'name': display_name,
-                'field': '<input type="radio" id="%s" name="%s" value="%s"%s/>' % \
-                    (self.get_id() + '_' + str(i), self.field_name, value, selected_html),
-                'label': '<label for="%s">%s</label>' % \
-                    (self.get_id() + '_' + str(i), display_name),
-            })
-        return RadioFieldRenderer(datalist, self.ul_class)
-
-    def isValidChoice(self, data, form):