Index: django/django/db/models/sql/query.py
===================================================================
--- django/django/db/models/sql/query.py	(revision 7999)
+++ django/django/db/models/sql/query.py	(working copy)
@@ -7,7 +7,6 @@
 all about the internals of models in order to get the information it needs.
 """
 
-import datetime
 from copy import deepcopy
 
 from django.utils.tree import Node
Index: django/django/db/models/base.py
===================================================================
--- django/django/db/models/base.py	(revision 7999)
+++ django/django/db/models/base.py	(working copy)
@@ -12,7 +12,7 @@
 import django.db.models.manager         # Ditto.
 from django.core import validators
 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
-from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
+from django.db.models.fields import AutoField, ImageField
 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
 from django.db.models.query import delete_objects, Q, CollectedObjects
 from django.db.models.options import Options
@@ -20,7 +20,6 @@
 from django.db.models import signals
 from django.db.models.loading import register_models, get_model
 from django.dispatch import dispatcher
-from django.utils.datastructures import SortedDict
 from django.utils.functional import curry
 from django.utils.encoding import smart_str, force_unicode, smart_unicode
 from django.core.files.move import file_move_safe
Index: django/django/db/models/fields/related.py
===================================================================
--- django/django/db/models/fields/related.py	(revision 7999)
+++ django/django/db/models/fields/related.py	(working copy)
@@ -3,10 +3,8 @@
 from django.db.models.fields import AutoField, Field, IntegerField, PositiveIntegerField, PositiveSmallIntegerField, FieldDoesNotExist
 from django.db.models.related import RelatedObject
 from django.db.models.query_utils import QueryWrapper
-from django.utils.text import capfirst
 from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _
 from django.utils.functional import curry
-from django.utils.encoding import smart_unicode
 from django.core import validators
 from django import oldforms
 from django import forms
Index: django/django/db/models/__init__.py
===================================================================
--- django/django/db/models/__init__.py	(revision 7999)
+++ django/django/db/models/__init__.py	(working copy)
@@ -10,8 +10,6 @@
 from django.db.models.fields.subclassing import SubfieldBase
 from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED
 from django.db.models import signals
-from django.utils.functional import curry
-from django.utils.text import capfirst
 
 # Admin stages.
 ADD, CHANGE, BOTH = 1, 2, 3
Index: django/django/db/backends/oracle/base.py
===================================================================
--- django/django/db/backends/oracle/base.py	(revision 7999)
+++ django/django/db/backends/oracle/base.py	(working copy)
@@ -8,7 +8,6 @@
 
 from django.db.backends import BaseDatabaseWrapper, BaseDatabaseFeatures, BaseDatabaseOperations, util
 from django.db.backends.oracle import query
-from django.utils.datastructures import SortedDict
 from django.utils.encoding import smart_str, force_unicode
 
 # Oracle takes client-side character set encoding from the environment.
Index: django/django/forms/util.py
===================================================================
--- django/django/forms/util.py	(revision 7999)
+++ django/django/forms/util.py	(working copy)
@@ -1,6 +1,5 @@
 from django.utils.html import escape
 from django.utils.encoding import smart_unicode, StrAndUnicode, force_unicode
-from django.utils.functional import Promise
 from django.utils.safestring import mark_safe
 
 def flatatt(attrs):
Index: django/django/forms/formsets.py
===================================================================
--- django/django/forms/formsets.py	(revision 7999)
+++ django/django/forms/formsets.py	(working copy)
@@ -2,7 +2,7 @@
 from django.utils.encoding import StrAndUnicode
 from django.utils.safestring import mark_safe
 from fields import IntegerField, BooleanField
-from widgets import Media, HiddenInput, TextInput
+from widgets import Media, HiddenInput
 from util import ErrorList, ValidationError
 
 __all__ = ('BaseFormSet', 'all_valid')
Index: django/django/forms/models.py
===================================================================
--- django/django/forms/models.py	(revision 7999)
+++ django/django/forms/models.py	(working copy)
@@ -8,7 +8,6 @@
 from django.utils.translation import ugettext_lazy as _
 from django.utils.encoding import smart_unicode
 from django.utils.datastructures import SortedDict
-from django.core.exceptions import ImproperlyConfigured
 
 from util import ValidationError, ErrorList
 from forms import BaseForm, get_declared_fields
Index: django/django/forms/fields.py
===================================================================
--- django/django/forms/fields.py	(revision 7999)
+++ django/django/forms/fields.py	(working copy)
@@ -23,7 +23,7 @@
     from sets import Set as set
 
 from django.utils.translation import ugettext_lazy as _
-from django.utils.encoding import StrAndUnicode, smart_unicode, smart_str
+from django.utils.encoding import smart_unicode, smart_str
 
 from util import ErrorList, ValidationError
 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput
Index: django/django/core/files/uploadhandler.py
===================================================================
--- django/django/core/files/uploadhandler.py	(revision 7999)
+++ django/django/core/files/uploadhandler.py	(working copy)
@@ -1,8 +1,6 @@
 """
 Base file upload handler classes, and the built-in concrete subclasses
 """
-import os
-import tempfile
 try:
     from cStringIO import StringIO
 except ImportError:
Index: django/django/core/management/commands/compilemessages.py
===================================================================
--- django/django/core/management/commands/compilemessages.py	(revision 7999)
+++ django/django/core/management/commands/compilemessages.py	(working copy)
@@ -2,7 +2,6 @@
 import sys
 from optparse import make_option
 from django.core.management.base import BaseCommand
-from django.core.management.color import no_style
 
 try:
     set
Index: django/django/core/management/commands/testserver.py
===================================================================
--- django/django/core/management/commands/testserver.py	(revision 7999)
+++ django/django/core/management/commands/testserver.py	(working copy)
@@ -17,7 +17,6 @@
     requires_model_validation = False
 
     def handle(self, *fixture_labels, **options):
-        from django.conf import settings
         from django.core.management import call_command
         from django.test.utils import create_test_db
 
Index: django/django/core/management/commands/test.py
===================================================================
--- django/django/core/management/commands/test.py	(revision 7999)
+++ django/django/core/management/commands/test.py	(working copy)
@@ -17,7 +17,6 @@
 
     def handle(self, *test_labels, **options):
         from django.conf import settings
-        from django.db.models import get_app, get_apps
 
         verbosity = int(options.get('verbosity', 1))
         interactive = options.get('interactive', True)
Index: django/django/views/generic/simple.py
===================================================================
--- django/django/views/generic/simple.py	(revision 7999)
+++ django/django/views/generic/simple.py	(working copy)
@@ -1,4 +1,3 @@
-from django.shortcuts import render_to_response
 from django.template import loader, RequestContext
 from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseGone
 
Index: django/django/dispatch/saferef.py
===================================================================
--- django/django/dispatch/saferef.py	(revision 7999)
+++ django/django/dispatch/saferef.py	(working copy)
@@ -1,6 +1,5 @@
 """Refactored "safe reference" from dispatcher.py"""
 import weakref, traceback
-from django.utils.functional import curry
 
 def safeRef(target, onDelete = None):
     """Return a *safe* weak reference to a callable target
Index: django/django/dispatch/dispatcher.py
===================================================================
--- django/django/dispatch/dispatcher.py	(revision 7999)
+++ django/django/dispatch/dispatcher.py	(working copy)
@@ -25,7 +25,7 @@
         deletion, (considerably speeds up the cleanup process
         vs. the original code.)
 """
-import types, weakref
+import weakref
 from django.dispatch import saferef, robustapply, errors
 
 __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
Index: django/django/contrib/formtools/tests.py
===================================================================
--- django/django/contrib/formtools/tests.py	(revision 7999)
+++ django/django/contrib/formtools/tests.py	(working copy)
@@ -1,7 +1,6 @@
 from django import forms
 from django.contrib.formtools import preview
 from django import http
-from django.conf import settings
 from django.test import TestCase
 
 success_string = "Done was called!"
Index: django/django/contrib/syndication/feeds.py
===================================================================
--- django/django/contrib/syndication/feeds.py	(revision 7999)
+++ django/django/contrib/syndication/feeds.py	(working copy)
@@ -1,5 +1,5 @@
 from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
-from django.template import Context, loader, Template, TemplateDoesNotExist
+from django.template import loader, Template, TemplateDoesNotExist
 from django.contrib.sites.models import Site, RequestSite
 from django.utils import feedgenerator
 from django.utils.encoding import smart_unicode, iri_to_uri
Index: django/django/contrib/admin/options.py
===================================================================
--- django/django/contrib/admin/options.py	(revision 7999)
+++ django/django/contrib/admin/options.py	(working copy)
@@ -1,795 +1,795 @@
-from django import oldforms, template
-from django import forms
-from django.forms.formsets import all_valid
-from django.forms.models import modelform_factory, inlineformset_factory
-from django.forms.models import BaseInlineFormset
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.admin import widgets
-from django.contrib.admin.util import quote, unquote, get_deleted_objects
-from django.core.exceptions import ImproperlyConfigured, PermissionDenied
-from django.db import models, transaction
-from django.http import Http404, HttpResponse, HttpResponseRedirect
-from django.shortcuts import get_object_or_404, render_to_response
-from django.utils.html import escape
-from django.utils.safestring import mark_safe
-from django.utils.text import capfirst, get_text_list
-from django.utils.translation import ugettext as _
-from django.utils.encoding import force_unicode
-import sets
-
-HORIZONTAL, VERTICAL = 1, 2
-# returns the <ul> class for a given radio_admin field
-get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
-
-class IncorrectLookupParameters(Exception):
-    pass
-
-def flatten_fieldsets(fieldsets):
-    """Returns a list of field names from an admin fieldsets structure."""
-    field_names = []
-    for name, opts in fieldsets:
-        for field in opts['fields']:
-            # type checking feels dirty, but it seems like the best way here
-            if type(field) == tuple:
-                field_names.extend(field)
-            else:
-                field_names.append(field)
-    return field_names
-
-class AdminForm(object):
-    def __init__(self, form, fieldsets, prepopulated_fields):
-        self.form, self.fieldsets = form, fieldsets
-        self.prepopulated_fields = [{
-            'field': form[field_name],
-            'dependencies': [form[f] for f in dependencies]
-        } for field_name, dependencies in prepopulated_fields.items()]
-
-    def __iter__(self):
-        for name, options in self.fieldsets:
-            yield Fieldset(self.form, name, **options)
-
-    def first_field(self):
-        for bf in self.form:
-            return bf
-
-    def _media(self):
-        media = self.form.media
-        for fs in self:
-            media = media + fs.media
-        return media
-    media = property(_media)
-
-class Fieldset(object):
-    def __init__(self, form, name=None, fields=(), classes=(), description=None):
-        self.form = form
-        self.name, self.fields = name, fields
-        self.classes = u' '.join(classes)
-        self.description = description
-
-    def _media(self):
-        from django.conf import settings
-        if 'collapse' in self.classes:
-            return forms.Media(js=['%sjs/admin/CollapsedFieldsets.js' % settings.ADMIN_MEDIA_PREFIX])
-        return forms.Media()
-    media = property(_media)
-
-    def __iter__(self):
-        for field in self.fields:
-            yield Fieldline(self.form, field)
-
-class Fieldline(object):
-    def __init__(self, form, field):
-        self.form = form # A django.forms.Form instance
-        if isinstance(field, basestring):
-            self.fields = [field]
-        else:
-            self.fields = field
-
-    def __iter__(self):
-        for i, field in enumerate(self.fields):
-            yield AdminField(self.form, field, is_first=(i == 0))
-
-    def errors(self):
-        return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]))
-
-class AdminField(object):
-    def __init__(self, form, field, is_first):
-        self.field = form[field] # A django.forms.BoundField instance
-        self.is_first = is_first # Whether this field is first on the line
-        self.is_checkbox = isinstance(self.field.field.widget, forms.CheckboxInput)
-
-    def label_tag(self):
-        classes = []
-        if self.is_checkbox:
-            classes.append(u'vCheckboxLabel')
-            contents = escape(self.field.label)
-        else:
-            contents = force_unicode(escape(self.field.label)) + u':'
-        if self.field.field.required:
-            classes.append(u'required')
-        if not self.is_first:
-            classes.append(u'inline')
-        attrs = classes and {'class': u' '.join(classes)} or {}
-        return self.field.label_tag(contents=contents, attrs=attrs)
-
-class BaseModelAdmin(object):
-    """Functionality common to both ModelAdmin and InlineAdmin."""
-    raw_id_fields = ()
-    fields = None
-    fieldsets = None
-    form = forms.ModelForm
-    filter_vertical = ()
-    filter_horizontal = ()
-    radio_fields = {}
-    prepopulated_fields = {}
-
-    def formfield_for_dbfield(self, db_field, **kwargs):
-        """
-        Hook for specifying the form Field instance for a given database Field
-        instance.
-
-        If kwargs are given, they're passed to the form Field's constructor.
-        """
-        # For DateTimeFields, use a special field and widget.
-        if isinstance(db_field, models.DateTimeField):
-            kwargs['form_class'] = forms.SplitDateTimeField
-            kwargs['widget'] = widgets.AdminSplitDateTime()
-            return db_field.formfield(**kwargs)
-
-        # For DateFields, add a custom CSS class.
-        if isinstance(db_field, models.DateField):
-            kwargs['widget'] = widgets.AdminDateWidget
-            return db_field.formfield(**kwargs)
-
-        # For TimeFields, add a custom CSS class.
-        if isinstance(db_field, models.TimeField):
-            kwargs['widget'] = widgets.AdminTimeWidget
-            return db_field.formfield(**kwargs)
-
-        # For FileFields and ImageFields add a link to the current file.
-        if isinstance(db_field, models.ImageField) or isinstance(db_field, models.FileField):
-            kwargs['widget'] = widgets.AdminFileWidget
-            return db_field.formfield(**kwargs)
-
-        # For ForeignKey or ManyToManyFields, use a special widget.
-        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
-            if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields:
-                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
-            elif isinstance(db_field, models.ForeignKey) and db_field.name in self.radio_fields:
-                kwargs['widget'] = widgets.AdminRadioSelect(attrs={
-                    'class': get_ul_class(self.radio_fields[db_field.name]),
-                })
-                kwargs['empty_label'] = db_field.blank and _('None') or None
-            else:
-                if isinstance(db_field, models.ManyToManyField):
-                    if db_field.name in self.raw_id_fields:
-                        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
-                        kwargs['help_text'] = ''
-                    elif db_field.name in (self.filter_vertical + self.filter_horizontal):
-                        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
-            # Wrap the widget's render() method with a method that adds
-            # extra HTML to the end of the rendered output.
-            formfield = db_field.formfield(**kwargs)
-            # Don't wrap raw_id fields. Their add function is in the popup window.
-            if not db_field.name in self.raw_id_fields:
-                formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)
-            return formfield
-        
-        if db_field.choices and db_field.name in self.radio_fields:
-            kwargs['widget'] = widgets.AdminRadioSelect(
-                choices=db_field.get_choices(include_blank=db_field.blank,
-                    blank_choice=[('', _('None'))]),
-                attrs={
-                    'class': get_ul_class(self.radio_fields[db_field.name]),
-                }
-            )
-
-        # For any other type of field, just call its formfield() method.
-        return db_field.formfield(**kwargs)
-
-    def _declared_fieldsets(self):
-        if self.fieldsets:
-            return self.fieldsets
-        elif self.fields:
-            return [(None, {'fields': self.fields})]
-        return None
-    declared_fieldsets = property(_declared_fieldsets)
-
-class ModelAdmin(BaseModelAdmin):
-    "Encapsulates all admin options and functionality for a given model."
-    __metaclass__ = forms.MediaDefiningClass
-
-    list_display = ('__str__',)
-    list_display_links = ()
-    list_filter = ()
-    list_select_related = False
-    list_per_page = 100
-    search_fields = ()
-    date_hierarchy = None
-    save_as = False
-    save_on_top = False
-    ordering = None
-    inlines = []
-    
-    # Custom templates (designed to be over-ridden in subclasses)
-    change_form_template = None
-    change_list_template = None
-    delete_confirmation_template = None
-    object_history_template = None
-
-    def __init__(self, model, admin_site):
-        self.model = model
-        self.opts = model._meta
-        self.admin_site = admin_site
-        self.inline_instances = []
-        for inline_class in self.inlines:
-            inline_instance = inline_class(self.model, self.admin_site)
-            self.inline_instances.append(inline_instance)
-        super(ModelAdmin, self).__init__()
-
-    def __call__(self, request, url):
-        # Check that LogEntry, ContentType and the auth context processor are installed.
-        from django.conf import settings
-        if settings.DEBUG:
-            from django.contrib.admin.models import LogEntry
-            if not LogEntry._meta.installed:
-                raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.")
-            if not ContentType._meta.installed:
-                raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.")
-            if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS:
-                raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
-
-        # Delegate to the appropriate method, based on the URL.
-        if url is None:
-            return self.changelist_view(request)
-        elif url.endswith('add'):
-            return self.add_view(request)
-        elif url.endswith('history'):
-            return self.history_view(request, unquote(url[:-8]))
-        elif url.endswith('delete'):
-            return self.delete_view(request, unquote(url[:-7]))
-        else:
-            return self.change_view(request, unquote(url))
-
-    def _media(self):
-        from django.conf import settings
-
-        js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
-        if self.prepopulated_fields:
-            js.append('js/urlify.js')
-        if self.opts.get_ordered_objects():
-            js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
-        if self.filter_vertical or self.filter_horizontal:
-            js.extend(['js/SelectBox.js' , 'js/SelectFilter2.js'])
-        
-        return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
-    media = property(_media)
-
-    def has_add_permission(self, request):
-        "Returns True if the given request has permission to add an object."
-        opts = self.opts
-        return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission())
-
-    def has_change_permission(self, request, obj=None):
-        """
-        Returns True if the given request has permission to change the given
-        Django model instance.
-
-        If `obj` is None, this should return True if the given request has
-        permission to change *any* object of the given type.
-        """
-        opts = self.opts
-        return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
-
-    def has_delete_permission(self, request, obj=None):
-        """
-        Returns True if the given request has permission to change the given
-        Django model instance.
-
-        If `obj` is None, this should return True if the given request has
-        permission to delete *any* object of the given type.
-        """
-        opts = self.opts
-        return request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission())
-
-    def queryset(self, request):
-        """
-        Returns a QuerySet of all model instances that can be edited by the
-        admin site. This is used by changelist_view.
-        """
-        qs = self.model._default_manager.get_query_set()
-        # TODO: this should be handled by some parameter to the ChangeList.
-        ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
-        if ordering:
-            qs = qs.order_by(*ordering)
-        return qs
-
-    def get_fieldsets(self, request, obj=None):
-        "Hook for specifying fieldsets for the add form."
-        if self.declared_fieldsets:
-            return self.declared_fieldsets
-        form = self.get_form(request)
-        return [(None, {'fields': form.base_fields.keys()})]
-
-    def get_form(self, request, obj=None):
-        """
-        Returns a Form class for use in the admin add view. This is used by
-        add_view and change_view.
-        """
-        if self.declared_fieldsets:
-            fields = flatten_fieldsets(self.declared_fieldsets)
-        else:
-            fields = None
-        return modelform_factory(self.model, form=self.form, fields=fields, formfield_callback=self.formfield_for_dbfield)
-
-    def get_formsets(self, request, obj=None):
-        for inline in self.inline_instances:
-            yield inline.get_formset(request, obj)
-
-    def save_add(self, request, form, formsets, post_url_continue):
-        """
-        Saves the object in the "add" stage and returns an HttpResponseRedirect.
-
-        `form` is a bound Form instance that's verified to be valid.
-        """
-        from django.contrib.admin.models import LogEntry, ADDITION
-        opts = self.model._meta
-        new_object = form.save(commit=True)
-
-        if formsets:
-            for formset in formsets:
-                # HACK: it seems like the parent obejct should be passed into
-                # a method of something, not just set as an attribute
-                formset.instance = new_object
-                formset.save()
-
-        pk_value = new_object._get_pk_val()
-        LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION)
-        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
-        # Here, we distinguish between different save types by checking for
-        # the presence of keys in request.POST.
-        if request.POST.has_key("_continue"):
-            request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
-            if request.POST.has_key("_popup"):
-                post_url_continue += "?_popup=1"
-            return HttpResponseRedirect(post_url_continue % pk_value)
-
-        if request.POST.has_key("_popup"):
-            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
-                # escape() calls force_unicode.
-                (escape(pk_value), escape(new_object)))
-        elif request.POST.has_key("_addanother"):
-            request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
-            return HttpResponseRedirect(request.path)
-        else:
-            request.user.message_set.create(message=msg)
-            # Figure out where to redirect. If the user has change permission,
-            # redirect to the change-list page for this object. Otherwise,
-            # redirect to the admin index.
-            if self.has_change_permission(request, None):
-                post_url = '../'
-            else:
-                post_url = '../../../'
-            return HttpResponseRedirect(post_url)
-    save_add = transaction.commit_on_success(save_add)
-
-    def save_change(self, request, form, formsets=None):
-        """
-        Saves the object in the "change" stage and returns an HttpResponseRedirect.
-
-        `form` is a bound Form instance that's verified to be valid.
-        
-        `formsets` is a sequence of InlineFormSet instances that are verified to be valid.
-        """
-        from django.contrib.admin.models import LogEntry, CHANGE
-        opts = self.model._meta
-        new_object = form.save(commit=True)
-        pk_value = new_object._get_pk_val()
-
-        if formsets:
-            for formset in formsets:
-                formset.save()
-
-        # Construct the change message.
-        change_message = []
-        if form.changed_data:
-            change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
-            
-        if formsets:
-            for formset in formsets:
-                for added_object in formset.new_objects:
-                    change_message.append(_('Added %(name)s "%(object)s".') 
-                                          % {'name': added_object._meta.verbose_name,
-                                             'object': added_object})
-                for changed_object, changed_fields in formset.changed_objects:
-                    change_message.append(_('Changed %(list)s for %(name)s "%(object)s".') 
-                                          % {'list': get_text_list(changed_fields, _('and')), 
-                                             'name': changed_object._meta.verbose_name, 
-                                             'object': changed_object})
-                for deleted_object in formset.deleted_objects:
-                    change_message.append(_('Deleted %(name)s "%(object)s".') 
-                                          % {'name': deleted_object._meta.verbose_name,
-                                             'object': deleted_object})
-        change_message = ' '.join(change_message)
-        if not change_message:
-            change_message = _('No fields changed.')
-        LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
-
-        msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
-        if request.POST.has_key("_continue"):
-            request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
-            if request.REQUEST.has_key('_popup'):
-                return HttpResponseRedirect(request.path + "?_popup=1")
-            else:
-                return HttpResponseRedirect(request.path)
-        elif request.POST.has_key("_saveasnew"):
-            request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
-            return HttpResponseRedirect("../%s/" % pk_value)
-        elif request.POST.has_key("_addanother"):
-            request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
-            return HttpResponseRedirect("../add/")
-        else:
-            request.user.message_set.create(message=msg)
-            return HttpResponseRedirect("../")
-    save_change = transaction.commit_on_success(save_change)
-
-    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
-        opts = self.model._meta
-        app_label = opts.app_label
-        ordered_objects = opts.get_ordered_objects()
-        context.update({
-            'add': add,
-            'change': change,
-            'has_add_permission': self.has_add_permission(request),
-            'has_change_permission': self.has_change_permission(request, obj),
-            'has_delete_permission': self.has_delete_permission(request, obj),
-            'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
-            'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
-            'ordered_objects': ordered_objects,
-            'form_url': mark_safe(form_url),
-            'opts': opts,
-            'content_type_id': ContentType.objects.get_for_model(self.model).id,
-            'save_as': self.save_as,
-            'save_on_top': self.save_on_top,
-            'root_path': self.admin_site.root_path,
-        })
-        return render_to_response(self.change_form_template or [
-            "admin/%s/%s/change_form.html" % (app_label, opts.object_name.lower()),
-            "admin/%s/change_form.html" % app_label,
-            "admin/change_form.html"
-        ], context, context_instance=template.RequestContext(request))
-
-    def add_view(self, request, form_url='', extra_context=None):
-        "The 'add' admin view for this model."
-        model = self.model
-        opts = model._meta
-        app_label = opts.app_label
-
-        if not self.has_add_permission(request):
-            raise PermissionDenied
-
-        if self.has_change_permission(request, None):
-            # redirect to list view
-            post_url = '../'
-        else:
-            # Object list will give 'Permission Denied', so go back to admin home
-            post_url = '../../../'
-
-        ModelForm = self.get_form(request)
-        inline_formsets = []
-        obj = self.model()
-        if request.method == 'POST':
-            form = ModelForm(request.POST, request.FILES)
-            for FormSet in self.get_formsets(request):
-                inline_formset = FormSet(data=request.POST, files=request.FILES,
-                    instance=obj, save_as_new=request.POST.has_key("_saveasnew"))
-                inline_formsets.append(inline_formset)
-            if all_valid(inline_formsets) and form.is_valid():
-                return self.save_add(request, form, inline_formsets, '../%s/')
-        else:
-            form = ModelForm(initial=dict(request.GET.items()))
-            for FormSet in self.get_formsets(request):
-                inline_formset = FormSet(instance=obj)
-                inline_formsets.append(inline_formset)
-
-        adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
-        media = self.media + adminForm.media
-        for fs in inline_formsets:
-            media = media + fs.media
-
-        inline_admin_formsets = []
-        for inline, formset in zip(self.inline_instances, inline_formsets):
-            fieldsets = list(inline.get_fieldsets(request))
-            inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
-            inline_admin_formsets.append(inline_admin_formset)
-
-        context = {
-            'title': _('Add %s') % opts.verbose_name,
-            'adminform': adminForm,
-            'is_popup': request.REQUEST.has_key('_popup'),
-            'show_delete': False,
-            'media': mark_safe(media),
-            'inline_admin_formsets': inline_admin_formsets,
-            'errors': AdminErrorList(form, inline_formsets),
-            'root_path': self.admin_site.root_path,
-        }
-        context.update(extra_context or {})
-        return self.render_change_form(request, context, add=True)
-
-    def change_view(self, request, object_id, extra_context=None):
-        "The 'change' admin view for this model."
-        model = self.model
-        opts = model._meta
-        app_label = opts.app_label
-
-        try:
-            obj = model._default_manager.get(pk=object_id)
-        except model.DoesNotExist:
-            # Don't raise Http404 just yet, because we haven't checked
-            # permissions yet. We don't want an unauthenticated user to be able
-            # to determine whether a given object exists.
-            obj = None
-
-        if not self.has_change_permission(request, obj):
-            raise PermissionDenied
-
-        if obj is None:
-            raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
-
-        if request.POST and request.POST.has_key("_saveasnew"):
-            return self.add_view(request, form_url='../../add/')
-
-        ModelForm = self.get_form(request, obj)
-        inline_formsets = []
-        if request.method == 'POST':
-            form = ModelForm(request.POST, request.FILES, instance=obj)
-            for FormSet in self.get_formsets(request, obj):
-                inline_formset = FormSet(request.POST, request.FILES, instance=obj)
-                inline_formsets.append(inline_formset)
-
-            if all_valid(inline_formsets) and form.is_valid():
-                return self.save_change(request, form, inline_formsets)
-        else:
-            form = ModelForm(instance=obj)
-            for FormSet in self.get_formsets(request, obj):
-                inline_formset = FormSet(instance=obj)
-                inline_formsets.append(inline_formset)
-
-        adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
-        media = self.media + adminForm.media
-        for fs in inline_formsets:
-            media = media + fs.media
-
-        inline_admin_formsets = []
-        for inline, formset in zip(self.inline_instances, inline_formsets):
-            fieldsets = list(inline.get_fieldsets(request, obj))
-            inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
-            inline_admin_formsets.append(inline_admin_formset)
-
-        context = {
-            'title': _('Change %s') % opts.verbose_name,
-            'adminform': adminForm,
-            'object_id': object_id,
-            'original': obj,
-            'is_popup': request.REQUEST.has_key('_popup'),
-            'media': mark_safe(media),
-            'inline_admin_formsets': inline_admin_formsets,
-            'errors': AdminErrorList(form, inline_formsets),
-            'root_path': self.admin_site.root_path,
-        }
-        context.update(extra_context or {})
-        return self.render_change_form(request, context, change=True, obj=obj)
-
-    def changelist_view(self, request, extra_context=None):
-        "The 'change list' admin view for this model."
-        from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
-        opts = self.model._meta
-        app_label = opts.app_label
-        if not self.has_change_permission(request, None):
-            raise PermissionDenied
-        try:
-            cl = ChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter,
-                self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self)
-        except IncorrectLookupParameters:
-            # Wacky lookup parameters were given, so redirect to the main
-            # changelist page, without parameters, and pass an 'invalid=1'
-            # parameter via the query string. If wacky parameters were given and
-            # the 'invalid=1' parameter was already in the query string, something
-            # is screwed up with the database, so display an error page.
-            if ERROR_FLAG in request.GET.keys():
-                return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
-            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
-        
-        context = {
-            'title': cl.title,
-            'is_popup': cl.is_popup,
-            'cl': cl,
-            'has_add_permission': self.has_add_permission(request),
-            'root_path': self.admin_site.root_path,
-        }
-        context.update(extra_context or {})
-        return render_to_response(self.change_list_template or [
-            'admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()),
-            'admin/%s/change_list.html' % app_label,
-            'admin/change_list.html'
-        ], context, context_instance=template.RequestContext(request))
-
-    def delete_view(self, request, object_id, extra_context=None):
-        "The 'delete' admin view for this model."
-        from django.contrib.admin.models import LogEntry, DELETION
-        opts = self.model._meta
-        app_label = opts.app_label
-
-        try:
-            obj = self.model._default_manager.get(pk=object_id)
-        except self.model.DoesNotExist:
-            # Don't raise Http404 just yet, because we haven't checked
-            # permissions yet. We don't want an unauthenticated user to be able
-            # to determine whether a given object exists.
-            obj = None
-
-        if not self.has_delete_permission(request, obj):
-            raise PermissionDenied
-
-        if obj is None:
-            raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
-
-        # Populate deleted_objects, a data structure of all related objects that
-        # will also be deleted.
-        deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), quote(object_id), escape(obj))), []]
-        perms_needed = sets.Set()
-        get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site)
-
-        if request.POST: # The user has already confirmed the deletion.
-            if perms_needed:
-                raise PermissionDenied
-            obj_display = str(obj)
-            obj.delete()
-            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, object_id, obj_display, DELETION)
-            request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
-            if not self.has_change_permission(request, None):
-                return HttpResponseRedirect("../../../../")
-            return HttpResponseRedirect("../../")
-        
-        context = {
-            "title": _("Are you sure?"),
-            "object_name": opts.verbose_name,
-            "object": obj,
-            "deleted_objects": deleted_objects,
-            "perms_lacking": perms_needed,
-            "opts": opts,
-            "root_path": self.admin_site.root_path,
-        }
-        context.update(extra_context or {})
-        return render_to_response(self.delete_confirmation_template or [
-            "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()),
-            "admin/%s/delete_confirmation.html" % app_label,
-            "admin/delete_confirmation.html"
-        ], context, context_instance=template.RequestContext(request))
-
-    def history_view(self, request, object_id, extra_context=None):
-        "The 'history' admin view for this model."
-        from django.contrib.admin.models import LogEntry
-        model = self.model
-        opts = model._meta
-        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.
-        obj = get_object_or_404(model, pk=object_id)
-        context = {
-            'title': _('Change history: %s') % force_unicode(obj),
-            'action_list': action_list,
-            'module_name': capfirst(opts.verbose_name_plural),
-            'object': obj,
-            'root_path': self.admin_site.root_path,
-        }
-        context.update(extra_context or {})
-        return render_to_response(self.object_history_template or [
-            "admin/%s/%s/object_history.html" % (opts.app_label, opts.object_name.lower()),
-            "admin/%s/object_history.html" % opts.app_label,
-            "admin/object_history.html"
-        ], context, context_instance=template.RequestContext(request))
-
-class InlineModelAdmin(BaseModelAdmin):
-    """
-    Options for inline editing of ``model`` instances.
-
-    Provide ``name`` to specify the attribute name of the ``ForeignKey`` from
-    ``model`` to its parent. This is required if ``model`` has more than one
-    ``ForeignKey`` to its parent.
-    """
-    model = None
-    fk_name = None
-    formset = BaseInlineFormset
-    extra = 3
-    max_num = 0
-    template = None
-    verbose_name = None
-    verbose_name_plural = None
-
-    def __init__(self, parent_model, admin_site):
-        self.admin_site = admin_site
-        self.parent_model = parent_model
-        self.opts = self.model._meta
-        super(InlineModelAdmin, self).__init__()
-        if self.verbose_name is None:
-            self.verbose_name = self.model._meta.verbose_name
-        if self.verbose_name_plural is None:
-            self.verbose_name_plural = self.model._meta.verbose_name_plural
-
-    def get_formset(self, request, obj=None):
-        """Returns a BaseInlineFormSet class for use in admin add/change views."""
-        if self.declared_fieldsets:
-            fields = flatten_fieldsets(self.declared_fieldsets)
-        else:
-            fields = None
-        return inlineformset_factory(self.parent_model, self.model,
-            form=self.form, formset=self.formset, fk_name=self.fk_name,
-            fields=fields, formfield_callback=self.formfield_for_dbfield,
-            extra=self.extra, max_num=self.max_num)
-
-    def get_fieldsets(self, request, obj=None):
-        if self.declared_fieldsets:
-            return self.declared_fieldsets
-        form = self.get_formset(request).form
-        return [(None, {'fields': form.base_fields.keys()})]
-
-class StackedInline(InlineModelAdmin):
-    template = 'admin/edit_inline/stacked.html'
-
-class TabularInline(InlineModelAdmin):
-    template = 'admin/edit_inline/tabular.html'
-
-class InlineAdminFormSet(object):
-    """
-    A wrapper around an inline formset for use in the admin system.
-    """
-    def __init__(self, inline, formset, fieldsets):
-        self.opts = inline
-        self.formset = formset
-        self.fieldsets = fieldsets
-
-    def __iter__(self):
-        for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
-            yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, original)
-        for form in self.formset.extra_forms:
-            yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, None)
-
-    def fields(self):
-        for field_name in flatten_fieldsets(self.fieldsets):
-            yield self.formset.form.base_fields[field_name]
-
-class InlineAdminForm(AdminForm):
-    """
-    A wrapper around an inline form for use in the admin system.
-    """
-    def __init__(self, formset, form, fieldsets, prepopulated_fields, original):
-        self.formset = formset
-        self.original = original
-        self.show_url = original and hasattr(original, 'get_absolute_url')
-        super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields)
-
-    def pk_field(self):
-        return AdminField(self.form, self.formset._pk_field_name, False)
-
-    def deletion_field(self):
-        from django.forms.formsets import DELETION_FIELD_NAME
-        return AdminField(self.form, DELETION_FIELD_NAME, False)
-
-    def ordering_field(self):
-        from django.forms.formsets import ORDERING_FIELD_NAME
-        return AdminField(self.form, ORDERING_FIELD_NAME, False)
-
-class AdminErrorList(forms.util.ErrorList):
-    """
-    Stores all errors for the form/formsets in an add/change stage view.
-    """
-    def __init__(self, form, inline_formsets):
-        if form.is_bound:
-            self.extend(form.errors.values())
-            for inline_formset in inline_formsets:
-                self.extend(inline_formset.non_form_errors())
-                for errors_in_inline_form in inline_formset.errors:
-                    self.extend(errors_in_inline_form.values())
+from django import template
+from django import forms
+from django.forms.formsets import all_valid
+from django.forms.models import modelform_factory, inlineformset_factory
+from django.forms.models import BaseInlineFormset
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.admin import widgets
+from django.contrib.admin.util import quote, unquote, get_deleted_objects
+from django.core.exceptions import ImproperlyConfigured, PermissionDenied
+from django.db import models, transaction
+from django.http import Http404, HttpResponse, HttpResponseRedirect
+from django.shortcuts import get_object_or_404, render_to_response
+from django.utils.html import escape
+from django.utils.safestring import mark_safe
+from django.utils.text import capfirst, get_text_list
+from django.utils.translation import ugettext as _
+from django.utils.encoding import force_unicode
+import sets
+
+HORIZONTAL, VERTICAL = 1, 2
+# returns the <ul> class for a given radio_admin field
+get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
+
+class IncorrectLookupParameters(Exception):
+    pass
+
+def flatten_fieldsets(fieldsets):
+    """Returns a list of field names from an admin fieldsets structure."""
+    field_names = []
+    for name, opts in fieldsets:
+        for field in opts['fields']:
+            # type checking feels dirty, but it seems like the best way here
+            if type(field) == tuple:
+                field_names.extend(field)
+            else:
+                field_names.append(field)
+    return field_names
+
+class AdminForm(object):
+    def __init__(self, form, fieldsets, prepopulated_fields):
+        self.form, self.fieldsets = form, fieldsets
+        self.prepopulated_fields = [{
+            'field': form[field_name],
+            'dependencies': [form[f] for f in dependencies]
+        } for field_name, dependencies in prepopulated_fields.items()]
+
+    def __iter__(self):
+        for name, options in self.fieldsets:
+            yield Fieldset(self.form, name, **options)
+
+    def first_field(self):
+        for bf in self.form:
+            return bf
+
+    def _media(self):
+        media = self.form.media
+        for fs in self:
+            media = media + fs.media
+        return media
+    media = property(_media)
+
+class Fieldset(object):
+    def __init__(self, form, name=None, fields=(), classes=(), description=None):
+        self.form = form
+        self.name, self.fields = name, fields
+        self.classes = u' '.join(classes)
+        self.description = description
+
+    def _media(self):
+        from django.conf import settings
+        if 'collapse' in self.classes:
+            return forms.Media(js=['%sjs/admin/CollapsedFieldsets.js' % settings.ADMIN_MEDIA_PREFIX])
+        return forms.Media()
+    media = property(_media)
+
+    def __iter__(self):
+        for field in self.fields:
+            yield Fieldline(self.form, field)
+
+class Fieldline(object):
+    def __init__(self, form, field):
+        self.form = form # A django.forms.Form instance
+        if isinstance(field, basestring):
+            self.fields = [field]
+        else:
+            self.fields = field
+
+    def __iter__(self):
+        for i, field in enumerate(self.fields):
+            yield AdminField(self.form, field, is_first=(i == 0))
+
+    def errors(self):
+        return mark_safe(u'\n'.join([self.form[f].errors.as_ul() for f in self.fields]))
+
+class AdminField(object):
+    def __init__(self, form, field, is_first):
+        self.field = form[field] # A django.forms.BoundField instance
+        self.is_first = is_first # Whether this field is first on the line
+        self.is_checkbox = isinstance(self.field.field.widget, forms.CheckboxInput)
+
+    def label_tag(self):
+        classes = []
+        if self.is_checkbox:
+            classes.append(u'vCheckboxLabel')
+            contents = escape(self.field.label)
+        else:
+            contents = force_unicode(escape(self.field.label)) + u':'
+        if self.field.field.required:
+            classes.append(u'required')
+        if not self.is_first:
+            classes.append(u'inline')
+        attrs = classes and {'class': u' '.join(classes)} or {}
+        return self.field.label_tag(contents=contents, attrs=attrs)
+
+class BaseModelAdmin(object):
+    """Functionality common to both ModelAdmin and InlineAdmin."""
+    raw_id_fields = ()
+    fields = None
+    fieldsets = None
+    form = forms.ModelForm
+    filter_vertical = ()
+    filter_horizontal = ()
+    radio_fields = {}
+    prepopulated_fields = {}
+
+    def formfield_for_dbfield(self, db_field, **kwargs):
+        """
+        Hook for specifying the form Field instance for a given database Field
+        instance.
+
+        If kwargs are given, they're passed to the form Field's constructor.
+        """
+        # For DateTimeFields, use a special field and widget.
+        if isinstance(db_field, models.DateTimeField):
+            kwargs['form_class'] = forms.SplitDateTimeField
+            kwargs['widget'] = widgets.AdminSplitDateTime()
+            return db_field.formfield(**kwargs)
+
+        # For DateFields, add a custom CSS class.
+        if isinstance(db_field, models.DateField):
+            kwargs['widget'] = widgets.AdminDateWidget
+            return db_field.formfield(**kwargs)
+
+        # For TimeFields, add a custom CSS class.
+        if isinstance(db_field, models.TimeField):
+            kwargs['widget'] = widgets.AdminTimeWidget
+            return db_field.formfield(**kwargs)
+
+        # For FileFields and ImageFields add a link to the current file.
+        if isinstance(db_field, models.ImageField) or isinstance(db_field, models.FileField):
+            kwargs['widget'] = widgets.AdminFileWidget
+            return db_field.formfield(**kwargs)
+
+        # For ForeignKey or ManyToManyFields, use a special widget.
+        if isinstance(db_field, (models.ForeignKey, models.ManyToManyField)):
+            if isinstance(db_field, models.ForeignKey) and db_field.name in self.raw_id_fields:
+                kwargs['widget'] = widgets.ForeignKeyRawIdWidget(db_field.rel)
+            elif isinstance(db_field, models.ForeignKey) and db_field.name in self.radio_fields:
+                kwargs['widget'] = widgets.AdminRadioSelect(attrs={
+                    'class': get_ul_class(self.radio_fields[db_field.name]),
+                })
+                kwargs['empty_label'] = db_field.blank and _('None') or None
+            else:
+                if isinstance(db_field, models.ManyToManyField):
+                    if db_field.name in self.raw_id_fields:
+                        kwargs['widget'] = widgets.ManyToManyRawIdWidget(db_field.rel)
+                        kwargs['help_text'] = ''
+                    elif db_field.name in (self.filter_vertical + self.filter_horizontal):
+                        kwargs['widget'] = widgets.FilteredSelectMultiple(db_field.verbose_name, (db_field.name in self.filter_vertical))
+            # Wrap the widget's render() method with a method that adds
+            # extra HTML to the end of the rendered output.
+            formfield = db_field.formfield(**kwargs)
+            # Don't wrap raw_id fields. Their add function is in the popup window.
+            if not db_field.name in self.raw_id_fields:
+                formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)
+            return formfield
+        
+        if db_field.choices and db_field.name in self.radio_fields:
+            kwargs['widget'] = widgets.AdminRadioSelect(
+                choices=db_field.get_choices(include_blank=db_field.blank,
+                    blank_choice=[('', _('None'))]),
+                attrs={
+                    'class': get_ul_class(self.radio_fields[db_field.name]),
+                }
+            )
+
+        # For any other type of field, just call its formfield() method.
+        return db_field.formfield(**kwargs)
+
+    def _declared_fieldsets(self):
+        if self.fieldsets:
+            return self.fieldsets
+        elif self.fields:
+            return [(None, {'fields': self.fields})]
+        return None
+    declared_fieldsets = property(_declared_fieldsets)
+
+class ModelAdmin(BaseModelAdmin):
+    "Encapsulates all admin options and functionality for a given model."
+    __metaclass__ = forms.MediaDefiningClass
+
+    list_display = ('__str__',)
+    list_display_links = ()
+    list_filter = ()
+    list_select_related = False
+    list_per_page = 100
+    search_fields = ()
+    date_hierarchy = None
+    save_as = False
+    save_on_top = False
+    ordering = None
+    inlines = []
+    
+    # Custom templates (designed to be over-ridden in subclasses)
+    change_form_template = None
+    change_list_template = None
+    delete_confirmation_template = None
+    object_history_template = None
+
+    def __init__(self, model, admin_site):
+        self.model = model
+        self.opts = model._meta
+        self.admin_site = admin_site
+        self.inline_instances = []
+        for inline_class in self.inlines:
+            inline_instance = inline_class(self.model, self.admin_site)
+            self.inline_instances.append(inline_instance)
+        super(ModelAdmin, self).__init__()
+
+    def __call__(self, request, url):
+        # Check that LogEntry, ContentType and the auth context processor are installed.
+        from django.conf import settings
+        if settings.DEBUG:
+            from django.contrib.admin.models import LogEntry
+            if not LogEntry._meta.installed:
+                raise ImproperlyConfigured("Put 'django.contrib.admin' in your INSTALLED_APPS setting in order to use the admin application.")
+            if not ContentType._meta.installed:
+                raise ImproperlyConfigured("Put 'django.contrib.contenttypes' in your INSTALLED_APPS setting in order to use the admin application.")
+            if 'django.core.context_processors.auth' not in settings.TEMPLATE_CONTEXT_PROCESSORS:
+                raise ImproperlyConfigured("Put 'django.core.context_processors.auth' in your TEMPLATE_CONTEXT_PROCESSORS setting in order to use the admin application.")
+
+        # Delegate to the appropriate method, based on the URL.
+        if url is None:
+            return self.changelist_view(request)
+        elif url.endswith('add'):
+            return self.add_view(request)
+        elif url.endswith('history'):
+            return self.history_view(request, unquote(url[:-8]))
+        elif url.endswith('delete'):
+            return self.delete_view(request, unquote(url[:-7]))
+        else:
+            return self.change_view(request, unquote(url))
+
+    def _media(self):
+        from django.conf import settings
+
+        js = ['js/core.js', 'js/admin/RelatedObjectLookups.js']
+        if self.prepopulated_fields:
+            js.append('js/urlify.js')
+        if self.opts.get_ordered_objects():
+            js.extend(['js/getElementsBySelector.js', 'js/dom-drag.js' , 'js/admin/ordering.js'])
+        if self.filter_vertical or self.filter_horizontal:
+            js.extend(['js/SelectBox.js' , 'js/SelectFilter2.js'])
+        
+        return forms.Media(js=['%s%s' % (settings.ADMIN_MEDIA_PREFIX, url) for url in js])
+    media = property(_media)
+
+    def has_add_permission(self, request):
+        "Returns True if the given request has permission to add an object."
+        opts = self.opts
+        return request.user.has_perm(opts.app_label + '.' + opts.get_add_permission())
+
+    def has_change_permission(self, request, obj=None):
+        """
+        Returns True if the given request has permission to change the given
+        Django model instance.
+
+        If `obj` is None, this should return True if the given request has
+        permission to change *any* object of the given type.
+        """
+        opts = self.opts
+        return request.user.has_perm(opts.app_label + '.' + opts.get_change_permission())
+
+    def has_delete_permission(self, request, obj=None):
+        """
+        Returns True if the given request has permission to change the given
+        Django model instance.
+
+        If `obj` is None, this should return True if the given request has
+        permission to delete *any* object of the given type.
+        """
+        opts = self.opts
+        return request.user.has_perm(opts.app_label + '.' + opts.get_delete_permission())
+
+    def queryset(self, request):
+        """
+        Returns a QuerySet of all model instances that can be edited by the
+        admin site. This is used by changelist_view.
+        """
+        qs = self.model._default_manager.get_query_set()
+        # TODO: this should be handled by some parameter to the ChangeList.
+        ordering = self.ordering or () # otherwise we might try to *None, which is bad ;)
+        if ordering:
+            qs = qs.order_by(*ordering)
+        return qs
+
+    def get_fieldsets(self, request, obj=None):
+        "Hook for specifying fieldsets for the add form."
+        if self.declared_fieldsets:
+            return self.declared_fieldsets
+        form = self.get_form(request)
+        return [(None, {'fields': form.base_fields.keys()})]
+
+    def get_form(self, request, obj=None):
+        """
+        Returns a Form class for use in the admin add view. This is used by
+        add_view and change_view.
+        """
+        if self.declared_fieldsets:
+            fields = flatten_fieldsets(self.declared_fieldsets)
+        else:
+            fields = None
+        return modelform_factory(self.model, form=self.form, fields=fields, formfield_callback=self.formfield_for_dbfield)
+
+    def get_formsets(self, request, obj=None):
+        for inline in self.inline_instances:
+            yield inline.get_formset(request, obj)
+
+    def save_add(self, request, form, formsets, post_url_continue):
+        """
+        Saves the object in the "add" stage and returns an HttpResponseRedirect.
+
+        `form` is a bound Form instance that's verified to be valid.
+        """
+        from django.contrib.admin.models import LogEntry, ADDITION
+        opts = self.model._meta
+        new_object = form.save(commit=True)
+
+        if formsets:
+            for formset in formsets:
+                # HACK: it seems like the parent obejct should be passed into
+                # a method of something, not just set as an attribute
+                formset.instance = new_object
+                formset.save()
+
+        pk_value = new_object._get_pk_val()
+        LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), ADDITION)
+        msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+        # Here, we distinguish between different save types by checking for
+        # the presence of keys in request.POST.
+        if request.POST.has_key("_continue"):
+            request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
+            if request.POST.has_key("_popup"):
+                post_url_continue += "?_popup=1"
+            return HttpResponseRedirect(post_url_continue % pk_value)
+
+        if request.POST.has_key("_popup"):
+            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, "%s", "%s");</script>' % \
+                # escape() calls force_unicode.
+                (escape(pk_value), escape(new_object)))
+        elif request.POST.has_key("_addanother"):
+            request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+            return HttpResponseRedirect(request.path)
+        else:
+            request.user.message_set.create(message=msg)
+            # Figure out where to redirect. If the user has change permission,
+            # redirect to the change-list page for this object. Otherwise,
+            # redirect to the admin index.
+            if self.has_change_permission(request, None):
+                post_url = '../'
+            else:
+                post_url = '../../../'
+            return HttpResponseRedirect(post_url)
+    save_add = transaction.commit_on_success(save_add)
+
+    def save_change(self, request, form, formsets=None):
+        """
+        Saves the object in the "change" stage and returns an HttpResponseRedirect.
+
+        `form` is a bound Form instance that's verified to be valid.
+        
+        `formsets` is a sequence of InlineFormSet instances that are verified to be valid.
+        """
+        from django.contrib.admin.models import LogEntry, CHANGE
+        opts = self.model._meta
+        new_object = form.save(commit=True)
+        pk_value = new_object._get_pk_val()
+
+        if formsets:
+            for formset in formsets:
+                formset.save()
+
+        # Construct the change message.
+        change_message = []
+        if form.changed_data:
+            change_message.append(_('Changed %s.') % get_text_list(form.changed_data, _('and')))
+            
+        if formsets:
+            for formset in formsets:
+                for added_object in formset.new_objects:
+                    change_message.append(_('Added %(name)s "%(object)s".') 
+                                          % {'name': added_object._meta.verbose_name,
+                                             'object': added_object})
+                for changed_object, changed_fields in formset.changed_objects:
+                    change_message.append(_('Changed %(list)s for %(name)s "%(object)s".') 
+                                          % {'list': get_text_list(changed_fields, _('and')), 
+                                             'name': changed_object._meta.verbose_name, 
+                                             'object': changed_object})
+                for deleted_object in formset.deleted_objects:
+                    change_message.append(_('Deleted %(name)s "%(object)s".') 
+                                          % {'name': deleted_object._meta.verbose_name,
+                                             'object': deleted_object})
+        change_message = ' '.join(change_message)
+        if not change_message:
+            change_message = _('No fields changed.')
+        LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
+
+        msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
+        if request.POST.has_key("_continue"):
+            request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
+            if request.REQUEST.has_key('_popup'):
+                return HttpResponseRedirect(request.path + "?_popup=1")
+            else:
+                return HttpResponseRedirect(request.path)
+        elif request.POST.has_key("_saveasnew"):
+            request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
+            return HttpResponseRedirect("../%s/" % pk_value)
+        elif request.POST.has_key("_addanother"):
+            request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
+            return HttpResponseRedirect("../add/")
+        else:
+            request.user.message_set.create(message=msg)
+            return HttpResponseRedirect("../")
+    save_change = transaction.commit_on_success(save_change)
+
+    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
+        opts = self.model._meta
+        app_label = opts.app_label
+        ordered_objects = opts.get_ordered_objects()
+        context.update({
+            'add': add,
+            'change': change,
+            'has_add_permission': self.has_add_permission(request),
+            'has_change_permission': self.has_change_permission(request, obj),
+            'has_delete_permission': self.has_delete_permission(request, obj),
+            'has_file_field': True, # FIXME - this should check if form or formsets have a FileField,
+            'has_absolute_url': hasattr(self.model, 'get_absolute_url'),
+            'ordered_objects': ordered_objects,
+            'form_url': mark_safe(form_url),
+            'opts': opts,
+            'content_type_id': ContentType.objects.get_for_model(self.model).id,
+            'save_as': self.save_as,
+            'save_on_top': self.save_on_top,
+            'root_path': self.admin_site.root_path,
+        })
+        return render_to_response(self.change_form_template or [
+            "admin/%s/%s/change_form.html" % (app_label, opts.object_name.lower()),
+            "admin/%s/change_form.html" % app_label,
+            "admin/change_form.html"
+        ], context, context_instance=template.RequestContext(request))
+
+    def add_view(self, request, form_url='', extra_context=None):
+        "The 'add' admin view for this model."
+        model = self.model
+        opts = model._meta
+        app_label = opts.app_label
+
+        if not self.has_add_permission(request):
+            raise PermissionDenied
+
+        if self.has_change_permission(request, None):
+            # redirect to list view
+            post_url = '../'
+        else:
+            # Object list will give 'Permission Denied', so go back to admin home
+            post_url = '../../../'
+
+        ModelForm = self.get_form(request)
+        inline_formsets = []
+        obj = self.model()
+        if request.method == 'POST':
+            form = ModelForm(request.POST, request.FILES)
+            for FormSet in self.get_formsets(request):
+                inline_formset = FormSet(data=request.POST, files=request.FILES,
+                    instance=obj, save_as_new=request.POST.has_key("_saveasnew"))
+                inline_formsets.append(inline_formset)
+            if all_valid(inline_formsets) and form.is_valid():
+                return self.save_add(request, form, inline_formsets, '../%s/')
+        else:
+            form = ModelForm(initial=dict(request.GET.items()))
+            for FormSet in self.get_formsets(request):
+                inline_formset = FormSet(instance=obj)
+                inline_formsets.append(inline_formset)
+
+        adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields)
+        media = self.media + adminForm.media
+        for fs in inline_formsets:
+            media = media + fs.media
+
+        inline_admin_formsets = []
+        for inline, formset in zip(self.inline_instances, inline_formsets):
+            fieldsets = list(inline.get_fieldsets(request))
+            inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
+            inline_admin_formsets.append(inline_admin_formset)
+
+        context = {
+            'title': _('Add %s') % opts.verbose_name,
+            'adminform': adminForm,
+            'is_popup': request.REQUEST.has_key('_popup'),
+            'show_delete': False,
+            'media': mark_safe(media),
+            'inline_admin_formsets': inline_admin_formsets,
+            'errors': AdminErrorList(form, inline_formsets),
+            'root_path': self.admin_site.root_path,
+        }
+        context.update(extra_context or {})
+        return self.render_change_form(request, context, add=True)
+
+    def change_view(self, request, object_id, extra_context=None):
+        "The 'change' admin view for this model."
+        model = self.model
+        opts = model._meta
+        app_label = opts.app_label
+
+        try:
+            obj = model._default_manager.get(pk=object_id)
+        except model.DoesNotExist:
+            # Don't raise Http404 just yet, because we haven't checked
+            # permissions yet. We don't want an unauthenticated user to be able
+            # to determine whether a given object exists.
+            obj = None
+
+        if not self.has_change_permission(request, obj):
+            raise PermissionDenied
+
+        if obj is None:
+            raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
+
+        if request.POST and request.POST.has_key("_saveasnew"):
+            return self.add_view(request, form_url='../../add/')
+
+        ModelForm = self.get_form(request, obj)
+        inline_formsets = []
+        if request.method == 'POST':
+            form = ModelForm(request.POST, request.FILES, instance=obj)
+            for FormSet in self.get_formsets(request, obj):
+                inline_formset = FormSet(request.POST, request.FILES, instance=obj)
+                inline_formsets.append(inline_formset)
+
+            if all_valid(inline_formsets) and form.is_valid():
+                return self.save_change(request, form, inline_formsets)
+        else:
+            form = ModelForm(instance=obj)
+            for FormSet in self.get_formsets(request, obj):
+                inline_formset = FormSet(instance=obj)
+                inline_formsets.append(inline_formset)
+
+        adminForm = AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields)
+        media = self.media + adminForm.media
+        for fs in inline_formsets:
+            media = media + fs.media
+
+        inline_admin_formsets = []
+        for inline, formset in zip(self.inline_instances, inline_formsets):
+            fieldsets = list(inline.get_fieldsets(request, obj))
+            inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets)
+            inline_admin_formsets.append(inline_admin_formset)
+
+        context = {
+            'title': _('Change %s') % opts.verbose_name,
+            'adminform': adminForm,
+            'object_id': object_id,
+            'original': obj,
+            'is_popup': request.REQUEST.has_key('_popup'),
+            'media': mark_safe(media),
+            'inline_admin_formsets': inline_admin_formsets,
+            'errors': AdminErrorList(form, inline_formsets),
+            'root_path': self.admin_site.root_path,
+        }
+        context.update(extra_context or {})
+        return self.render_change_form(request, context, change=True, obj=obj)
+
+    def changelist_view(self, request, extra_context=None):
+        "The 'change list' admin view for this model."
+        from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
+        opts = self.model._meta
+        app_label = opts.app_label
+        if not self.has_change_permission(request, None):
+            raise PermissionDenied
+        try:
+            cl = ChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter,
+                self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self)
+        except IncorrectLookupParameters:
+            # Wacky lookup parameters were given, so redirect to the main
+            # changelist page, without parameters, and pass an 'invalid=1'
+            # parameter via the query string. If wacky parameters were given and
+            # the 'invalid=1' parameter was already in the query string, something
+            # is screwed up with the database, so display an error page.
+            if ERROR_FLAG in request.GET.keys():
+                return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
+            return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
+        
+        context = {
+            'title': cl.title,
+            'is_popup': cl.is_popup,
+            'cl': cl,
+            'has_add_permission': self.has_add_permission(request),
+            'root_path': self.admin_site.root_path,
+        }
+        context.update(extra_context or {})
+        return render_to_response(self.change_list_template or [
+            'admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()),
+            'admin/%s/change_list.html' % app_label,
+            'admin/change_list.html'
+        ], context, context_instance=template.RequestContext(request))
+
+    def delete_view(self, request, object_id, extra_context=None):
+        "The 'delete' admin view for this model."
+        from django.contrib.admin.models import LogEntry, DELETION
+        opts = self.model._meta
+        app_label = opts.app_label
+
+        try:
+            obj = self.model._default_manager.get(pk=object_id)
+        except self.model.DoesNotExist:
+            # Don't raise Http404 just yet, because we haven't checked
+            # permissions yet. We don't want an unauthenticated user to be able
+            # to determine whether a given object exists.
+            obj = None
+
+        if not self.has_delete_permission(request, obj):
+            raise PermissionDenied
+
+        if obj is None:
+            raise Http404('%s object with primary key %r does not exist.' % (opts.verbose_name, escape(object_id)))
+
+        # Populate deleted_objects, a data structure of all related objects that
+        # will also be deleted.
+        deleted_objects = [mark_safe(u'%s: <a href="../../%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), quote(object_id), escape(obj))), []]
+        perms_needed = sets.Set()
+        get_deleted_objects(deleted_objects, perms_needed, request.user, obj, opts, 1, self.admin_site)
+
+        if request.POST: # The user has already confirmed the deletion.
+            if perms_needed:
+                raise PermissionDenied
+            obj_display = str(obj)
+            obj.delete()
+            LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(self.model).id, object_id, obj_display, DELETION)
+            request.user.message_set.create(message=_('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
+            if not self.has_change_permission(request, None):
+                return HttpResponseRedirect("../../../../")
+            return HttpResponseRedirect("../../")
+        
+        context = {
+            "title": _("Are you sure?"),
+            "object_name": opts.verbose_name,
+            "object": obj,
+            "deleted_objects": deleted_objects,
+            "perms_lacking": perms_needed,
+            "opts": opts,
+            "root_path": self.admin_site.root_path,
+        }
+        context.update(extra_context or {})
+        return render_to_response(self.delete_confirmation_template or [
+            "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()),
+            "admin/%s/delete_confirmation.html" % app_label,
+            "admin/delete_confirmation.html"
+        ], context, context_instance=template.RequestContext(request))
+
+    def history_view(self, request, object_id, extra_context=None):
+        "The 'history' admin view for this model."
+        from django.contrib.admin.models import LogEntry
+        model = self.model
+        opts = model._meta
+        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.
+        obj = get_object_or_404(model, pk=object_id)
+        context = {
+            'title': _('Change history: %s') % force_unicode(obj),
+            'action_list': action_list,
+            'module_name': capfirst(opts.verbose_name_plural),
+            'object': obj,
+            'root_path': self.admin_site.root_path,
+        }
+        context.update(extra_context or {})
+        return render_to_response(self.object_history_template or [
+            "admin/%s/%s/object_history.html" % (opts.app_label, opts.object_name.lower()),
+            "admin/%s/object_history.html" % opts.app_label,
+            "admin/object_history.html"
+        ], context, context_instance=template.RequestContext(request))
+
+class InlineModelAdmin(BaseModelAdmin):
+    """
+    Options for inline editing of ``model`` instances.
+
+    Provide ``name`` to specify the attribute name of the ``ForeignKey`` from
+    ``model`` to its parent. This is required if ``model`` has more than one
+    ``ForeignKey`` to its parent.
+    """
+    model = None
+    fk_name = None
+    formset = BaseInlineFormset
+    extra = 3
+    max_num = 0
+    template = None
+    verbose_name = None
+    verbose_name_plural = None
+
+    def __init__(self, parent_model, admin_site):
+        self.admin_site = admin_site
+        self.parent_model = parent_model
+        self.opts = self.model._meta
+        super(InlineModelAdmin, self).__init__()
+        if self.verbose_name is None:
+            self.verbose_name = self.model._meta.verbose_name
+        if self.verbose_name_plural is None:
+            self.verbose_name_plural = self.model._meta.verbose_name_plural
+
+    def get_formset(self, request, obj=None):
+        """Returns a BaseInlineFormSet class for use in admin add/change views."""
+        if self.declared_fieldsets:
+            fields = flatten_fieldsets(self.declared_fieldsets)
+        else:
+            fields = None
+        return inlineformset_factory(self.parent_model, self.model,
+            form=self.form, formset=self.formset, fk_name=self.fk_name,
+            fields=fields, formfield_callback=self.formfield_for_dbfield,
+            extra=self.extra, max_num=self.max_num)
+
+    def get_fieldsets(self, request, obj=None):
+        if self.declared_fieldsets:
+            return self.declared_fieldsets
+        form = self.get_formset(request).form
+        return [(None, {'fields': form.base_fields.keys()})]
+
+class StackedInline(InlineModelAdmin):
+    template = 'admin/edit_inline/stacked.html'
+
+class TabularInline(InlineModelAdmin):
+    template = 'admin/edit_inline/tabular.html'
+
+class InlineAdminFormSet(object):
+    """
+    A wrapper around an inline formset for use in the admin system.
+    """
+    def __init__(self, inline, formset, fieldsets):
+        self.opts = inline
+        self.formset = formset
+        self.fieldsets = fieldsets
+
+    def __iter__(self):
+        for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
+            yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, original)
+        for form in self.formset.extra_forms:
+            yield InlineAdminForm(self.formset, form, self.fieldsets, self.opts.prepopulated_fields, None)
+
+    def fields(self):
+        for field_name in flatten_fieldsets(self.fieldsets):
+            yield self.formset.form.base_fields[field_name]
+
+class InlineAdminForm(AdminForm):
+    """
+    A wrapper around an inline form for use in the admin system.
+    """
+    def __init__(self, formset, form, fieldsets, prepopulated_fields, original):
+        self.formset = formset
+        self.original = original
+        self.show_url = original and hasattr(original, 'get_absolute_url')
+        super(InlineAdminForm, self).__init__(form, fieldsets, prepopulated_fields)
+
+    def pk_field(self):
+        return AdminField(self.form, self.formset._pk_field_name, False)
+
+    def deletion_field(self):
+        from django.forms.formsets import DELETION_FIELD_NAME
+        return AdminField(self.form, DELETION_FIELD_NAME, False)
+
+    def ordering_field(self):
+        from django.forms.formsets import ORDERING_FIELD_NAME
+        return AdminField(self.form, ORDERING_FIELD_NAME, False)
+
+class AdminErrorList(forms.util.ErrorList):
+    """
+    Stores all errors for the form/formsets in an add/change stage view.
+    """
+    def __init__(self, form, inline_formsets):
+        if form.is_bound:
+            self.extend(form.errors.values())
+            for inline_formset in inline_formsets:
+                self.extend(inline_formset.non_form_errors())
+                for errors_in_inline_form in inline_formset.errors:
+                    self.extend(errors_in_inline_form.values())
Index: django/django/contrib/admin/views/main.py
===================================================================
--- django/django/contrib/admin/views/main.py	(revision 7999)
+++ django/django/contrib/admin/views/main.py	(working copy)
@@ -6,7 +6,6 @@
 from django.db.models.query import QuerySet
 from django.utils.encoding import force_unicode, smart_str
 from django.utils.translation import ugettext
-from django.utils.safestring import mark_safe
 from django.utils.http import urlencode
 import operator
 
Index: django/django/contrib/admin/widgets.py
===================================================================
--- django/django/contrib/admin/widgets.py	(revision 7999)
+++ django/django/contrib/admin/widgets.py	(working copy)
@@ -1,211 +1,210 @@
-"""
-Form Widget classes specific to the Django admin site.
-"""
-
-import copy
-
-from django import forms
-from django.forms.widgets import RadioFieldRenderer
-from django.forms.util import flatatt
-from django.utils.datastructures import MultiValueDict
-from django.utils.text import capfirst, truncate_words
-from django.utils.translation import ugettext as _
-from django.utils.safestring import mark_safe
-from django.utils.encoding import force_unicode
-from django.conf import settings
-
-class FilteredSelectMultiple(forms.SelectMultiple):
-    """
-    A SelectMultiple with a JavaScript filter interface.
-
-    Note that the resulting JavaScript assumes that the SelectFilter2.js
-    library and its dependencies have been loaded in the HTML page.
-    """
-    def __init__(self, verbose_name, is_stacked, attrs=None, choices=()):
-        self.verbose_name = verbose_name
-        self.is_stacked = is_stacked
-        super(FilteredSelectMultiple, self).__init__(attrs, choices)
-
-    def render(self, name, value, attrs=None, choices=()):
-        output = [super(FilteredSelectMultiple, self).render(name, value, attrs, choices)]
-        output.append(u'<script type="text/javascript">addEvent(window, "load", function(e) {')
-        # TODO: "id_" is hard-coded here. This should instead use the correct
-        # API to determine the ID dynamically.
-        output.append(u'SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % \
-            (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
-        return mark_safe(u''.join(output))
-
-class AdminDateWidget(forms.TextInput):
-    class Media:
-        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 
-              settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
-        
-    def __init__(self, attrs={}):
-        super(AdminDateWidget, self).__init__(attrs={'class': 'vDateField', 'size': '10'})
-
-class AdminTimeWidget(forms.TextInput):
-    class Media:
-        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 
-              settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
-
-    def __init__(self, attrs={}):
-        super(AdminTimeWidget, self).__init__(attrs={'class': 'vTimeField', 'size': '8'})
-    
-class AdminSplitDateTime(forms.SplitDateTimeWidget):
-    """
-    A SplitDateTime Widget that has some admin-specific styling.
-    """
-    def __init__(self, attrs=None):
-        widgets = [AdminDateWidget, AdminTimeWidget]
-        # Note that we're calling MultiWidget, not SplitDateTimeWidget, because
-        # we want to define widgets.
-        forms.MultiWidget.__init__(self, widgets, attrs)
-
-    def format_output(self, rendered_widgets):
-        return mark_safe(u'<p class="datetime">%s %s<br />%s %s</p>' % \
-            (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1]))
-
-class AdminRadioFieldRenderer(RadioFieldRenderer):
-    def render(self):
-        """Outputs a <ul> for this set of radio fields."""
-        return mark_safe(u'<ul%s>\n%s\n</ul>' % (
-            flatatt(self.attrs),
-            u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]))
-        )
-
-class AdminRadioSelect(forms.RadioSelect):
-    renderer = AdminRadioFieldRenderer
-
-class AdminFileWidget(forms.FileInput):
-    """
-    A FileField Widget that shows its current value if it has one.
-    """
-    def __init__(self, attrs={}):
-        super(AdminFileWidget, self).__init__(attrs)
-        
-    def render(self, name, value, attrs=None):
-        output = []
-        if value:
-            output.append('%s <a target="_blank" href="%s%s">%s</a> <br />%s ' % \
-                (_('Currently:'), settings.MEDIA_URL, value, value, _('Change:')))
-        output.append(super(AdminFileWidget, self).render(name, value, attrs))
-        return mark_safe(u''.join(output))
-
-class ForeignKeyRawIdWidget(forms.TextInput):
-    """
-    A Widget for displaying ForeignKeys in the "raw_id" interface rather than
-    in a <select> box.
-    """
-    def __init__(self, rel, attrs=None):
-        self.rel = rel
-        super(ForeignKeyRawIdWidget, self).__init__(attrs)
-
-    def render(self, name, value, attrs=None):
-        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
-        if self.rel.limit_choices_to:
-            url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in self.rel.limit_choices_to.items()])
-        else:
-            url = ''
-        if not attrs.has_key('class'):
-          attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
-        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
-        # TODO: "id_" is hard-coded here. This should instead use the correct
-        # API to determine the ID dynamically.
-        output.append('<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> ' % \
-            (related_url, url, name))
-        output.append('<img src="%simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % settings.ADMIN_MEDIA_PREFIX)
-        if value:
-            output.append(self.label_for_value(value))
-        return mark_safe(u''.join(output))
-    
-    def label_for_value(self, value):
-        return '&nbsp;<strong>%s</strong>' % \
-            truncate_words(self.rel.to.objects.get(pk=value), 14)
-            
-class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
-    """
-    A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
-    in a <select multiple> box.
-    """
-    def __init__(self, rel, attrs=None):
-        super(ManyToManyRawIdWidget, self).__init__(rel, attrs)
-    
-    def render(self, name, value, attrs=None):
-        attrs['class'] = 'vManyToManyRawIdAdminField'
-        if value:
-            value = ','.join([str(v) for v in value])
-        else:
-            value = ''
-        return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
-    
-    def label_for_value(self, value):
-        return ''
-
-    def value_from_datadict(self, data, files, name):
-        value = data.get(name, None)
-        if value and ',' in value:
-            return data[name].split(',')
-        if value:
-            return [value]
-        return None
-    
-    def _has_changed(self, initial, data):
-        if initial is None:
-            initial = []
-        if data is None:
-            data = []
-        if len(initial) != len(data):
-            return True
-        for pk1, pk2 in zip(initial, data):
-            if force_unicode(pk1) != force_unicode(pk2):
-                return True
-        return False
-
-class RelatedFieldWidgetWrapper(forms.Widget):
-    """
-    This class is a wrapper to a given widget to add the add icon for the
-    admin interface.
-    """
-    def __init__(self, widget, rel, admin_site):
-        self.is_hidden = widget.is_hidden
-        self.needs_multipart_form = widget.needs_multipart_form
-        self.attrs = widget.attrs
-        self.choices = widget.choices
-        self.widget = widget
-        self.rel = rel
-        # so we can check if the related object is registered with this AdminSite
-        self.admin_site = admin_site
-
-    def __deepcopy__(self, memo):
-        obj = copy.copy(self)
-        obj.widget = copy.deepcopy(self.widget, memo)
-        obj.attrs = self.widget.attrs
-        memo[id(self)] = obj
-        return obj
-
-    def render(self, name, value, *args, **kwargs):
-        rel_to = self.rel.to
-        related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower())
-        self.widget.choices = self.choices
-        output = [self.widget.render(name, value, *args, **kwargs)]
-        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
-            # TODO: "id_" is hard-coded here. This should instead use the correct
-            # API to determine the ID dynamically.
-            output.append(u'<a href="%sadd/" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
-                (related_url, name))
-            output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>' % settings.ADMIN_MEDIA_PREFIX)
-        return mark_safe(u''.join(output))
-
-    def build_attrs(self, extra_attrs=None, **kwargs):
-        "Helper function for building an attribute dictionary."
-        self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs)
-        return self.attrs
-
-    def value_from_datadict(self, data, files, name):
-        return self.widget.value_from_datadict(data, files, name)
-
-    def _has_changed(self, initial, data):
-        return self.widget._has_changed(initial, data)
-
-    def id_for_label(self, id_):
-        return self.widget.id_for_label(id_)
+"""
+Form Widget classes specific to the Django admin site.
+"""
+
+import copy
+
+from django import forms
+from django.forms.widgets import RadioFieldRenderer
+from django.forms.util import flatatt
+from django.utils.text import truncate_words
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+from django.utils.encoding import force_unicode
+from django.conf import settings
+
+class FilteredSelectMultiple(forms.SelectMultiple):
+    """
+    A SelectMultiple with a JavaScript filter interface.
+
+    Note that the resulting JavaScript assumes that the SelectFilter2.js
+    library and its dependencies have been loaded in the HTML page.
+    """
+    def __init__(self, verbose_name, is_stacked, attrs=None, choices=()):
+        self.verbose_name = verbose_name
+        self.is_stacked = is_stacked
+        super(FilteredSelectMultiple, self).__init__(attrs, choices)
+
+    def render(self, name, value, attrs=None, choices=()):
+        output = [super(FilteredSelectMultiple, self).render(name, value, attrs, choices)]
+        output.append(u'<script type="text/javascript">addEvent(window, "load", function(e) {')
+        # TODO: "id_" is hard-coded here. This should instead use the correct
+        # API to determine the ID dynamically.
+        output.append(u'SelectFilter.init("id_%s", "%s", %s, "%s"); });</script>\n' % \
+            (name, self.verbose_name.replace('"', '\\"'), int(self.is_stacked), settings.ADMIN_MEDIA_PREFIX))
+        return mark_safe(u''.join(output))
+
+class AdminDateWidget(forms.TextInput):
+    class Media:
+        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 
+              settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
+        
+    def __init__(self, attrs={}):
+        super(AdminDateWidget, self).__init__(attrs={'class': 'vDateField', 'size': '10'})
+
+class AdminTimeWidget(forms.TextInput):
+    class Media:
+        js = (settings.ADMIN_MEDIA_PREFIX + "js/calendar.js", 
+              settings.ADMIN_MEDIA_PREFIX + "js/admin/DateTimeShortcuts.js")
+
+    def __init__(self, attrs={}):
+        super(AdminTimeWidget, self).__init__(attrs={'class': 'vTimeField', 'size': '8'})
+    
+class AdminSplitDateTime(forms.SplitDateTimeWidget):
+    """
+    A SplitDateTime Widget that has some admin-specific styling.
+    """
+    def __init__(self, attrs=None):
+        widgets = [AdminDateWidget, AdminTimeWidget]
+        # Note that we're calling MultiWidget, not SplitDateTimeWidget, because
+        # we want to define widgets.
+        forms.MultiWidget.__init__(self, widgets, attrs)
+
+    def format_output(self, rendered_widgets):
+        return mark_safe(u'<p class="datetime">%s %s<br />%s %s</p>' % \
+            (_('Date:'), rendered_widgets[0], _('Time:'), rendered_widgets[1]))
+
+class AdminRadioFieldRenderer(RadioFieldRenderer):
+    def render(self):
+        """Outputs a <ul> for this set of radio fields."""
+        return mark_safe(u'<ul%s>\n%s\n</ul>' % (
+            flatatt(self.attrs),
+            u'\n'.join([u'<li>%s</li>' % force_unicode(w) for w in self]))
+        )
+
+class AdminRadioSelect(forms.RadioSelect):
+    renderer = AdminRadioFieldRenderer
+
+class AdminFileWidget(forms.FileInput):
+    """
+    A FileField Widget that shows its current value if it has one.
+    """
+    def __init__(self, attrs={}):
+        super(AdminFileWidget, self).__init__(attrs)
+        
+    def render(self, name, value, attrs=None):
+        output = []
+        if value:
+            output.append('%s <a target="_blank" href="%s%s">%s</a> <br />%s ' % \
+                (_('Currently:'), settings.MEDIA_URL, value, value, _('Change:')))
+        output.append(super(AdminFileWidget, self).render(name, value, attrs))
+        return mark_safe(u''.join(output))
+
+class ForeignKeyRawIdWidget(forms.TextInput):
+    """
+    A Widget for displaying ForeignKeys in the "raw_id" interface rather than
+    in a <select> box.
+    """
+    def __init__(self, rel, attrs=None):
+        self.rel = rel
+        super(ForeignKeyRawIdWidget, self).__init__(attrs)
+
+    def render(self, name, value, attrs=None):
+        related_url = '../../../%s/%s/' % (self.rel.to._meta.app_label, self.rel.to._meta.object_name.lower())
+        if self.rel.limit_choices_to:
+            url = '?' + '&amp;'.join(['%s=%s' % (k, v) for k, v in self.rel.limit_choices_to.items()])
+        else:
+            url = ''
+        if not attrs.has_key('class'):
+          attrs['class'] = 'vForeignKeyRawIdAdminField' # The JavaScript looks for this hook.
+        output = [super(ForeignKeyRawIdWidget, self).render(name, value, attrs)]
+        # TODO: "id_" is hard-coded here. This should instead use the correct
+        # API to determine the ID dynamically.
+        output.append('<a href="%s%s" class="related-lookup" id="lookup_id_%s" onclick="return showRelatedObjectLookupPopup(this);"> ' % \
+            (related_url, url, name))
+        output.append('<img src="%simg/admin/selector-search.gif" width="16" height="16" alt="Lookup" /></a>' % settings.ADMIN_MEDIA_PREFIX)
+        if value:
+            output.append(self.label_for_value(value))
+        return mark_safe(u''.join(output))
+    
+    def label_for_value(self, value):
+        return '&nbsp;<strong>%s</strong>' % \
+            truncate_words(self.rel.to.objects.get(pk=value), 14)
+            
+class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
+    """
+    A Widget for displaying ManyToMany ids in the "raw_id" interface rather than
+    in a <select multiple> box.
+    """
+    def __init__(self, rel, attrs=None):
+        super(ManyToManyRawIdWidget, self).__init__(rel, attrs)
+    
+    def render(self, name, value, attrs=None):
+        attrs['class'] = 'vManyToManyRawIdAdminField'
+        if value:
+            value = ','.join([str(v) for v in value])
+        else:
+            value = ''
+        return super(ManyToManyRawIdWidget, self).render(name, value, attrs)
+    
+    def label_for_value(self, value):
+        return ''
+
+    def value_from_datadict(self, data, files, name):
+        value = data.get(name, None)
+        if value and ',' in value:
+            return data[name].split(',')
+        if value:
+            return [value]
+        return None
+    
+    def _has_changed(self, initial, data):
+        if initial is None:
+            initial = []
+        if data is None:
+            data = []
+        if len(initial) != len(data):
+            return True
+        for pk1, pk2 in zip(initial, data):
+            if force_unicode(pk1) != force_unicode(pk2):
+                return True
+        return False
+
+class RelatedFieldWidgetWrapper(forms.Widget):
+    """
+    This class is a wrapper to a given widget to add the add icon for the
+    admin interface.
+    """
+    def __init__(self, widget, rel, admin_site):
+        self.is_hidden = widget.is_hidden
+        self.needs_multipart_form = widget.needs_multipart_form
+        self.attrs = widget.attrs
+        self.choices = widget.choices
+        self.widget = widget
+        self.rel = rel
+        # so we can check if the related object is registered with this AdminSite
+        self.admin_site = admin_site
+
+    def __deepcopy__(self, memo):
+        obj = copy.copy(self)
+        obj.widget = copy.deepcopy(self.widget, memo)
+        obj.attrs = self.widget.attrs
+        memo[id(self)] = obj
+        return obj
+
+    def render(self, name, value, *args, **kwargs):
+        rel_to = self.rel.to
+        related_url = '../../../%s/%s/' % (rel_to._meta.app_label, rel_to._meta.object_name.lower())
+        self.widget.choices = self.choices
+        output = [self.widget.render(name, value, *args, **kwargs)]
+        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
+            # TODO: "id_" is hard-coded here. This should instead use the correct
+            # API to determine the ID dynamically.
+            output.append(u'<a href="%sadd/" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
+                (related_url, name))
+            output.append(u'<img src="%simg/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>' % settings.ADMIN_MEDIA_PREFIX)
+        return mark_safe(u''.join(output))
+
+    def build_attrs(self, extra_attrs=None, **kwargs):
+        "Helper function for building an attribute dictionary."
+        self.attrs = self.widget.build_attrs(extra_attrs=None, **kwargs)
+        return self.attrs
+
+    def value_from_datadict(self, data, files, name):
+        return self.widget.value_from_datadict(data, files, name)
+
+    def _has_changed(self, initial, data):
+        return self.widget._has_changed(initial, data)
+
+    def id_for_label(self, id_):
+        return self.widget.id_for_label(id_)
Index: django/django/contrib/databrowse/plugins/calendars.py
===================================================================
--- django/django/contrib/databrowse/plugins/calendars.py	(revision 7999)
+++ django/django/contrib/databrowse/plugins/calendars.py	(working copy)
@@ -4,7 +4,6 @@
 from django.contrib.databrowse.sites import DatabrowsePlugin
 from django.shortcuts import render_to_response
 from django.utils.text import capfirst
-from django.utils.translation import get_date_formats
 from django.utils.encoding import force_unicode
 from django.utils.safestring import mark_safe
 from django.views.generic import date_based
Index: django/django/contrib/databrowse/plugins/fieldchoices.py
===================================================================
--- django/django/contrib/databrowse/plugins/fieldchoices.py	(revision 7999)
+++ django/django/contrib/databrowse/plugins/fieldchoices.py	(working copy)
@@ -6,7 +6,6 @@
 from django.utils.text import capfirst
 from django.utils.encoding import smart_str, force_unicode
 from django.utils.safestring import mark_safe
-from django.views.generic import date_based
 import urllib
 
 class FieldChoicePlugin(DatabrowsePlugin):
Index: django/django/contrib/databrowse/views.py
===================================================================
--- django/django/contrib/databrowse/views.py	(revision 7999)
+++ django/django/contrib/databrowse/views.py	(working copy)
@@ -1,7 +1,5 @@
-from django.db.models import FieldDoesNotExist, DateTimeField
 from django.http import Http404
 from django.shortcuts import render_to_response
-from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
 
 ###########
 # CHOICES #
Index: django/django/contrib/databrowse/sites.py
===================================================================
--- django/django/contrib/databrowse/sites.py	(revision 7999)
+++ django/django/contrib/databrowse/sites.py	(working copy)
@@ -1,6 +1,6 @@
 from django import http
 from django.db import models
-from django.contrib.databrowse.datastructures import EasyModel, EasyChoice
+from django.contrib.databrowse.datastructures import EasyModel
 from django.shortcuts import render_to_response
 from django.utils.safestring import mark_safe
 
Index: django/django/contrib/auth/admin.py
===================================================================
--- django/django/contrib/auth/admin.py	(revision 7999)
+++ django/django/contrib/auth/admin.py	(working copy)
@@ -1,66 +1,66 @@
-from django.contrib.auth.models import User, Group
-from django.core.exceptions import PermissionDenied
-from django import oldforms, template
-from django.shortcuts import render_to_response
-from django.http import HttpResponseRedirect
-from django.utils.translation import ugettext, ugettext_lazy as _
-from django.contrib import admin
-
-class GroupAdmin(admin.ModelAdmin):
-    search_fields = ('name',)
-    ordering = ('name',)
-    filter_horizontal = ('permissions',)
-
-class UserAdmin(admin.ModelAdmin):
-    fieldsets = (
-        (None, {'fields': ('username', 'password')}),
-        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
-        (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
-        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
-        (_('Groups'), {'fields': ('groups',)}),
-    )
-    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
-    list_filter = ('is_staff', 'is_superuser')
-    search_fields = ('username', 'first_name', 'last_name', 'email')
-    ordering = ('username',)
-    filter_horizontal = ('user_permissions',)
-
-    def add_view(self, request):
-        # avoid a circular import. see #6718.
-        from django.contrib.auth.forms import UserCreationForm
-        if not self.has_change_permission(request):
-            raise PermissionDenied
-        if request.method == 'POST':
-            form = UserCreationForm(request.POST)
-            if form.is_valid():
-                new_user = form.save()
-                msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
-                if "_addanother" in request.POST:
-                    request.user.message_set.create(message=msg)
-                    return HttpResponseRedirect(request.path)
-                else:
-                    request.user.message_set.create(message=msg + ' ' + ugettext("You may edit it again below."))
-                    return HttpResponseRedirect('../%s/' % new_user.id)
-        else:
-            form = UserCreationForm()
-        return render_to_response('admin/auth/user/add_form.html', {
-            'title': _('Add user'),
-            'form': form,
-            'is_popup': '_popup' in request.REQUEST,
-            'add': True,
-            'change': False,
-            'has_add_permission': True,
-            'has_delete_permission': False,
-            'has_change_permission': True,
-            'has_file_field': False,
-            'has_absolute_url': False,
-            'auto_populated_fields': (),
-            'opts': User._meta,
-            'save_as': False,
-            'username_help_text': User._meta.get_field('username').help_text,
-            'root_path': self.admin_site.root_path,
-        }, context_instance=template.RequestContext(request))
-
-admin.site.register(Group, GroupAdmin)
-admin.site.register(User, UserAdmin)
-
+from django.contrib.auth.models import User, Group
+from django.core.exceptions import PermissionDenied
+from django import template
+from django.shortcuts import render_to_response
+from django.http import HttpResponseRedirect
+from django.utils.translation import ugettext, ugettext_lazy as _
+from django.contrib import admin
+
+class GroupAdmin(admin.ModelAdmin):
+    search_fields = ('name',)
+    ordering = ('name',)
+    filter_horizontal = ('permissions',)
+
+class UserAdmin(admin.ModelAdmin):
+    fieldsets = (
+        (None, {'fields': ('username', 'password')}),
+        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email')}),
+        (_('Permissions'), {'fields': ('is_staff', 'is_active', 'is_superuser', 'user_permissions')}),
+        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
+        (_('Groups'), {'fields': ('groups',)}),
+    )
+    list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
+    list_filter = ('is_staff', 'is_superuser')
+    search_fields = ('username', 'first_name', 'last_name', 'email')
+    ordering = ('username',)
+    filter_horizontal = ('user_permissions',)
+
+    def add_view(self, request):
+        # avoid a circular import. see #6718.
+        from django.contrib.auth.forms import UserCreationForm
+        if not self.has_change_permission(request):
+            raise PermissionDenied
+        if request.method == 'POST':
+            form = UserCreationForm(request.POST)
+            if form.is_valid():
+                new_user = form.save()
+                msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': 'user', 'obj': new_user}
+                if "_addanother" in request.POST:
+                    request.user.message_set.create(message=msg)
+                    return HttpResponseRedirect(request.path)
+                else:
+                    request.user.message_set.create(message=msg + ' ' + ugettext("You may edit it again below."))
+                    return HttpResponseRedirect('../%s/' % new_user.id)
+        else:
+            form = UserCreationForm()
+        return render_to_response('admin/auth/user/add_form.html', {
+            'title': _('Add user'),
+            'form': form,
+            'is_popup': '_popup' in request.REQUEST,
+            'add': True,
+            'change': False,
+            'has_add_permission': True,
+            'has_delete_permission': False,
+            'has_change_permission': True,
+            'has_file_field': False,
+            'has_absolute_url': False,
+            'auto_populated_fields': (),
+            'opts': User._meta,
+            'save_as': False,
+            'username_help_text': User._meta.get_field('username').help_text,
+            'root_path': self.admin_site.root_path,
+        }, context_instance=template.RequestContext(request))
+
+admin.site.register(Group, GroupAdmin)
+admin.site.register(User, UserAdmin)
+
Index: django/django/contrib/auth/management/commands/createsuperuser.py
===================================================================
--- django/django/contrib/auth/management/commands/createsuperuser.py	(revision 7999)
+++ django/django/contrib/auth/management/commands/createsuperuser.py	(working copy)
@@ -1,123 +1,123 @@
-"""
-Management utility to create superusers.
-"""
-
-import getpass
-import os
-import re
-import sys
-from optparse import make_option
-from django.contrib.auth.models import User, UNUSABLE_PASSWORD
-from django.core import validators
-from django.core.management.base import BaseCommand, CommandError
-
-RE_VALID_USERNAME = re.compile('\w+$')
-
-class Command(BaseCommand):
-    option_list = BaseCommand.option_list + (
-        make_option('--username', dest='username', default=None,
-            help='Specifies the username for the superuser.'),
-        make_option('--email', dest='email', default=None,
-            help='Specifies the email address for the superuser.'),
-        make_option('--noinput', action='store_false', dest='interactive', default=True,
-            help='Tells Django to NOT prompt the user for input of any kind. '    \
-                 'You must use --username and --email with --noinput, and '      \
-                 'superusers created with --noinput will not be able to log in '  \
-                 'until they\'re given a valid password.'),
-    )
-    help = 'Used to create a superuser.'
-
-    def handle(self, *args, **options):
-        username = options.get('username', None)
-        email = options.get('email', None)
-        interactive = options.get('interactive')
-        
-        # Do quick and dirty validation if --noinput
-        if not interactive:
-            if not username or not email:
-                raise CommandError("You must use --username and --email with --noinput.")
-            if not RE_VALID_USERNAME.match(username):
-                raise CommandError("Invalid username. Use only letters, digits, and underscores")
-            try:
-                validators.isValidEmail(email, None)
-            except validators.ValidationError:
-                raise CommandError("Invalid email address.")
-
-        password = ''
-
-        # Try to determine the current system user's username to use as a default.
-        try:
-            import pwd
-        except ImportError:
-            default_username = ''
-        else:
-            default_username = pwd.getpwuid(os.getuid())[0].replace(' ', '').lower()
-
-        # Determine whether the default username is taken, so we don't display
-        # it as an option.
-        if default_username:
-            try:
-                User.objects.get(username=default_username)
-            except User.DoesNotExist:
-                pass
-            else:
-                default_username = ''
-
-        # Prompt for username/email/password. Enclose this whole thing in a
-        # try/except to trap for a keyboard interrupt and exit gracefully.
-        if interactive:
-            try:
-            
-                # Get a username
-                while 1:
-                    if not username:
-                        input_msg = 'Username'
-                        if default_username:
-                            input_msg += ' (Leave blank to use %r)' % default_username
-                        username = raw_input(input_msg + ': ')
-                    if default_username and username == '':
-                        username = default_username
-                    if not RE_VALID_USERNAME.match(username):
-                        sys.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.\n")
-                        username = None
-                        continue
-                    try:
-                        User.objects.get(username=username)
-                    except User.DoesNotExist:
-                        break
-                    else:
-                        sys.stderr.write("Error: That username is already taken.\n")
-                        username = None
-            
-                # Get an email
-                while 1:
-                    if not email:
-                        email = raw_input('E-mail address: ')
-                    try:
-                        validators.isValidEmail(email, None)
-                    except validators.ValidationError:
-                        sys.stderr.write("Error: That e-mail address is invalid.\n")
-                        email = None
-                    else:
-                        break
-            
-                # Get a password
-                while 1:
-                    if not password:
-                        password = getpass.getpass()
-                        password2 = getpass.getpass('Password (again): ')
-                        if password != password2:
-                            sys.stderr.write("Error: Your passwords didn't match.\n")
-                            password = None
-                            continue
-                    if password.strip() == '':
-                        sys.stderr.write("Error: Blank passwords aren't allowed.\n")
-                        password = None
-                        continue
-                    break
-            except KeyboardInterrupt:
-                sys.stderr.write("\nOperation cancelled.\n")
-                sys.exit(1)
-        
-        User.objects.create_superuser(username, email, password)
-        print "Superuser created successfully."
+"""
+Management utility to create superusers.
+"""
+
+import getpass
+import os
+import re
+import sys
+from optparse import make_option
+from django.contrib.auth.models import User
+from django.core import validators
+from django.core.management.base import BaseCommand, CommandError
+
+RE_VALID_USERNAME = re.compile('\w+$')
+
+class Command(BaseCommand):
+    option_list = BaseCommand.option_list + (
+        make_option('--username', dest='username', default=None,
+            help='Specifies the username for the superuser.'),
+        make_option('--email', dest='email', default=None,
+            help='Specifies the email address for the superuser.'),
+        make_option('--noinput', action='store_false', dest='interactive', default=True,
+            help='Tells Django to NOT prompt the user for input of any kind. '    \
+                 'You must use --username and --email with --noinput, and '      \
+                 'superusers created with --noinput will not be able to log in '  \
+                 'until they\'re given a valid password.'),
+    )
+    help = 'Used to create a superuser.'
+
+    def handle(self, *args, **options):
+        username = options.get('username', None)
+        email = options.get('email', None)
+        interactive = options.get('interactive')
+        
+        # Do quick and dirty validation if --noinput
+        if not interactive:
+            if not username or not email:
+                raise CommandError("You must use --username and --email with --noinput.")
+            if not RE_VALID_USERNAME.match(username):
+                raise CommandError("Invalid username. Use only letters, digits, and underscores")
+            try:
+                validators.isValidEmail(email, None)
+            except validators.ValidationError:
+                raise CommandError("Invalid email address.")
+
+        password = ''
+
+        # Try to determine the current system user's username to use as a default.
+        try:
+            import pwd
+        except ImportError:
+            default_username = ''
+        else:
+            default_username = pwd.getpwuid(os.getuid())[0].replace(' ', '').lower()
+
+        # Determine whether the default username is taken, so we don't display
+        # it as an option.
+        if default_username:
+            try:
+                User.objects.get(username=default_username)
+            except User.DoesNotExist:
+                pass
+            else:
+                default_username = ''
+
+        # Prompt for username/email/password. Enclose this whole thing in a
+        # try/except to trap for a keyboard interrupt and exit gracefully.
+        if interactive:
+            try:
+            
+                # Get a username
+                while 1:
+                    if not username:
+                        input_msg = 'Username'
+                        if default_username:
+                            input_msg += ' (Leave blank to use %r)' % default_username
+                        username = raw_input(input_msg + ': ')
+                    if default_username and username == '':
+                        username = default_username
+                    if not RE_VALID_USERNAME.match(username):
+                        sys.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.\n")
+                        username = None
+                        continue
+                    try:
+                        User.objects.get(username=username)
+                    except User.DoesNotExist:
+                        break
+                    else:
+                        sys.stderr.write("Error: That username is already taken.\n")
+                        username = None
+            
+                # Get an email
+                while 1:
+                    if not email:
+                        email = raw_input('E-mail address: ')
+                    try:
+                        validators.isValidEmail(email, None)
+                    except validators.ValidationError:
+                        sys.stderr.write("Error: That e-mail address is invalid.\n")
+                        email = None
+                    else:
+                        break
+            
+                # Get a password
+                while 1:
+                    if not password:
+                        password = getpass.getpass()
+                        password2 = getpass.getpass('Password (again): ')
+                        if password != password2:
+                            sys.stderr.write("Error: Your passwords didn't match.\n")
+                            password = None
+                            continue
+                    if password.strip() == '':
+                        sys.stderr.write("Error: Blank passwords aren't allowed.\n")
+                        password = None
+                        continue
+                    break
+            except KeyboardInterrupt:
+                sys.stderr.write("\nOperation cancelled.\n")
+                sys.exit(1)
+        
+        User.objects.create_superuser(username, email, password)
+        print "Superuser created successfully."
Index: django/django/contrib/auth/decorators.py
===================================================================
--- django/django/contrib/auth/decorators.py	(revision 7999)
+++ django/django/contrib/auth/decorators.py	(working copy)
@@ -1,7 +1,7 @@
 try:
     from functools import wraps, update_wrapper
 except ImportError:
-    from django.utils.functional import wraps, update_wrapper  # Python 2.3, 2.4 fallback.
+    from django.utils.functional import update_wrapper  # Python 2.3, 2.4 fallback.
 
 from django.contrib.auth import REDIRECT_FIELD_NAME
 from django.http import HttpResponseRedirect
Index: django/django/contrib/auth/forms.py
===================================================================
--- django/django/contrib/auth/forms.py	(revision 7999)
+++ django/django/contrib/auth/forms.py	(working copy)
@@ -2,7 +2,6 @@
 from django.contrib.auth import authenticate
 from django.contrib.sites.models import Site
 from django.template import Context, loader
-from django.core import validators
 from django import forms
 from django.utils.translation import ugettext_lazy as _
 
Index: django/django/contrib/admindocs/views.py
===================================================================
--- django/django/contrib/admindocs/views.py	(revision 7999)
+++ django/django/contrib/admindocs/views.py	(working copy)
@@ -5,7 +5,7 @@
 from django.db import models
 from django.shortcuts import render_to_response
 from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
-from django.http import Http404, get_host
+from django.http import Http404
 from django.core import urlresolvers
 from django.contrib.admindocs import utils
 from django.contrib.sites.models import Site
Index: django/django/contrib/sessions/backends/cache.py
===================================================================
--- django/django/contrib/sessions/backends/cache.py	(revision 7999)
+++ django/django/contrib/sessions/backends/cache.py	(working copy)
@@ -1,4 +1,3 @@
-from django.conf import settings
 from django.contrib.sessions.backends.base import SessionBase
 from django.core.cache import cache
 
Index: django/django/contrib/sessions/backends/db.py
===================================================================
--- django/django/contrib/sessions/backends/db.py	(revision 7999)
+++ django/django/contrib/sessions/backends/db.py	(working copy)
@@ -1,6 +1,5 @@
 import datetime
 
-from django.conf import settings
 from django.contrib.sessions.models import Session
 from django.contrib.sessions.backends.base import SessionBase
 from django.core.exceptions import SuspiciousOperation
Index: django/django/utils/dateformat.py
===================================================================
--- django/django/utils/dateformat.py	(revision 7999)
+++ django/django/utils/dateformat.py	(working copy)
@@ -13,7 +13,7 @@
 
 from django.utils.dates import MONTHS, MONTHS_3, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR
 from django.utils.tzinfo import LocalTimezone
-from django.utils.translation import string_concat, ugettext as _
+from django.utils.translation import ugettext as _
 from django.utils.encoding import force_unicode
 from calendar import isleap, monthrange
 import re, time
Index: django/django/utils/encoding.py
===================================================================
--- django/django/utils/encoding.py	(revision 7999)
+++ django/django/utils/encoding.py	(working copy)
@@ -3,7 +3,6 @@
 import datetime
 
 from django.utils.functional import Promise
-from django.utils.safestring import SafeData, mark_safe
 
 class DjangoUnicodeDecodeError(UnicodeDecodeError):
     def __init__(self, obj, *args):
