Index: db/backends/ado_mssql/base.py.bak
===================================================================
--- db/backends/ado_mssql/base.py.bak	(revision 0)
+++ db/backends/ado_mssql/base.py.bak	(revision 0)
@@ -0,0 +1,300 @@
+"""
+ADO MSSQL database backend for Django.
+
+Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
+"""
+import pythoncom
+from django.db.backends import util
+try:
+    import adodbapi as Database
+except ImportError, e:
+    from django.core.exceptions import ImproperlyConfigured
+    raise ImproperlyConfigured, "Error loading adodbapi module: %s" % e
+import datetime
+try:
+    import mx
+except ImportError:
+    mx = None
+
+DatabaseError = Database.DatabaseError
+
+# We need to use a special Cursor class because adodbapi expects question-mark
+# param style, but Django expects "%s". This cursor converts question marks to
+# format-string style.
+class Cursor(Database.Cursor):
+    def executeHelper(self, operation, isStoredProcedureCall, parameters=None):
+        if parameters is not None and "%s" in operation:
+            operation = operation.replace("%s", "?")
+        Database.Cursor.executeHelper(self, operation, isStoredProcedureCall, parameters)
+
+class Connection(Database.Connection):
+    def cursor(self):
+        return Cursor(self)
+Database.Connection = Connection
+
+origCVtoP = Database.convertVariantToPython
+def variantToPython(variant, adType):
+    if type(variant) == bool and adType == 11:
+        return variant  # bool not 1/0
+    res = origCVtoP(variant, adType)
+    if mx is not None and type(res) == mx.DateTime.mxDateTime.DateTimeType:
+        # Convert ms.DateTime objects to Python datetime.datetime objects.
+        tv = list(res.tuple()[:7])
+        tv[-2] = int(tv[-2])
+        return datetime.datetime(*tuple(tv))
+    if type(res) == float and str(res)[-2:] == ".0":
+        return int(res) # If float but int, then int.
+    return res
+Database.convertVariantToPython = variantToPython
+
+try:
+    # Only exists in Python 2.4+
+    from threading import local
+except ImportError:
+    # Import copy of _thread_local.py from Python 2.4
+    from django.utils._threading_local import local
+
+class DatabaseWrapper(local):
+    def __init__(self, **kwargs):
+        self.connection = None
+        self.queries = []
+
+    def cursor(self):
+        from django.conf import settings
+        if self.connection is None:
+            if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
+                from django.core.exceptions import ImproperlyConfigured
+                raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file."
+            if not settings.DATABASE_HOST:
+                settings.DATABASE_HOST = "127.0.0.1"
+            # TODO: Handle DATABASE_PORT.
+            conn_string = "PROVIDER=SQLOLEDB;DATA SOURCE=%s;UID=%s;PWD=%s;DATABASE=%s" % (settings.DATABASE_HOST, settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME)
+            self.connection = Database.connect(conn_string)
+        cursor = self.connection.cursor()
+        if settings.DEBUG:
+            return util.CursorDebugWrapper(cursor, self)
+        return cursor
+
+    def _commit(self):
+        return self.connection.commit()
+
+    def _rollback(self):
+        if self.connection:
+            return self.connection.rollback()
+
+    def close(self):
+        if self.connection is not None:
+            self.connection.close()
+            self.connection = None
+
+supports_constraints = True
+
+def quote_name(name):
+    if name.startswith('[') and name.endswith(']'):
+        return name # Quoting once is enough.
+    return '[%s]' % name
+
+dictfetchone = util.dictfetchone
+dictfetchmany = util.dictfetchmany
+dictfetchall  = util.dictfetchall
+
+def get_last_insert_id(cursor, table_name, pk_name):
+    cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name))
+    return cursor.fetchone()[0]
+
+def get_date_extract_sql(lookup_type, table_name):
+    # lookup_type is 'year', 'month', 'day'
+    return "DATEPART(%s, %s)" % (lookup_type, table_name)
+
+def get_date_trunc_sql(lookup_type, field_name):
+    # lookup_type is 'year', 'month', 'day'
+    if lookup_type=='year':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name
+    if lookup_type=='month':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name)
+    if lookup_type=='day':
+        return "Convert(datetime, Convert(varchar(12), %s))" % field_name
+
+def get_limit_offset_sql(limit, offset=None):
+    # TODO: This is a guess. Make sure this is correct.
+    sql = "LIMIT %s" % limit
+    if offset and offset != 0:
+        sql += " OFFSET %s" % offset
+    return sql
+
+def get_random_function_sql():
+    return "RAND()"
+
+def get_fulltext_search_sql(field_name):
+    raise NotImplementedError
+
+def get_drop_foreignkey_sql():
+    return "DROP CONSTRAINT"
+
+def get_pk_default_value():
+    return "DEFAULT"
+
+OPERATOR_MAPPING = {
+    'exact': '= %s',
+    'iexact': 'LIKE %s',
+    'contains': 'LIKE %s',
+    'icontains': 'LIKE %s',
+    'gt': '> %s',
+    'gte': '>= %s',
+    'lt': '< %s',
+    'lte': '<= %s',
+    'startswith': 'LIKE %s',
+    'endswith': 'LIKE %s',
+    'istartswith': 'LIKE %s',
+    'iendswith': 'LIKE %s',
+}
+"""
+ADO MSSQL database backend for Django.
+
+Requires adodbapi 2.0.1: http://adodbapi.sourceforge.net/
+"""
+import pythoncom
+from django.db.backends import util
+try:
+    import adodbapi as Database
+except ImportError, e:
+    from django.core.exceptions import ImproperlyConfigured
+    raise ImproperlyConfigured, "Error loading adodbapi module: %s" % e
+import datetime
+try:
+    import mx
+except ImportError:
+    mx = None
+
+DatabaseError = Database.DatabaseError
+
+# We need to use a special Cursor class because adodbapi expects question-mark
+# param style, but Django expects "%s". This cursor converts question marks to
+# format-string style.
+class Cursor(Database.Cursor):
+    def executeHelper(self, operation, isStoredProcedureCall, parameters=None):
+        if parameters is not None and "%s" in operation:
+            operation = operation.replace("%s", "?")
+        Database.Cursor.executeHelper(self, operation, isStoredProcedureCall, parameters)
+
+class Connection(Database.Connection):
+    def cursor(self):
+        return Cursor(self)
+Database.Connection = Connection
+
+origCVtoP = Database.convertVariantToPython
+def variantToPython(variant, adType):
+    if type(variant) == bool and adType == 11:
+        return variant  # bool not 1/0
+    res = origCVtoP(variant, adType)
+    if mx is not None and type(res) == mx.DateTime.mxDateTime.DateTimeType:
+        # Convert ms.DateTime objects to Python datetime.datetime objects.
+        tv = list(res.tuple()[:7])
+        tv[-2] = int(tv[-2])
+        return datetime.datetime(*tuple(tv))
+    if type(res) == float and str(res)[-2:] == ".0":
+        return int(res) # If float but int, then int.
+    return res
+Database.convertVariantToPython = variantToPython
+
+try:
+    # Only exists in Python 2.4+
+    from threading import local
+except ImportError:
+    # Import copy of _thread_local.py from Python 2.4
+    from django.utils._threading_local import local
+
+class DatabaseWrapper(local):
+    def __init__(self, **kwargs):
+        self.connection = None
+        self.queries = []
+
+    def cursor(self):
+        from django.conf import settings
+        if self.connection is None:
+            if settings.DATABASE_NAME == '' or settings.DATABASE_USER == '':
+                from django.core.exceptions import ImproperlyConfigured
+                raise ImproperlyConfigured, "You need to specify both DATABASE_NAME and DATABASE_USER in your Django settings file."
+            if not settings.DATABASE_HOST:
+                settings.DATABASE_HOST = "127.0.0.1"
+            # TODO: Handle DATABASE_PORT.
+            conn_string = "PROVIDER=SQLOLEDB;DATA SOURCE=%s;UID=%s;PWD=%s;DATABASE=%s" % (settings.DATABASE_HOST, settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME)
+            self.connection = Database.connect(conn_string)
+        cursor = self.connection.cursor()
+        if settings.DEBUG:
+            return util.CursorDebugWrapper(cursor, self)
+        return cursor
+
+    def _commit(self):
+        return self.connection.commit()
+
+    def _rollback(self):
+        if self.connection:
+            return self.connection.rollback()
+
+    def close(self):
+        if self.connection is not None:
+            self.connection.close()
+            self.connection = None
+
+supports_constraints = True
+
+def quote_name(name):
+    if name.startswith('[') and name.endswith(']'):
+        return name # Quoting once is enough.
+    return '[%s]' % name
+
+dictfetchone = util.dictfetchone
+dictfetchmany = util.dictfetchmany
+dictfetchall  = util.dictfetchall
+
+def get_last_insert_id(cursor, table_name, pk_name):
+    cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name))
+    return cursor.fetchone()[0]
+
+def get_date_extract_sql(lookup_type, table_name):
+    # lookup_type is 'year', 'month', 'day'
+    return "DATEPART(%s, %s)" % (lookup_type, table_name)
+
+def get_date_trunc_sql(lookup_type, field_name):
+    # lookup_type is 'year', 'month', 'day'
+    if lookup_type=='year':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/01/01')" % field_name
+    if lookup_type=='month':
+        return "Convert(datetime, Convert(varchar, DATEPART(year, %s)) + '/' + Convert(varchar, DATEPART(month, %s)) + '/01')" % (field_name, field_name)
+    if lookup_type=='day':
+        return "Convert(datetime, Convert(varchar(12), %s))" % field_name
+
+def get_limit_offset_sql(limit, offset=None):
+    # TODO: This is a guess. Make sure this is correct.
+    sql = "LIMIT %s" % limit
+    if offset and offset != 0:
+        sql += " OFFSET %s" % offset
+    return sql
+
+def get_random_function_sql():
+    return "RAND()"
+
+def get_fulltext_search_sql(field_name):
+    raise NotImplementedError
+
+def get_drop_foreignkey_sql():
+    return "DROP CONSTRAINT"
+
+def get_pk_default_value():
+    return "DEFAULT"
+
+OPERATOR_MAPPING = {
+    'exact': '= %s',
+    'iexact': 'LIKE %s',
+    'contains': 'LIKE %s',
+    'icontains': 'LIKE %s',
+    'gt': '> %s',
+    'gte': '>= %s',
+    'lt': '< %s',
+    'lte': '<= %s',
+    'startswith': 'LIKE %s',
+    'endswith': 'LIKE %s',
+    'istartswith': 'LIKE %s',
+    'iendswith': 'LIKE %s',
+}
Index: db/backends/ado_mssql/introspection.py.bak
===================================================================
--- db/backends/ado_mssql/introspection.py.bak	(revision 0)
+++ db/backends/ado_mssql/introspection.py.bak	(revision 0)
@@ -0,0 +1,26 @@
+def get_table_list(cursor):
+    raise NotImplementedError
+
+def get_table_description(cursor, table_name):
+    raise NotImplementedError
+
+def get_relations(cursor, table_name):
+    raise NotImplementedError
+
+def get_indexes(cursor, table_name):
+    raise NotImplementedError
+
+DATA_TYPES_REVERSE = {}
+def get_table_list(cursor):
+    raise NotImplementedError
+
+def get_table_description(cursor, table_name):
+    raise NotImplementedError
+
+def get_relations(cursor, table_name):
+    raise NotImplementedError
+
+def get_indexes(cursor, table_name):
+    raise NotImplementedError
+
+DATA_TYPES_REVERSE = {}
Index: db/models/base.py.bak
===================================================================
--- db/models/base.py.bak	(revision 0)
+++ db/models/base.py.bak	(revision 0)
@@ -0,0 +1,826 @@
+import django.db.models.manipulators
+import django.db.models.manager
+from django.core import validators
+from django.core.exceptions import ObjectDoesNotExist
+from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
+from django.db.models.fields.related import OneToOneRel, ManyToOneRel
+from django.db.models.query import delete_objects
+from django.db.models.options import Options, AdminOptions
+from django.db import connection, backend, transaction
+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.conf import settings
+import types
+import sys
+import os
+
+class ModelBase(type):
+    "Metaclass for all models"
+    def __new__(cls, name, bases, attrs):
+        # If this isn't a subclass of Model, don't do anything special.
+        if not bases or bases == (object,):
+            return type.__new__(cls, name, bases, attrs)
+
+        # Create the class.
+        new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
+        new_class.add_to_class('_meta', Options(attrs.pop('Meta', None)))
+        new_class.add_to_class('DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {}))
+
+        # Build complete list of parents
+        for base in bases:
+            # TODO: Checking for the presence of '_meta' is hackish.
+            if '_meta' in dir(base):
+                new_class._meta.parents.append(base)
+                new_class._meta.parents.extend(base._meta.parents)
+
+        model_module = sys.modules[new_class.__module__]
+
+        if getattr(new_class._meta, 'app_label', None) is None:
+            # Figure out the app_label by looking one level up.
+            # For 'django.contrib.sites.models', this would be 'sites'.
+            new_class._meta.app_label = model_module.__name__.split('.')[-2]
+
+        # Bail out early if we have already created this class.
+        m = get_model(new_class._meta.app_label, name, False)
+        if m is not None:
+            return m
+
+        # Add all attributes to the class.
+        for obj_name, obj in attrs.items():
+            new_class.add_to_class(obj_name, obj)
+
+        # Add Fields inherited from parents
+        for parent in new_class._meta.parents:
+            for field in parent._meta.fields:
+                # Only add parent fields if they aren't defined for this class.
+                try:
+                    new_class._meta.get_field(field.name)
+                except FieldDoesNotExist:
+                    field.contribute_to_class(new_class, field.name)
+
+        new_class._prepare()
+
+        register_models(new_class._meta.app_label, new_class)
+        # Because of the way imports happen (recursively), we may or may not be
+        # the first class for this model to register with the framework. There
+        # should only be one class for each model, so we must always return the
+        # registered version.
+        return get_model(new_class._meta.app_label, name, False)
+
+class Model(object):
+    __metaclass__ = ModelBase
+
+    def _get_pk_val(self):
+        return getattr(self, self._meta.pk.attname)
+
+    def __repr__(self):
+        return '<%s: %s>' % (self.__class__.__name__, self)
+
+    def __str__(self):
+        return '%s object' % self.__class__.__name__
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __init__(self, *args, **kwargs):
+        dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
+        for f in self._meta.fields:
+            if isinstance(f.rel, ManyToOneRel):
+                try:
+                    # Assume object instance was passed in.
+                    rel_obj = kwargs.pop(f.name)
+                except KeyError:
+                    try:
+                        # Object instance wasn't passed in -- must be an ID.
+                        val = kwargs.pop(f.attname)
+                    except KeyError:
+                        val = f.get_default()
+                else:
+                    # Object instance was passed in.
+                    # Special case: You can pass in "None" for related objects if it's allowed.
+                    if rel_obj is None and f.null:
+                        val = None
+                    else:
+                        try:
+                            val = getattr(rel_obj, f.rel.get_related_field().attname)
+                        except AttributeError:
+                            raise TypeError, "Invalid value: %r should be a %s instance, not a %s" % (f.name, f.rel.to, type(rel_obj))
+                setattr(self, f.attname, val)
+            else:
+                val = kwargs.pop(f.attname, f.get_default())
+                setattr(self, f.attname, val)
+        for prop in kwargs.keys():
+            try:
+                if isinstance(getattr(self.__class__, prop), property):
+                    setattr(self, prop, kwargs.pop(prop))
+            except AttributeError:
+                pass
+        if kwargs:
+            raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
+        for i, arg in enumerate(args):
+            setattr(self, self._meta.fields[i].attname, arg)
+        dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
+
+    def add_to_class(cls, name, value):
+        if name == 'Admin':
+            assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value))
+            value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() if not k.startswith('_')]))
+        if hasattr(value, 'contribute_to_class'):
+            value.contribute_to_class(cls, name)
+        else:
+            setattr(cls, name, value)
+    add_to_class = classmethod(add_to_class)
+
+    def _prepare(cls):
+        # Creates some methods once self._meta has been populated.
+        opts = cls._meta
+        opts._prepare(cls)
+
+        if opts.order_with_respect_to:
+            cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
+            cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
+            setattr(opts.order_with_respect_to.rel.to, 'get_%s_order' % cls.__name__.lower(), curry(method_get_order, cls))
+            setattr(opts.order_with_respect_to.rel.to, 'set_%s_order' % cls.__name__.lower(), curry(method_set_order, cls))
+
+        # Give the class a docstring -- its definition.
+        if cls.__doc__ is None:
+            cls.__doc__ = "%s(%s)" % (cls.__name__, ", ".join([f.attname for f in opts.fields]))
+
+        if hasattr(cls, 'get_absolute_url'):
+            cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url)
+
+        dispatcher.send(signal=signals.class_prepared, sender=cls)
+
+    _prepare = classmethod(_prepare)
+
+    def save(self):
+        dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
+
+        non_pks = [f for f in self._meta.fields if not f.primary_key]
+        cursor = connection.cursor()
+
+        # First, try an UPDATE. If that doesn't update anything, do an INSERT.
+        pk_val = self._get_pk_val()
+        pk_set = bool(pk_val)
+        record_exists = True
+        if pk_set:
+            # Determine whether a record with the primary key already exists.
+	    cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % 
+                (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), [pk_val])
+            # If it does already exist, do an UPDATE.
+            if cursor.fetchone():
+                db_values = [f.get_db_prep_save(f.pre_save(self, False)) for f in non_pks]
+                if db_values:
+                    cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \
+                        (backend.quote_name(self._meta.db_table),
+                        ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]),
+                        backend.quote_name(self._meta.pk.column)),
+                        db_values + [pk_val])
+            else:
+                record_exists = False
+        if not pk_set or not record_exists:
+            field_names = [backend.quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)]
+            db_values = [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)]
+            # If the PK has been manually set, respect that.
+            if pk_set:
+                field_names += [f.column for f in self._meta.fields if isinstance(f, AutoField)]
+                db_values += [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)]
+            placeholders = ['%s'] * len(field_names)
+            if self._meta.order_with_respect_to:
+                field_names.append(backend.quote_name('_order'))
+                # TODO: This assumes the database supports subqueries.
+                placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \
+                    (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column)))
+                db_values.append(getattr(self, self._meta.order_with_respect_to.attname))
+            if db_values:
+                cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \
+                    (backend.quote_name(self._meta.db_table), ','.join(field_names),
+                    ','.join(placeholders)), db_values)
+            else:
+                # Create a new record with defaults for everything.
+                cursor.execute("INSERT INTO %s (%s) VALUES (%s)" %
+                    (backend.quote_name(self._meta.db_table),
+                     backend.quote_name(self._meta.pk.column),
+                     backend.get_pk_default_value()))
+            if self._meta.has_auto_field and not pk_set:
+                setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column))
+        transaction.commit_unless_managed()
+
+        # Run any post-save hooks.
+        dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self)
+
+    save.alters_data = True
+
+    def validate(self):
+        """
+        First coerces all fields on this instance to their proper Python types.
+        Then runs validation on every field. Returns a dictionary of
+        field_name -> error_list.
+        """
+        error_dict = {}
+        invalid_python = {}
+        for f in self._meta.fields:
+            try:
+                setattr(self, f.attname, f.to_python(getattr(self, f.attname, f.get_default())))
+            except validators.ValidationError, e:
+                error_dict[f.name] = e.messages
+                invalid_python[f.name] = 1
+        for f in self._meta.fields:
+            if f.name in invalid_python:
+                continue
+            errors = f.validate_full(getattr(self, f.attname, f.get_default()), self.__dict__)
+            if errors:
+                error_dict[f.name] = errors
+        return error_dict
+
+    def _collect_sub_objects(self, seen_objs):
+        """
+        Recursively populates seen_objs with all objects related to this object.
+        When done, seen_objs will be in the format:
+            {model_class: {pk_val: obj, pk_val: obj, ...},
+             model_class: {pk_val: obj, pk_val: obj, ...}, ...}
+        """
+        pk_val = self._get_pk_val()
+        if pk_val in seen_objs.setdefault(self.__class__, {}):
+            return
+        seen_objs.setdefault(self.__class__, {})[pk_val] = self
+
+        for related in self._meta.get_all_related_objects():
+            rel_opts_name = related.get_accessor_name()
+            if isinstance(related.field.rel, OneToOneRel):
+                try:
+                    sub_obj = getattr(self, rel_opts_name)
+                except ObjectDoesNotExist:
+                    pass
+                else:
+                    sub_obj._collect_sub_objects(seen_objs)
+            else:
+                for sub_obj in getattr(self, rel_opts_name).all():
+                    sub_obj._collect_sub_objects(seen_objs)
+
+    def delete(self):
+        assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
+
+        # Find all the objects than need to be deleted
+        seen_objs = SortedDict()
+        self._collect_sub_objects(seen_objs)
+
+        # Actually delete the objects
+        delete_objects(seen_objs)
+
+    delete.alters_data = True
+
+    def _get_FIELD_display(self, field):
+        value = getattr(self, field.attname)
+        return dict(field.choices).get(value, value)
+
+    def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
+        op = is_next and '>' or '<'
+        where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \
+            (backend.quote_name(field.column), op, backend.quote_name(field.column),
+            backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column), op)
+        param = str(getattr(self, field.attname))
+        q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name)
+        q._where.append(where)
+        q._params.extend([param, param, getattr(self, self._meta.pk.attname)])
+        try:
+            return q[0]
+        except IndexError:
+            raise self.DoesNotExist, "%s matching query does not exist." % self.__class__._meta.object_name
+
+    def _get_next_or_previous_in_order(self, is_next):
+        cachename = "__%s_order_cache" % is_next
+        if not hasattr(self, cachename):
+            op = is_next and '>' or '<'
+            order_field = self._meta.order_with_respect_to
+            where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \
+                (backend.quote_name('_order'), op, backend.quote_name('_order'),
+                backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),
+                '%s=%%s' % backend.quote_name(order_field.column)]
+            params = [self._get_pk_val(), getattr(self, order_field.attname)]
+            obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get()
+            setattr(self, cachename, obj)
+        return getattr(self, cachename)
+
+    def _get_FIELD_filename(self, field):
+        if getattr(self, field.attname): # value is not blank
+            return os.path.join(settings.MEDIA_ROOT, getattr(self, field.attname))
+        return ''
+
+    def _get_FIELD_url(self, field):
+        if getattr(self, field.attname): # value is not blank
+            import urlparse
+            return urlparse.urljoin(settings.MEDIA_URL, getattr(self, field.attname)).replace('\\', '/')
+        return ''
+
+    def _get_FIELD_size(self, field):
+        return os.path.getsize(self._get_FIELD_filename(field))
+
+    def _save_FIELD_file(self, field, filename, raw_contents):
+        directory = field.get_directory_name()
+        try: # Create the date-based directory if it doesn't exist.
+            os.makedirs(os.path.join(settings.MEDIA_ROOT, directory))
+        except OSError: # Directory probably already exists.
+            pass
+        filename = field.get_filename(filename)
+
+        # If the filename already exists, keep adding an underscore to the name of
+        # the file until the filename doesn't exist.
+        while os.path.exists(os.path.join(settings.MEDIA_ROOT, filename)):
+            try:
+                dot_index = filename.rindex('.')
+            except ValueError: # filename has no dot
+                filename += '_'
+            else:
+                filename = filename[:dot_index] + '_' + filename[dot_index:]
+
+        # Write the file to disk.
+        setattr(self, field.attname, filename)
+
+        full_filename = self._get_FIELD_filename(field)
+        fp = open(full_filename, 'wb')
+        fp.write(raw_contents)
+        fp.close()
+
+        # Save the width and/or height, if applicable.
+        if isinstance(field, ImageField) and (field.width_field or field.height_field):
+            from django.utils.images import get_image_dimensions
+            width, height = get_image_dimensions(full_filename)
+            if field.width_field:
+                setattr(self, field.width_field, width)
+            if field.height_field:
+                setattr(self, field.height_field, height)
+
+        # Save the object, because it has changed.
+        self.save()
+
+    _save_FIELD_file.alters_data = True
+
+    def _get_FIELD_width(self, field):
+        return self._get_image_dimensions(field)[0]
+
+    def _get_FIELD_height(self, field):
+        return self._get_image_dimensions(field)[1]
+
+    def _get_image_dimensions(self, field):
+        cachename = "__%s_dimensions_cache" % field.name
+        if not hasattr(self, cachename):
+            from django.utils.images import get_image_dimensions
+            filename = self._get_FIELD_filename(field)
+            setattr(self, cachename, get_image_dimensions(filename))
+        return getattr(self, cachename)
+
+############################################
+# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
+############################################
+
+# ORDERING METHODS #########################
+
+def method_set_order(ordered_obj, self, id_list):
+    cursor = connection.cursor()
+    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
+    sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
+        (backend.quote_name(ordered_obj._meta.db_table), backend.quote_name('_order'),
+        backend.quote_name(ordered_obj._meta.order_with_respect_to.column),
+        backend.quote_name(ordered_obj._meta.pk.column))
+    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
+    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
+    transaction.commit_unless_managed()
+
+def method_get_order(ordered_obj, self):
+    cursor = connection.cursor()
+    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
+    sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \
+        (backend.quote_name(ordered_obj._meta.pk.column),
+        backend.quote_name(ordered_obj._meta.db_table),
+        backend.quote_name(ordered_obj._meta.order_with_respect_to.column),
+        backend.quote_name('_order'))
+    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
+    cursor.execute(sql, [rel_val])
+    return [r[0] for r in cursor.fetchall()]
+
+##############################################
+# HELPER FUNCTIONS (CURRIED MODEL FUNCTIONS) #
+##############################################
+
+def get_absolute_url(opts, func, self):
+    return settings.ABSOLUTE_URL_OVERRIDES.get('%s.%s' % (opts.app_label, opts.module_name), func)(self)
+import django.db.models.manipulators
+import django.db.models.manager
+from django.core import validators
+from django.core.exceptions import ObjectDoesNotExist
+from django.db.models.fields import AutoField, ImageField, FieldDoesNotExist
+from django.db.models.fields.related import OneToOneRel, ManyToOneRel
+from django.db.models.query import delete_objects
+from django.db.models.options import Options, AdminOptions
+from django.db import connection, backend, transaction
+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.conf import settings
+import types
+import sys
+import os
+
+class ModelBase(type):
+    "Metaclass for all models"
+    def __new__(cls, name, bases, attrs):
+        # If this isn't a subclass of Model, don't do anything special.
+        if not bases or bases == (object,):
+            return type.__new__(cls, name, bases, attrs)
+
+        # Create the class.
+        new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
+        new_class.add_to_class('_meta', Options(attrs.pop('Meta', None)))
+        new_class.add_to_class('DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {}))
+
+        # Build complete list of parents
+        for base in bases:
+            # TODO: Checking for the presence of '_meta' is hackish.
+            if '_meta' in dir(base):
+                new_class._meta.parents.append(base)
+                new_class._meta.parents.extend(base._meta.parents)
+
+        model_module = sys.modules[new_class.__module__]
+
+        if getattr(new_class._meta, 'app_label', None) is None:
+            # Figure out the app_label by looking one level up.
+            # For 'django.contrib.sites.models', this would be 'sites'.
+            new_class._meta.app_label = model_module.__name__.split('.')[-2]
+
+        # Bail out early if we have already created this class.
+        m = get_model(new_class._meta.app_label, name, False)
+        if m is not None:
+            return m
+
+        # Add all attributes to the class.
+        for obj_name, obj in attrs.items():
+            new_class.add_to_class(obj_name, obj)
+
+        # Add Fields inherited from parents
+        for parent in new_class._meta.parents:
+            for field in parent._meta.fields:
+                # Only add parent fields if they aren't defined for this class.
+                try:
+                    new_class._meta.get_field(field.name)
+                except FieldDoesNotExist:
+                    field.contribute_to_class(new_class, field.name)
+
+        new_class._prepare()
+
+        register_models(new_class._meta.app_label, new_class)
+        # Because of the way imports happen (recursively), we may or may not be
+        # the first class for this model to register with the framework. There
+        # should only be one class for each model, so we must always return the
+        # registered version.
+        return get_model(new_class._meta.app_label, name, False)
+
+class Model(object):
+    __metaclass__ = ModelBase
+
+    def _get_pk_val(self):
+        return getattr(self, self._meta.pk.attname)
+
+    def __repr__(self):
+        return '<%s: %s>' % (self.__class__.__name__, self)
+
+    def __str__(self):
+        return '%s object' % self.__class__.__name__
+
+    def __eq__(self, other):
+        return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val()
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __init__(self, *args, **kwargs):
+        dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs)
+        for f in self._meta.fields:
+            if isinstance(f.rel, ManyToOneRel):
+                try:
+                    # Assume object instance was passed in.
+                    rel_obj = kwargs.pop(f.name)
+                except KeyError:
+                    try:
+                        # Object instance wasn't passed in -- must be an ID.
+                        val = kwargs.pop(f.attname)
+                    except KeyError:
+                        val = f.get_default()
+                else:
+                    # Object instance was passed in.
+                    # Special case: You can pass in "None" for related objects if it's allowed.
+                    if rel_obj is None and f.null:
+                        val = None
+                    else:
+                        try:
+                            val = getattr(rel_obj, f.rel.get_related_field().attname)
+                        except AttributeError:
+                            raise TypeError, "Invalid value: %r should be a %s instance, not a %s" % (f.name, f.rel.to, type(rel_obj))
+                setattr(self, f.attname, val)
+            else:
+                val = kwargs.pop(f.attname, f.get_default())
+                setattr(self, f.attname, val)
+        for prop in kwargs.keys():
+            try:
+                if isinstance(getattr(self.__class__, prop), property):
+                    setattr(self, prop, kwargs.pop(prop))
+            except AttributeError:
+                pass
+        if kwargs:
+            raise TypeError, "'%s' is an invalid keyword argument for this function" % kwargs.keys()[0]
+        for i, arg in enumerate(args):
+            setattr(self, self._meta.fields[i].attname, arg)
+        dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self)
+
+    def add_to_class(cls, name, value):
+        if name == 'Admin':
+            assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value))
+            value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() if not k.startswith('_')]))
+        if hasattr(value, 'contribute_to_class'):
+            value.contribute_to_class(cls, name)
+        else:
+            setattr(cls, name, value)
+    add_to_class = classmethod(add_to_class)
+
+    def _prepare(cls):
+        # Creates some methods once self._meta has been populated.
+        opts = cls._meta
+        opts._prepare(cls)
+
+        if opts.order_with_respect_to:
+            cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True)
+            cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False)
+            setattr(opts.order_with_respect_to.rel.to, 'get_%s_order' % cls.__name__.lower(), curry(method_get_order, cls))
+            setattr(opts.order_with_respect_to.rel.to, 'set_%s_order' % cls.__name__.lower(), curry(method_set_order, cls))
+
+        # Give the class a docstring -- its definition.
+        if cls.__doc__ is None:
+            cls.__doc__ = "%s(%s)" % (cls.__name__, ", ".join([f.attname for f in opts.fields]))
+
+        if hasattr(cls, 'get_absolute_url'):
+            cls.get_absolute_url = curry(get_absolute_url, opts, cls.get_absolute_url)
+
+        dispatcher.send(signal=signals.class_prepared, sender=cls)
+
+    _prepare = classmethod(_prepare)
+
+    def save(self):
+        dispatcher.send(signal=signals.pre_save, sender=self.__class__, instance=self)
+
+        non_pks = [f for f in self._meta.fields if not f.primary_key]
+        cursor = connection.cursor()
+
+        # First, try an UPDATE. If that doesn't update anything, do an INSERT.
+        pk_val = self._get_pk_val()
+        pk_set = bool(pk_val)
+        record_exists = True
+        if pk_set:
+            # Determine whether a record with the primary key already exists.
+	    cursor.execute("SELECT 1 FROM %s WHERE %s=%%s" % 
+                (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)), [pk_val])
+            # If it does already exist, do an UPDATE.
+            if cursor.fetchone():
+                db_values = [f.get_db_prep_save(f.pre_save(self, False)) for f in non_pks]
+                if db_values:
+                    cursor.execute("UPDATE %s SET %s WHERE %s=%%s" % \
+                        (backend.quote_name(self._meta.db_table),
+                        ','.join(['%s=%%s' % backend.quote_name(f.column) for f in non_pks]),
+                        backend.quote_name(self._meta.pk.column)),
+                        db_values + [pk_val])
+            else:
+                record_exists = False
+        if not pk_set or not record_exists:
+            field_names = [backend.quote_name(f.column) for f in self._meta.fields if not isinstance(f, AutoField)]
+            db_values = [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if not isinstance(f, AutoField)]
+            # If the PK has been manually set, respect that.
+            if pk_set:
+                field_names += [f.column for f in self._meta.fields if isinstance(f, AutoField)]
+                db_values += [f.get_db_prep_save(f.pre_save(self, True)) for f in self._meta.fields if isinstance(f, AutoField)]
+            placeholders = ['%s'] * len(field_names)
+            if self._meta.order_with_respect_to:
+                field_names.append(backend.quote_name('_order'))
+                # TODO: This assumes the database supports subqueries.
+                placeholders.append('(SELECT COUNT(*) FROM %s WHERE %s = %%s)' % \
+                    (backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.order_with_respect_to.column)))
+                db_values.append(getattr(self, self._meta.order_with_respect_to.attname))
+            if db_values:
+                cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \
+                    (backend.quote_name(self._meta.db_table), ','.join(field_names),
+                    ','.join(placeholders)), db_values)
+            else:
+                # Create a new record with defaults for everything.
+                cursor.execute("INSERT INTO %s (%s) VALUES (%s)" %
+                    (backend.quote_name(self._meta.db_table),
+                     backend.quote_name(self._meta.pk.column),
+                     backend.get_pk_default_value()))
+            if self._meta.has_auto_field and not pk_set:
+                setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column))
+        transaction.commit_unless_managed()
+
+        # Run any post-save hooks.
+        dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self)
+
+    save.alters_data = True
+
+    def validate(self):
+        """
+        First coerces all fields on this instance to their proper Python types.
+        Then runs validation on every field. Returns a dictionary of
+        field_name -> error_list.
+        """
+        error_dict = {}
+        invalid_python = {}
+        for f in self._meta.fields:
+            try:
+                setattr(self, f.attname, f.to_python(getattr(self, f.attname, f.get_default())))
+            except validators.ValidationError, e:
+                error_dict[f.name] = e.messages
+                invalid_python[f.name] = 1
+        for f in self._meta.fields:
+            if f.name in invalid_python:
+                continue
+            errors = f.validate_full(getattr(self, f.attname, f.get_default()), self.__dict__)
+            if errors:
+                error_dict[f.name] = errors
+        return error_dict
+
+    def _collect_sub_objects(self, seen_objs):
+        """
+        Recursively populates seen_objs with all objects related to this object.
+        When done, seen_objs will be in the format:
+            {model_class: {pk_val: obj, pk_val: obj, ...},
+             model_class: {pk_val: obj, pk_val: obj, ...}, ...}
+        """
+        pk_val = self._get_pk_val()
+        if pk_val in seen_objs.setdefault(self.__class__, {}):
+            return
+        seen_objs.setdefault(self.__class__, {})[pk_val] = self
+
+        for related in self._meta.get_all_related_objects():
+            rel_opts_name = related.get_accessor_name()
+            if isinstance(related.field.rel, OneToOneRel):
+                try:
+                    sub_obj = getattr(self, rel_opts_name)
+                except ObjectDoesNotExist:
+                    pass
+                else:
+                    sub_obj._collect_sub_objects(seen_objs)
+            else:
+                for sub_obj in getattr(self, rel_opts_name).all():
+                    sub_obj._collect_sub_objects(seen_objs)
+
+    def delete(self):
+        assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
+
+        # Find all the objects than need to be deleted
+        seen_objs = SortedDict()
+        self._collect_sub_objects(seen_objs)
+
+        # Actually delete the objects
+        delete_objects(seen_objs)
+
+    delete.alters_data = True
+
+    def _get_FIELD_display(self, field):
+        value = getattr(self, field.attname)
+        return dict(field.choices).get(value, value)
+
+    def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs):
+        op = is_next and '>' or '<'
+        where = '(%s %s %%s OR (%s = %%s AND %s.%s %s %%s))' % \
+            (backend.quote_name(field.column), op, backend.quote_name(field.column),
+            backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column), op)
+        param = str(getattr(self, field.attname))
+        q = self.__class__._default_manager.filter(**kwargs).order_by((not is_next and '-' or '') + field.name, (not is_next and '-' or '') + self._meta.pk.name)
+        q._where.append(where)
+        q._params.extend([param, param, getattr(self, self._meta.pk.attname)])
+        try:
+            return q[0]
+        except IndexError:
+            raise self.DoesNotExist, "%s matching query does not exist." % self.__class__._meta.object_name
+
+    def _get_next_or_previous_in_order(self, is_next):
+        cachename = "__%s_order_cache" % is_next
+        if not hasattr(self, cachename):
+            op = is_next and '>' or '<'
+            order_field = self._meta.order_with_respect_to
+            where = ['%s %s (SELECT %s FROM %s WHERE %s=%%s)' % \
+                (backend.quote_name('_order'), op, backend.quote_name('_order'),
+                backend.quote_name(self._meta.db_table), backend.quote_name(self._meta.pk.column)),
+                '%s=%%s' % backend.quote_name(order_field.column)]
+            params = [self._get_pk_val(), getattr(self, order_field.attname)]
+            obj = self._default_manager.order_by('_order').extra(where=where, params=params)[:1].get()
+            setattr(self, cachename, obj)
+        return getattr(self, cachename)
+
+    def _get_FIELD_filename(self, field):
+        if getattr(self, field.attname): # value is not blank
+            return os.path.join(settings.MEDIA_ROOT, getattr(self, field.attname))
+        return ''
+
+    def _get_FIELD_url(self, field):
+        if getattr(self, field.attname): # value is not blank
+            import urlparse
+            return urlparse.urljoin(settings.MEDIA_URL, getattr(self, field.attname)).replace('\\', '/')
+        return ''
+
+    def _get_FIELD_size(self, field):
+        return os.path.getsize(self._get_FIELD_filename(field))
+
+    def _save_FIELD_file(self, field, filename, raw_contents):
+        directory = field.get_directory_name()
+        try: # Create the date-based directory if it doesn't exist.
+            os.makedirs(os.path.join(settings.MEDIA_ROOT, directory))
+        except OSError: # Directory probably already exists.
+            pass
+        filename = field.get_filename(filename)
+
+        # If the filename already exists, keep adding an underscore to the name of
+        # the file until the filename doesn't exist.
+        while os.path.exists(os.path.join(settings.MEDIA_ROOT, filename)):
+            try:
+                dot_index = filename.rindex('.')
+            except ValueError: # filename has no dot
+                filename += '_'
+            else:
+                filename = filename[:dot_index] + '_' + filename[dot_index:]
+
+        # Write the file to disk.
+        setattr(self, field.attname, filename)
+
+        full_filename = self._get_FIELD_filename(field)
+        fp = open(full_filename, 'wb')
+        fp.write(raw_contents)
+        fp.close()
+
+        # Save the width and/or height, if applicable.
+        if isinstance(field, ImageField) and (field.width_field or field.height_field):
+            from django.utils.images import get_image_dimensions
+            width, height = get_image_dimensions(full_filename)
+            if field.width_field:
+                setattr(self, field.width_field, width)
+            if field.height_field:
+                setattr(self, field.height_field, height)
+
+        # Save the object, because it has changed.
+        self.save()
+
+    _save_FIELD_file.alters_data = True
+
+    def _get_FIELD_width(self, field):
+        return self._get_image_dimensions(field)[0]
+
+    def _get_FIELD_height(self, field):
+        return self._get_image_dimensions(field)[1]
+
+    def _get_image_dimensions(self, field):
+        cachename = "__%s_dimensions_cache" % field.name
+        if not hasattr(self, cachename):
+            from django.utils.images import get_image_dimensions
+            filename = self._get_FIELD_filename(field)
+            setattr(self, cachename, get_image_dimensions(filename))
+        return getattr(self, cachename)
+
+############################################
+# HELPER FUNCTIONS (CURRIED MODEL METHODS) #
+############################################
+
+# ORDERING METHODS #########################
+
+def method_set_order(ordered_obj, self, id_list):
+    cursor = connection.cursor()
+    # Example: "UPDATE poll_choices SET _order = %s WHERE poll_id = %s AND id = %s"
+    sql = "UPDATE %s SET %s = %%s WHERE %s = %%s AND %s = %%s" % \
+        (backend.quote_name(ordered_obj._meta.db_table), backend.quote_name('_order'),
+        backend.quote_name(ordered_obj._meta.order_with_respect_to.column),
+        backend.quote_name(ordered_obj._meta.pk.column))
+    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
+    cursor.executemany(sql, [(i, rel_val, j) for i, j in enumerate(id_list)])
+    transaction.commit_unless_managed()
+
+def method_get_order(ordered_obj, self):
+    cursor = connection.cursor()
+    # Example: "SELECT id FROM poll_choices WHERE poll_id = %s ORDER BY _order"
+    sql = "SELECT %s FROM %s WHERE %s = %%s ORDER BY %s" % \
+        (backend.quote_name(ordered_obj._meta.pk.column),
+        backend.quote_name(ordered_obj._meta.db_table),
+        backend.quote_name(ordered_obj._meta.order_with_respect_to.column),
+        backend.quote_name('_order'))
+    rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name)
+    cursor.execute(sql, [rel_val])
+    return [r[0] for r in cursor.fetchall()]
+
+##############################################
+# HELPER FUNCTIONS (CURRIED MODEL FUNCTIONS) #
+##############################################
+
+def get_absolute_url(opts, func, self):
+    return settings.ABSOLUTE_URL_OVERRIDES.get('%s.%s' % (opts.app_label, opts.module_name), func)(self)
Index: db/models/fields/__init__.py.bak
===================================================================
--- db/models/fields/__init__.py.bak	(revision 0)
+++ db/models/fields/__init__.py.bak	(revision 0)
@@ -0,0 +1,1682 @@
+from django.db.models import signals
+from django.dispatch import dispatcher
+from django.conf import settings
+from django.core import validators
+from django import oldforms
+from django import newforms as forms
+from django.core.exceptions import ObjectDoesNotExist
+from django.utils.functional import curry
+from django.utils.itercompat import tee
+from django.utils.text import capfirst
+from django.utils.translation import gettext, gettext_lazy
+import datetime, os, time
+
+class NOT_PROVIDED:
+    pass
+
+# Values for filter_interface.
+HORIZONTAL, VERTICAL = 1, 2
+
+# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists.
+BLANK_CHOICE_DASH = [("", "---------")]
+BLANK_CHOICE_NONE = [("", "None")]
+
+# prepares a value for use in a LIKE query
+prep_for_like_query = lambda x: str(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
+
+# returns the <ul> class for a given radio_admin value
+get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
+
+class FieldDoesNotExist(Exception):
+    pass
+
+def manipulator_validator_unique(f, opts, self, field_data, all_data):
+    "Validates that the value is unique for this field."
+    lookup_type = f.get_validator_unique_lookup_type()
+    try:
+        old_obj = self.manager.get(**{lookup_type: field_data})
+    except ObjectDoesNotExist:
+        return
+    if getattr(self, 'original_object', None) and self.original_object._get_pk_val() == old_obj._get_pk_val():
+        return
+    raise validators.ValidationError, gettext("%(optname)s with this %(fieldname)s already exists.") % {'optname': capfirst(opts.verbose_name), 'fieldname': f.verbose_name}
+
+# A guide to Field parameters:
+#
+#   * name:      The name of the field specifed in the model.
+#   * attname:   The attribute to use on the model object. This is the same as
+#                "name", except in the case of ForeignKeys, where "_id" is
+#                appended.
+#   * db_column: The db_column specified in the model (or None).
+#   * column:    The database column for this field. This is the same as
+#                "attname", except if db_column is specified.
+#
+# Code that introspects values, or does other dynamic things, should use
+# attname. For example, this gets the primary key value of object "obj":
+#
+#     getattr(obj, opts.pk.attname)
+
+class Field(object):
+
+    # Designates whether empty strings fundamentally are allowed at the
+    # database level.
+    empty_strings_allowed = True
+
+    # Tracks each time a Field instance is created. Used to retain order.
+    creation_counter = 0
+
+    def __init__(self, verbose_name=None, name=None, primary_key=False,
+        maxlength=None, unique=False, blank=False, null=False, db_index=False,
+        core=False, rel=None, default=NOT_PROVIDED, editable=True,
+        prepopulate_from=None, unique_for_date=None, unique_for_month=None,
+        unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
+        help_text='', db_column=None):
+        self.name = name
+        self.verbose_name = verbose_name
+        self.primary_key = primary_key
+        self.maxlength, self.unique = maxlength, unique
+        self.blank, self.null = blank, null
+        self.core, self.rel, self.default = core, rel, default
+        self.editable = editable
+        self.validator_list = validator_list or []
+        self.prepopulate_from = prepopulate_from
+        self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
+        self.unique_for_year = unique_for_year
+        self._choices = choices or []
+        self.radio_admin = radio_admin
+        self.help_text = help_text
+        self.db_column = db_column
+
+        # Set db_index to True if the field has a relationship and doesn't explicitly set db_index.
+        self.db_index = db_index
+
+        # Increase the creation counter, and save our local copy.
+        self.creation_counter = Field.creation_counter
+        Field.creation_counter += 1
+
+    def __cmp__(self, other):
+        # This is needed because bisect does not take a comparison function.
+        return cmp(self.creation_counter, other.creation_counter)
+
+    def to_python(self, value):
+        """
+        Converts the input value into the expected Python data type, raising
+        validators.ValidationError if the data can't be converted. Returns the
+        converted value. Subclasses should override this.
+        """
+        return value
+
+    def validate_full(self, field_data, all_data):
+        """
+        Returns a list of errors for this field. This is the main interface,
+        as it encapsulates some basic validation logic used by all fields.
+        Subclasses should implement validate(), not validate_full().
+        """
+        if not self.blank and not field_data:
+            return [gettext_lazy('This field is required.')]
+        try:
+            self.validate(field_data, all_data)
+        except validators.ValidationError, e:
+            return e.messages
+        return []
+
+    def validate(self, field_data, all_data):
+        """
+        Raises validators.ValidationError if field_data has any errors.
+        Subclasses should override this to specify field-specific validation
+        logic. This method should assume field_data has already been converted
+        into the appropriate data type by Field.to_python().
+        """
+        pass
+
+    def set_attributes_from_name(self, name):
+        self.name = name
+        self.attname, self.column = self.get_attname_column()
+        self.verbose_name = self.verbose_name or (name and name.replace('_', ' '))
+
+    def contribute_to_class(self, cls, name):
+        self.set_attributes_from_name(name)
+        cls._meta.add_field(self)
+        if self.choices:
+            setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self))
+
+    def get_attname(self):
+        return self.name
+
+    def get_attname_column(self):
+        attname = self.get_attname()
+        column = self.db_column or attname
+        return attname, column
+
+    def get_cache_name(self):
+        return '_%s_cache' % self.name
+
+    def get_internal_type(self):
+        return self.__class__.__name__
+
+    def pre_save(self, model_instance, add):
+        "Returns field's value just before saving."
+        return getattr(model_instance, self.attname)
+
+    def get_db_prep_save(self, value):
+        "Returns field's value prepared for saving into a database."
+        return value
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        "Returns field's value prepared for database lookup."
+        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'year', 'month', 'day', 'search'):
+            return [value]
+        elif lookup_type in ('range', 'in'):
+            return value
+        elif lookup_type in ('contains', 'icontains'):
+            return ["%%%s%%" % prep_for_like_query(value)]
+        elif lookup_type == 'iexact':
+            return [prep_for_like_query(value)]
+        elif lookup_type in ('startswith', 'istartswith'):
+            return ["%s%%" % prep_for_like_query(value)]
+        elif lookup_type in ('endswith', 'iendswith'):
+            return ["%%%s" % prep_for_like_query(value)]
+        elif lookup_type == 'isnull':
+            return []
+        raise TypeError, "Field has invalid lookup: %s" % lookup_type
+
+    def has_default(self):
+        "Returns a boolean of whether this field has a default value."
+        return self.default is not NOT_PROVIDED
+
+    def get_default(self):
+        "Returns the default value for this field."
+        if self.default is not NOT_PROVIDED:
+            if callable(self.default):
+                return self.default()
+            return self.default
+        if not self.empty_strings_allowed or self.null:
+            return None
+        return ""
+
+    def get_manipulator_field_names(self, name_prefix):
+        """
+        Returns a list of field names that this object adds to the manipulator.
+        """
+        return [name_prefix + self.name]
+
+    def prepare_field_objs_and_params(self, manipulator, name_prefix):
+        params = {'validator_list': self.validator_list[:]}
+        if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
+            params['maxlength'] = self.maxlength
+
+        if self.choices:
+            if self.radio_admin:
+                field_objs = [oldforms.RadioSelectField]
+                params['ul_class'] = get_ul_class(self.radio_admin)
+            else:
+                field_objs = [oldforms.SelectField]
+
+            params['choices'] = self.get_choices_default()
+        else:
+            field_objs = self.get_manipulator_field_objs()
+        return (field_objs, params)
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        """
+        Returns a list of oldforms.FormField instances for this field. It
+        calculates the choices at runtime, not at compile time.
+
+        name_prefix is a prefix to prepend to the "field_name" argument.
+        rel is a boolean specifying whether this field is in a related context.
+        """
+        field_objs, params = self.prepare_field_objs_and_params(manipulator, name_prefix)
+
+        # Add the "unique" validator(s).
+        for field_name_list in opts.unique_together:
+            if field_name_list[0] == self.name:
+                params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list)))
+
+        # Add the "unique for..." validator(s).
+        if self.unique_for_date:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date)))
+        if self.unique_for_month:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
+        if self.unique_for_year:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
+        if self.unique or (self.primary_key and not rel):
+            params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
+
+        # Only add is_required=True if the field cannot be blank. Primary keys
+        # are a special case, and fields in a related context should set this
+        # as False, because they'll be caught by a separate validator --
+        # RequiredIfOtherFieldGiven.
+        params['is_required'] = not self.blank and not self.primary_key and not rel
+
+        # BooleanFields (CheckboxFields) are a special case. They don't take
+        # is_required.
+        if isinstance(self, BooleanField):
+            del params['is_required']
+
+        # If this field is in a related context, check whether any other fields
+        # in the related object have core=True. If so, add a validator --
+        # RequiredIfOtherFieldsGiven -- to this FormField.
+        if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField):
+            # First, get the core fields, if any.
+            core_field_names = []
+            for f in opts.fields:
+                if f.core and f != self:
+                    core_field_names.extend(f.get_manipulator_field_names(name_prefix))
+            # Now, if there are any, add the validator to this FormField.
+            if core_field_names:
+                params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, gettext_lazy("This field is required.")))
+
+        # Finally, add the field_names.
+        field_names = self.get_manipulator_field_names(name_prefix)
+        return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
+
+    def get_validator_unique_lookup_type(self):
+        return '%s__exact' % self.name
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        """
+        Given the full new_data dictionary (from the manipulator), returns this
+        field's data.
+        """
+        if rel:
+            return new_data.get(self.name, [self.get_default()])[0]
+        val = new_data.get(self.name, self.get_default())
+        if not self.empty_strings_allowed and val == '' and self.null:
+            val = None
+        return val
+
+    def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
+        "Returns a list of tuples used as SelectField choices for this field."
+        first_choice = include_blank and blank_choice or []
+        if self.choices:
+            return first_choice + list(self.choices)
+        rel_model = self.rel.to
+        if hasattr(self.rel, 'get_related_field'):
+            lst = [(getattr(x, self.rel.get_related_field().attname), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
+        else:
+            lst = [(x._get_pk_val(), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
+        return first_choice + lst
+
+    def get_choices_default(self):
+        if self.radio_admin:
+            return self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
+        else:
+            return self.get_choices()
+
+    def _get_val_from_obj(self, obj):
+        if obj:
+            return getattr(obj, self.attname)
+        else:
+            return self.get_default()
+
+    def flatten_data(self, follow, obj=None):
+        """
+        Returns a dictionary mapping the field's manipulator field names to its
+        "flattened" string values for the admin view. obj is the instance to
+        extract the values from.
+        """
+        return {self.attname: self._get_val_from_obj(obj)}
+
+    def get_follow(self, override=None):
+        if override != None:
+            return override
+        else:
+            return self.editable
+
+    def bind(self, fieldmapping, original, bound_field_class):
+        return bound_field_class(self, fieldmapping, original)
+
+    def _get_choices(self):
+        if hasattr(self._choices, 'next'):
+            choices, self._choices = tee(self._choices)
+            return choices
+        else:
+            return self._choices
+    choices = property(_get_choices)
+
+    def formfield(self):
+        "Returns a django.newforms.Field instance for this database Field."
+        # TODO: This is just a temporary default during development.
+        return forms.CharField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class AutoField(Field):
+    empty_strings_allowed = False
+    def __init__(self, *args, **kwargs):
+        assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__
+        kwargs['blank'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def to_python(self, value):
+        if value is None:
+            return value
+        try:
+            return int(value)
+        except (TypeError, ValueError):
+            raise validators.ValidationError, gettext("This value must be an integer.")
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        if not rel:
+            return [] # Don't add a FormField unless it's in a related context.
+        return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.HiddenField]
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        # Never going to be called
+        # Not in main change pages
+        # ignored in related context
+        if not rel:
+            return None
+        return Field.get_manipulator_new_data(self, new_data, rel)
+
+    def contribute_to_class(self, cls, name):
+        assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
+        super(AutoField, self).contribute_to_class(cls, name)
+        cls._meta.has_auto_field = True
+
+    def formfield(self):
+        return None
+
+class BooleanField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['blank'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def to_python(self, value):
+        if value in (True, False): return value
+        if value in ('t', 'True', '1'): return True
+        if value in ('f', 'False', '0'): return False
+        raise validators.ValidationError, gettext("This value must be either True or False.")
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.CheckboxField]
+
+    def formfield(self):
+        return forms.BooleanField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class CharField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.TextField]
+
+    def to_python(self, value):
+        if isinstance(value, basestring):
+            return value
+        if value is None:
+            if self.null:
+                return value
+            else:
+                raise validators.ValidationError, gettext_lazy("This field cannot be null.")
+        return str(value)
+
+    def formfield(self):
+        return forms.CharField(max_length=self.maxlength, required=not self.blank, label=capfirst(self.verbose_name))
+
+# TODO: Maybe move this into contrib, because it's specialized.
+class CommaSeparatedIntegerField(CharField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.CommaSeparatedIntegerField]
+
+class DateField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
+        self.auto_now, self.auto_now_add = auto_now, auto_now_add
+        #HACKs : auto_now_add/auto_now should be done as a default or a pre_save.
+        if auto_now or auto_now_add:
+            kwargs['editable'] = False
+            kwargs['blank'] = True
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def to_python(self, value):
+        if isinstance(value, datetime.datetime):
+            return value.date()
+        if isinstance(value, datetime.date):
+            return value
+        validators.isValidANSIDate(value, None)
+        try:
+            return datetime.date(*time.strptime(value, '%Y-%m-%d')[:3])
+        except ValueError:
+            raise validators.ValidationError, gettext('Enter a valid date in YYYY-MM-DD format.')
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'):
+            value = value.strftime('%Y-%m-%d')
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def pre_save(self, model_instance, add):
+        if self.auto_now or (self.auto_now_add and add):
+            value = datetime.datetime.now()
+            setattr(model_instance, self.attname, value)
+            return value
+        else:
+            return super(DateField, self).pre_save(model_instance, add)
+
+    def contribute_to_class(self, cls, name):
+        super(DateField,self).contribute_to_class(cls, name)
+        if not self.null:
+            setattr(cls, 'get_next_by_%s' % self.name,
+                curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=True))
+            setattr(cls, 'get_previous_by_%s' % self.name,
+                curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=False))
+
+    # Needed because of horrible auto_now[_add] behaviour wrt. editable
+    def get_follow(self, override=None):
+        if override != None:
+            return override
+        else:
+            return self.editable or self.auto_now or self.auto_now_add
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            value = value.strftime('%Y-%m-%d')
+        return Field.get_db_prep_save(self, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.DateField]
+
+    def flatten_data(self, follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        return {self.attname: (val is not None and val.strftime("%Y-%m-%d") or '')}
+
+    def formfield(self):
+        return forms.DateField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class DateTimeField(DateField):
+    def to_python(self, value):
+        if isinstance(value, datetime.datetime):
+            return value
+        if isinstance(value, datetime.date):
+            return datetime.datetime(value.year, value.month, value.day)
+        try: # Seconds are optional, so try converting seconds first.
+            return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6])
+        except ValueError:
+            try: # Try without seconds.
+                return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5])
+            except ValueError: # Try without hour/minutes/seconds.
+                try:
+                    return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3])
+                except ValueError:
+                    raise validators.ValidationError, gettext('Enter a valid date/time in YYYY-MM-DD HH:MM format.')
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            # MySQL will throw a warning if microseconds are given, because it
+            # doesn't support microseconds.
+            if (settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'ado_mssql') and hasattr(value, 'microsecond'):
+                value = value.replace(microsecond=0)
+            value = str(value)
+        return Field.get_db_prep_save(self, value)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+	# MSSQL doesn't like microseconds. 
+        if settings.DATABASE_ENGINE == 'ado_mssql' and hasattr(value, 'microsecond'):
+	    value = value.replace(microsecond=0)	
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.DateField, oldforms.TimeField]
+
+    def get_manipulator_field_names(self, name_prefix):
+        return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        date_field, time_field = self.get_manipulator_field_names('')
+        if rel:
+            d = new_data.get(date_field, [None])[0]
+            t = new_data.get(time_field, [None])[0]
+        else:
+            d = new_data.get(date_field, None)
+            t = new_data.get(time_field, None)
+        if d is not None and t is not None:
+            return datetime.datetime.combine(d, t)
+        return self.get_default()
+
+    def flatten_data(self,follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        date_field, time_field = self.get_manipulator_field_names('')
+        return {date_field: (val is not None and val.strftime("%Y-%m-%d") or ''),
+                time_field: (val is not None and val.strftime("%H:%M:%S") or '')}
+
+    def formfield(self):
+        return forms.DateTimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class EmailField(CharField):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = 75
+        CharField.__init__(self, *args, **kwargs)
+
+    def get_internal_type(self):
+        return "CharField"
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.EmailField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidEmail(field_data, all_data)
+
+    def formfield(self):
+        return forms.EmailField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class FileField(Field):
+    def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs):
+        self.upload_to = upload_to
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
+        if not self.blank:
+            if rel:
+                # This validator makes sure FileFields work in a related context.
+                class RequiredFileField(object):
+                    def __init__(self, other_field_names, other_file_field_name):
+                        self.other_field_names = other_field_names
+                        self.other_file_field_name = other_file_field_name
+                        self.always_test = True
+                    def __call__(self, field_data, all_data):
+                        if not all_data.get(self.other_file_field_name, False):
+                            c = validators.RequiredIfOtherFieldsGiven(self.other_field_names, gettext_lazy("This field is required."))
+                            c(field_data, all_data)
+                # First, get the core fields, if any.
+                core_field_names = []
+                for f in opts.fields:
+                    if f.core and f != self:
+                        core_field_names.extend(f.get_manipulator_field_names(name_prefix))
+                # Now, if there are any, add the validator to this FormField.
+                if core_field_names:
+                    field_list[0].validator_list.append(RequiredFileField(core_field_names, field_list[1].field_name))
+            else:
+                v = validators.RequiredIfOtherFieldNotGiven(field_list[1].field_name, gettext_lazy("This field is required."))
+                v.always_test = True
+                field_list[0].validator_list.append(v)
+                field_list[0].is_required = field_list[1].is_required = False
+
+        # If the raw path is passed in, validate it's under the MEDIA_ROOT.
+        def isWithinMediaRoot(field_data, all_data):
+            f = os.path.abspath(os.path.join(settings.MEDIA_ROOT, field_data))
+            if not f.startswith(os.path.abspath(os.path.normpath(settings.MEDIA_ROOT))):
+                raise validators.ValidationError, _("Enter a valid filename.")
+        field_list[1].validator_list.append(isWithinMediaRoot)
+        return field_list
+
+    def contribute_to_class(self, cls, name):
+        super(FileField, self).contribute_to_class(cls, name)
+        setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self))
+        setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self))
+        setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self))
+        setattr(cls, 'save_%s_file' % self.name, lambda instance, filename, raw_contents: instance._save_FIELD_file(self, filename, raw_contents))
+        dispatcher.connect(self.delete_file, signal=signals.post_delete, sender=cls)
+
+    def delete_file(self, instance):
+        if getattr(instance, self.attname):
+            file_name = getattr(instance, 'get_%s_filename' % self.name)()
+            # If the file exists and no other object of this type references it,
+            # delete it from the filesystem.
+            if os.path.exists(file_name) and \
+                not instance.__class__._default_manager.filter(**{'%s__exact' % self.name: getattr(instance, self.attname)}):
+                os.remove(file_name)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.FileUploadField, oldforms.HiddenField]
+
+    def get_manipulator_field_names(self, name_prefix):
+        return [name_prefix + self.name + '_file', name_prefix + self.name]
+
+    def save_file(self, new_data, new_object, original_object, change, rel):
+        upload_field_name = self.get_manipulator_field_names('')[0]
+        if new_data.get(upload_field_name, False):
+            func = getattr(new_object, 'save_%s_file' % self.name)
+            if rel:
+                func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"])
+            else:
+                func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"])
+
+    def get_directory_name(self):
+        return os.path.normpath(datetime.datetime.now().strftime(self.upload_to))
+
+    def get_filename(self, filename):
+        from django.utils.text import get_valid_filename
+        f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
+        return os.path.normpath(f)
+
+class FilePathField(Field):
+    def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
+        self.path, self.match, self.recursive = path, match, recursive
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
+
+class FloatField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
+        self.max_digits, self.decimal_places = max_digits, decimal_places
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
+
+class ImageField(FileField):
+    def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
+        self.width_field, self.height_field = width_field, height_field
+        FileField.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.ImageUploadField, oldforms.HiddenField]
+
+    def contribute_to_class(self, cls, name):
+        super(ImageField, self).contribute_to_class(cls, name)
+        # Add get_BLAH_width and get_BLAH_height methods, but only if the
+        # image field doesn't have width and height cache fields.
+        if not self.width_field:
+            setattr(cls, 'get_%s_width' % self.name, curry(cls._get_FIELD_width, field=self))
+        if not self.height_field:
+            setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self))
+
+    def save_file(self, new_data, new_object, original_object, change, rel):
+        FileField.save_file(self, new_data, new_object, original_object, change, rel)
+        # If the image has height and/or width field(s) and they haven't
+        # changed, set the width and/or height field(s) back to their original
+        # values.
+        if change and (self.width_field or self.height_field):
+            if self.width_field:
+                setattr(new_object, self.width_field, getattr(original_object, self.width_field))
+            if self.height_field:
+                setattr(new_object, self.height_field, getattr(original_object, self.height_field))
+            new_object.save()
+
+class IntegerField(Field):
+    empty_strings_allowed = False
+    def get_manipulator_field_objs(self):
+        return [oldforms.IntegerField]
+
+    def formfield(self):
+        return forms.IntegerField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class IPAddressField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = 15
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.IPAddressField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidIPAddress4(field_data, None)
+
+class NullBooleanField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['null'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.NullBooleanField]
+
+class PhoneNumberField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PhoneNumberField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidPhone(field_data, all_data)
+
+class PositiveIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PositiveIntegerField]
+
+class PositiveSmallIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PositiveSmallIntegerField]
+
+class SlugField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = kwargs.get('maxlength', 50)
+        kwargs.setdefault('validator_list', []).append(validators.isSlug)
+        # Set db_index=True unless it's been set manually.
+        if not kwargs.has_key('db_index'):
+            kwargs['db_index'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.TextField]
+
+class SmallIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.SmallIntegerField]
+
+class TextField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.LargeTextField]
+
+class TimeField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
+        self.auto_now, self.auto_now_add = auto_now, auto_now_add
+        if auto_now or auto_now_add:
+            kwargs['editable'] = False
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def pre_save(self, model_instance, add):
+        if self.auto_now or (self.auto_now_add and add):
+            value = datetime.datetime.now().time()
+            setattr(model_instance, self.attname, value)
+            return value
+        else:
+            return super(TimeField, self).pre_save(model_instance, add)
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            # MySQL will throw a warning if microseconds are given, because it
+            # doesn't support microseconds.
+            if settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'ado_mssql':
+                value = value.replace(microsecond=0)
+            value = str(value)
+        return Field.get_db_prep_save(self, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.TimeField]
+
+    def flatten_data(self,follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        return {self.attname: (val is not None and val.strftime("%H:%M:%S") or '')}
+
+    def formfield(self):
+        return forms.TimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class URLField(Field):
+    def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
+        if verify_exists:
+            kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
+        self.verify_exists = verify_exists
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.URLField]
+
+    def formfield(self):
+        return forms.URLField(required=not self.blank, verify_exists=self.verify_exists, label=capfirst(self.verbose_name))
+
+class USStateField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.USStateField]
+
+class XMLField(TextField):
+    def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs):
+        self.schema_path = schema_path
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_internal_type(self):
+        return "TextField"
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.XMLLargeTextField, schema_path=self.schema_path)]
+
+class OrderingField(IntegerField):
+    empty_strings_allowed=False
+    def __init__(self, with_respect_to, **kwargs):
+        self.wrt = with_respect_to
+        kwargs['null'] = True
+        IntegerField.__init__(self, **kwargs )
+
+    def get_internal_type(self):
+        return "IntegerField"
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        return [oldforms.HiddenField(name_prefix + self.name)]
+from django.db.models import signals
+from django.dispatch import dispatcher
+from django.conf import settings
+from django.core import validators
+from django import oldforms
+from django import newforms as forms
+from django.core.exceptions import ObjectDoesNotExist
+from django.utils.functional import curry
+from django.utils.itercompat import tee
+from django.utils.text import capfirst
+from django.utils.translation import gettext, gettext_lazy
+import datetime, os, time
+
+class NOT_PROVIDED:
+    pass
+
+# Values for filter_interface.
+HORIZONTAL, VERTICAL = 1, 2
+
+# The values to use for "blank" in SelectFields. Will be appended to the start of most "choices" lists.
+BLANK_CHOICE_DASH = [("", "---------")]
+BLANK_CHOICE_NONE = [("", "None")]
+
+# prepares a value for use in a LIKE query
+prep_for_like_query = lambda x: str(x).replace("\\", "\\\\").replace("%", "\%").replace("_", "\_")
+
+# returns the <ul> class for a given radio_admin value
+get_ul_class = lambda x: 'radiolist%s' % ((x == HORIZONTAL) and ' inline' or '')
+
+class FieldDoesNotExist(Exception):
+    pass
+
+def manipulator_validator_unique(f, opts, self, field_data, all_data):
+    "Validates that the value is unique for this field."
+    lookup_type = f.get_validator_unique_lookup_type()
+    try:
+        old_obj = self.manager.get(**{lookup_type: field_data})
+    except ObjectDoesNotExist:
+        return
+    if getattr(self, 'original_object', None) and self.original_object._get_pk_val() == old_obj._get_pk_val():
+        return
+    raise validators.ValidationError, gettext("%(optname)s with this %(fieldname)s already exists.") % {'optname': capfirst(opts.verbose_name), 'fieldname': f.verbose_name}
+
+# A guide to Field parameters:
+#
+#   * name:      The name of the field specifed in the model.
+#   * attname:   The attribute to use on the model object. This is the same as
+#                "name", except in the case of ForeignKeys, where "_id" is
+#                appended.
+#   * db_column: The db_column specified in the model (or None).
+#   * column:    The database column for this field. This is the same as
+#                "attname", except if db_column is specified.
+#
+# Code that introspects values, or does other dynamic things, should use
+# attname. For example, this gets the primary key value of object "obj":
+#
+#     getattr(obj, opts.pk.attname)
+
+class Field(object):
+
+    # Designates whether empty strings fundamentally are allowed at the
+    # database level.
+    empty_strings_allowed = True
+
+    # Tracks each time a Field instance is created. Used to retain order.
+    creation_counter = 0
+
+    def __init__(self, verbose_name=None, name=None, primary_key=False,
+        maxlength=None, unique=False, blank=False, null=False, db_index=False,
+        core=False, rel=None, default=NOT_PROVIDED, editable=True,
+        prepopulate_from=None, unique_for_date=None, unique_for_month=None,
+        unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
+        help_text='', db_column=None):
+        self.name = name
+        self.verbose_name = verbose_name
+        self.primary_key = primary_key
+        self.maxlength, self.unique = maxlength, unique
+        self.blank, self.null = blank, null
+        self.core, self.rel, self.default = core, rel, default
+        self.editable = editable
+        self.validator_list = validator_list or []
+        self.prepopulate_from = prepopulate_from
+        self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
+        self.unique_for_year = unique_for_year
+        self._choices = choices or []
+        self.radio_admin = radio_admin
+        self.help_text = help_text
+        self.db_column = db_column
+
+        # Set db_index to True if the field has a relationship and doesn't explicitly set db_index.
+        self.db_index = db_index
+
+        # Increase the creation counter, and save our local copy.
+        self.creation_counter = Field.creation_counter
+        Field.creation_counter += 1
+
+    def __cmp__(self, other):
+        # This is needed because bisect does not take a comparison function.
+        return cmp(self.creation_counter, other.creation_counter)
+
+    def to_python(self, value):
+        """
+        Converts the input value into the expected Python data type, raising
+        validators.ValidationError if the data can't be converted. Returns the
+        converted value. Subclasses should override this.
+        """
+        return value
+
+    def validate_full(self, field_data, all_data):
+        """
+        Returns a list of errors for this field. This is the main interface,
+        as it encapsulates some basic validation logic used by all fields.
+        Subclasses should implement validate(), not validate_full().
+        """
+        if not self.blank and not field_data:
+            return [gettext_lazy('This field is required.')]
+        try:
+            self.validate(field_data, all_data)
+        except validators.ValidationError, e:
+            return e.messages
+        return []
+
+    def validate(self, field_data, all_data):
+        """
+        Raises validators.ValidationError if field_data has any errors.
+        Subclasses should override this to specify field-specific validation
+        logic. This method should assume field_data has already been converted
+        into the appropriate data type by Field.to_python().
+        """
+        pass
+
+    def set_attributes_from_name(self, name):
+        self.name = name
+        self.attname, self.column = self.get_attname_column()
+        self.verbose_name = self.verbose_name or (name and name.replace('_', ' '))
+
+    def contribute_to_class(self, cls, name):
+        self.set_attributes_from_name(name)
+        cls._meta.add_field(self)
+        if self.choices:
+            setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self))
+
+    def get_attname(self):
+        return self.name
+
+    def get_attname_column(self):
+        attname = self.get_attname()
+        column = self.db_column or attname
+        return attname, column
+
+    def get_cache_name(self):
+        return '_%s_cache' % self.name
+
+    def get_internal_type(self):
+        return self.__class__.__name__
+
+    def pre_save(self, model_instance, add):
+        "Returns field's value just before saving."
+        return getattr(model_instance, self.attname)
+
+    def get_db_prep_save(self, value):
+        "Returns field's value prepared for saving into a database."
+        return value
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        "Returns field's value prepared for database lookup."
+        if lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte', 'year', 'month', 'day', 'search'):
+            return [value]
+        elif lookup_type in ('range', 'in'):
+            return value
+        elif lookup_type in ('contains', 'icontains'):
+            return ["%%%s%%" % prep_for_like_query(value)]
+        elif lookup_type == 'iexact':
+            return [prep_for_like_query(value)]
+        elif lookup_type in ('startswith', 'istartswith'):
+            return ["%s%%" % prep_for_like_query(value)]
+        elif lookup_type in ('endswith', 'iendswith'):
+            return ["%%%s" % prep_for_like_query(value)]
+        elif lookup_type == 'isnull':
+            return []
+        raise TypeError, "Field has invalid lookup: %s" % lookup_type
+
+    def has_default(self):
+        "Returns a boolean of whether this field has a default value."
+        return self.default is not NOT_PROVIDED
+
+    def get_default(self):
+        "Returns the default value for this field."
+        if self.default is not NOT_PROVIDED:
+            if callable(self.default):
+                return self.default()
+            return self.default
+        if not self.empty_strings_allowed or self.null:
+            return None
+        return ""
+
+    def get_manipulator_field_names(self, name_prefix):
+        """
+        Returns a list of field names that this object adds to the manipulator.
+        """
+        return [name_prefix + self.name]
+
+    def prepare_field_objs_and_params(self, manipulator, name_prefix):
+        params = {'validator_list': self.validator_list[:]}
+        if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
+            params['maxlength'] = self.maxlength
+
+        if self.choices:
+            if self.radio_admin:
+                field_objs = [oldforms.RadioSelectField]
+                params['ul_class'] = get_ul_class(self.radio_admin)
+            else:
+                field_objs = [oldforms.SelectField]
+
+            params['choices'] = self.get_choices_default()
+        else:
+            field_objs = self.get_manipulator_field_objs()
+        return (field_objs, params)
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        """
+        Returns a list of oldforms.FormField instances for this field. It
+        calculates the choices at runtime, not at compile time.
+
+        name_prefix is a prefix to prepend to the "field_name" argument.
+        rel is a boolean specifying whether this field is in a related context.
+        """
+        field_objs, params = self.prepare_field_objs_and_params(manipulator, name_prefix)
+
+        # Add the "unique" validator(s).
+        for field_name_list in opts.unique_together:
+            if field_name_list[0] == self.name:
+                params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list)))
+
+        # Add the "unique for..." validator(s).
+        if self.unique_for_date:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date)))
+        if self.unique_for_month:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
+        if self.unique_for_year:
+            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
+        if self.unique or (self.primary_key and not rel):
+            params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
+
+        # Only add is_required=True if the field cannot be blank. Primary keys
+        # are a special case, and fields in a related context should set this
+        # as False, because they'll be caught by a separate validator --
+        # RequiredIfOtherFieldGiven.
+        params['is_required'] = not self.blank and not self.primary_key and not rel
+
+        # BooleanFields (CheckboxFields) are a special case. They don't take
+        # is_required.
+        if isinstance(self, BooleanField):
+            del params['is_required']
+
+        # If this field is in a related context, check whether any other fields
+        # in the related object have core=True. If so, add a validator --
+        # RequiredIfOtherFieldsGiven -- to this FormField.
+        if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField):
+            # First, get the core fields, if any.
+            core_field_names = []
+            for f in opts.fields:
+                if f.core and f != self:
+                    core_field_names.extend(f.get_manipulator_field_names(name_prefix))
+            # Now, if there are any, add the validator to this FormField.
+            if core_field_names:
+                params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, gettext_lazy("This field is required.")))
+
+        # Finally, add the field_names.
+        field_names = self.get_manipulator_field_names(name_prefix)
+        return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
+
+    def get_validator_unique_lookup_type(self):
+        return '%s__exact' % self.name
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        """
+        Given the full new_data dictionary (from the manipulator), returns this
+        field's data.
+        """
+        if rel:
+            return new_data.get(self.name, [self.get_default()])[0]
+        val = new_data.get(self.name, self.get_default())
+        if not self.empty_strings_allowed and val == '' and self.null:
+            val = None
+        return val
+
+    def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
+        "Returns a list of tuples used as SelectField choices for this field."
+        first_choice = include_blank and blank_choice or []
+        if self.choices:
+            return first_choice + list(self.choices)
+        rel_model = self.rel.to
+        if hasattr(self.rel, 'get_related_field'):
+            lst = [(getattr(x, self.rel.get_related_field().attname), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
+        else:
+            lst = [(x._get_pk_val(), str(x)) for x in rel_model._default_manager.complex_filter(self.rel.limit_choices_to)]
+        return first_choice + lst
+
+    def get_choices_default(self):
+        if self.radio_admin:
+            return self.get_choices(include_blank=self.blank, blank_choice=BLANK_CHOICE_NONE)
+        else:
+            return self.get_choices()
+
+    def _get_val_from_obj(self, obj):
+        if obj:
+            return getattr(obj, self.attname)
+        else:
+            return self.get_default()
+
+    def flatten_data(self, follow, obj=None):
+        """
+        Returns a dictionary mapping the field's manipulator field names to its
+        "flattened" string values for the admin view. obj is the instance to
+        extract the values from.
+        """
+        return {self.attname: self._get_val_from_obj(obj)}
+
+    def get_follow(self, override=None):
+        if override != None:
+            return override
+        else:
+            return self.editable
+
+    def bind(self, fieldmapping, original, bound_field_class):
+        return bound_field_class(self, fieldmapping, original)
+
+    def _get_choices(self):
+        if hasattr(self._choices, 'next'):
+            choices, self._choices = tee(self._choices)
+            return choices
+        else:
+            return self._choices
+    choices = property(_get_choices)
+
+    def formfield(self):
+        "Returns a django.newforms.Field instance for this database Field."
+        # TODO: This is just a temporary default during development.
+        return forms.CharField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class AutoField(Field):
+    empty_strings_allowed = False
+    def __init__(self, *args, **kwargs):
+        assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__
+        kwargs['blank'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def to_python(self, value):
+        if value is None:
+            return value
+        try:
+            return int(value)
+        except (TypeError, ValueError):
+            raise validators.ValidationError, gettext("This value must be an integer.")
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        if not rel:
+            return [] # Don't add a FormField unless it's in a related context.
+        return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.HiddenField]
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        # Never going to be called
+        # Not in main change pages
+        # ignored in related context
+        if not rel:
+            return None
+        return Field.get_manipulator_new_data(self, new_data, rel)
+
+    def contribute_to_class(self, cls, name):
+        assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
+        super(AutoField, self).contribute_to_class(cls, name)
+        cls._meta.has_auto_field = True
+
+    def formfield(self):
+        return None
+
+class BooleanField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['blank'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def to_python(self, value):
+        if value in (True, False): return value
+        if value in ('t', 'True', '1'): return True
+        if value in ('f', 'False', '0'): return False
+        raise validators.ValidationError, gettext("This value must be either True or False.")
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.CheckboxField]
+
+    def formfield(self):
+        return forms.BooleanField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class CharField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.TextField]
+
+    def to_python(self, value):
+        if isinstance(value, basestring):
+            return value
+        if value is None:
+            if self.null:
+                return value
+            else:
+                raise validators.ValidationError, gettext_lazy("This field cannot be null.")
+        return str(value)
+
+    def formfield(self):
+        return forms.CharField(max_length=self.maxlength, required=not self.blank, label=capfirst(self.verbose_name))
+
+# TODO: Maybe move this into contrib, because it's specialized.
+class CommaSeparatedIntegerField(CharField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.CommaSeparatedIntegerField]
+
+class DateField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
+        self.auto_now, self.auto_now_add = auto_now, auto_now_add
+        #HACKs : auto_now_add/auto_now should be done as a default or a pre_save.
+        if auto_now or auto_now_add:
+            kwargs['editable'] = False
+            kwargs['blank'] = True
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def to_python(self, value):
+        if isinstance(value, datetime.datetime):
+            return value.date()
+        if isinstance(value, datetime.date):
+            return value
+        validators.isValidANSIDate(value, None)
+        try:
+            return datetime.date(*time.strptime(value, '%Y-%m-%d')[:3])
+        except ValueError:
+            raise validators.ValidationError, gettext('Enter a valid date in YYYY-MM-DD format.')
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        elif lookup_type in ('exact', 'gt', 'gte', 'lt', 'lte') and hasattr(value, 'strftime'):
+            value = value.strftime('%Y-%m-%d')
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def pre_save(self, model_instance, add):
+        if self.auto_now or (self.auto_now_add and add):
+            value = datetime.datetime.now()
+            setattr(model_instance, self.attname, value)
+            return value
+        else:
+            return super(DateField, self).pre_save(model_instance, add)
+
+    def contribute_to_class(self, cls, name):
+        super(DateField,self).contribute_to_class(cls, name)
+        if not self.null:
+            setattr(cls, 'get_next_by_%s' % self.name,
+                curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=True))
+            setattr(cls, 'get_previous_by_%s' % self.name,
+                curry(cls._get_next_or_previous_by_FIELD, field=self, is_next=False))
+
+    # Needed because of horrible auto_now[_add] behaviour wrt. editable
+    def get_follow(self, override=None):
+        if override != None:
+            return override
+        else:
+            return self.editable or self.auto_now or self.auto_now_add
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            value = value.strftime('%Y-%m-%d')
+        return Field.get_db_prep_save(self, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.DateField]
+
+    def flatten_data(self, follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        return {self.attname: (val is not None and val.strftime("%Y-%m-%d") or '')}
+
+    def formfield(self):
+        return forms.DateField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class DateTimeField(DateField):
+    def to_python(self, value):
+        if isinstance(value, datetime.datetime):
+            return value
+        if isinstance(value, datetime.date):
+            return datetime.datetime(value.year, value.month, value.day)
+        try: # Seconds are optional, so try converting seconds first.
+            return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M:%S')[:6])
+        except ValueError:
+            try: # Try without seconds.
+                return datetime.datetime(*time.strptime(value, '%Y-%m-%d %H:%M')[:5])
+            except ValueError: # Try without hour/minutes/seconds.
+                try:
+                    return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3])
+                except ValueError:
+                    raise validators.ValidationError, gettext('Enter a valid date/time in YYYY-MM-DD HH:MM format.')
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            # MySQL will throw a warning if microseconds are given, because it
+            # doesn't support microseconds.
+            if (settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'ado_mssql') and hasattr(value, 'microsecond'):
+                value = value.replace(microsecond=0)
+            value = str(value)
+        return Field.get_db_prep_save(self, value)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+	# MSSQL doesn't like microseconds. 
+        if settings.DATABASE_ENGINE == 'ado_mssql' and hasattr(value, 'microsecond'):
+	    value = value.replace(microsecond=0)	
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.DateField, oldforms.TimeField]
+
+    def get_manipulator_field_names(self, name_prefix):
+        return [name_prefix + self.name + '_date', name_prefix + self.name + '_time']
+
+    def get_manipulator_new_data(self, new_data, rel=False):
+        date_field, time_field = self.get_manipulator_field_names('')
+        if rel:
+            d = new_data.get(date_field, [None])[0]
+            t = new_data.get(time_field, [None])[0]
+        else:
+            d = new_data.get(date_field, None)
+            t = new_data.get(time_field, None)
+        if d is not None and t is not None:
+            return datetime.datetime.combine(d, t)
+        return self.get_default()
+
+    def flatten_data(self,follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        date_field, time_field = self.get_manipulator_field_names('')
+        return {date_field: (val is not None and val.strftime("%Y-%m-%d") or ''),
+                time_field: (val is not None and val.strftime("%H:%M:%S") or '')}
+
+    def formfield(self):
+        return forms.DateTimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class EmailField(CharField):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = 75
+        CharField.__init__(self, *args, **kwargs)
+
+    def get_internal_type(self):
+        return "CharField"
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.EmailField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidEmail(field_data, all_data)
+
+    def formfield(self):
+        return forms.EmailField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class FileField(Field):
+    def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs):
+        self.upload_to = upload_to
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        field_list = Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
+        if not self.blank:
+            if rel:
+                # This validator makes sure FileFields work in a related context.
+                class RequiredFileField(object):
+                    def __init__(self, other_field_names, other_file_field_name):
+                        self.other_field_names = other_field_names
+                        self.other_file_field_name = other_file_field_name
+                        self.always_test = True
+                    def __call__(self, field_data, all_data):
+                        if not all_data.get(self.other_file_field_name, False):
+                            c = validators.RequiredIfOtherFieldsGiven(self.other_field_names, gettext_lazy("This field is required."))
+                            c(field_data, all_data)
+                # First, get the core fields, if any.
+                core_field_names = []
+                for f in opts.fields:
+                    if f.core and f != self:
+                        core_field_names.extend(f.get_manipulator_field_names(name_prefix))
+                # Now, if there are any, add the validator to this FormField.
+                if core_field_names:
+                    field_list[0].validator_list.append(RequiredFileField(core_field_names, field_list[1].field_name))
+            else:
+                v = validators.RequiredIfOtherFieldNotGiven(field_list[1].field_name, gettext_lazy("This field is required."))
+                v.always_test = True
+                field_list[0].validator_list.append(v)
+                field_list[0].is_required = field_list[1].is_required = False
+
+        # If the raw path is passed in, validate it's under the MEDIA_ROOT.
+        def isWithinMediaRoot(field_data, all_data):
+            f = os.path.abspath(os.path.join(settings.MEDIA_ROOT, field_data))
+            if not f.startswith(os.path.abspath(os.path.normpath(settings.MEDIA_ROOT))):
+                raise validators.ValidationError, _("Enter a valid filename.")
+        field_list[1].validator_list.append(isWithinMediaRoot)
+        return field_list
+
+    def contribute_to_class(self, cls, name):
+        super(FileField, self).contribute_to_class(cls, name)
+        setattr(cls, 'get_%s_filename' % self.name, curry(cls._get_FIELD_filename, field=self))
+        setattr(cls, 'get_%s_url' % self.name, curry(cls._get_FIELD_url, field=self))
+        setattr(cls, 'get_%s_size' % self.name, curry(cls._get_FIELD_size, field=self))
+        setattr(cls, 'save_%s_file' % self.name, lambda instance, filename, raw_contents: instance._save_FIELD_file(self, filename, raw_contents))
+        dispatcher.connect(self.delete_file, signal=signals.post_delete, sender=cls)
+
+    def delete_file(self, instance):
+        if getattr(instance, self.attname):
+            file_name = getattr(instance, 'get_%s_filename' % self.name)()
+            # If the file exists and no other object of this type references it,
+            # delete it from the filesystem.
+            if os.path.exists(file_name) and \
+                not instance.__class__._default_manager.filter(**{'%s__exact' % self.name: getattr(instance, self.attname)}):
+                os.remove(file_name)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.FileUploadField, oldforms.HiddenField]
+
+    def get_manipulator_field_names(self, name_prefix):
+        return [name_prefix + self.name + '_file', name_prefix + self.name]
+
+    def save_file(self, new_data, new_object, original_object, change, rel):
+        upload_field_name = self.get_manipulator_field_names('')[0]
+        if new_data.get(upload_field_name, False):
+            func = getattr(new_object, 'save_%s_file' % self.name)
+            if rel:
+                func(new_data[upload_field_name][0]["filename"], new_data[upload_field_name][0]["content"])
+            else:
+                func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"])
+
+    def get_directory_name(self):
+        return os.path.normpath(datetime.datetime.now().strftime(self.upload_to))
+
+    def get_filename(self, filename):
+        from django.utils.text import get_valid_filename
+        f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
+        return os.path.normpath(f)
+
+class FilePathField(Field):
+    def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
+        self.path, self.match, self.recursive = path, match, recursive
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
+
+class FloatField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
+        self.max_digits, self.decimal_places = max_digits, decimal_places
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
+
+class ImageField(FileField):
+    def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
+        self.width_field, self.height_field = width_field, height_field
+        FileField.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.ImageUploadField, oldforms.HiddenField]
+
+    def contribute_to_class(self, cls, name):
+        super(ImageField, self).contribute_to_class(cls, name)
+        # Add get_BLAH_width and get_BLAH_height methods, but only if the
+        # image field doesn't have width and height cache fields.
+        if not self.width_field:
+            setattr(cls, 'get_%s_width' % self.name, curry(cls._get_FIELD_width, field=self))
+        if not self.height_field:
+            setattr(cls, 'get_%s_height' % self.name, curry(cls._get_FIELD_height, field=self))
+
+    def save_file(self, new_data, new_object, original_object, change, rel):
+        FileField.save_file(self, new_data, new_object, original_object, change, rel)
+        # If the image has height and/or width field(s) and they haven't
+        # changed, set the width and/or height field(s) back to their original
+        # values.
+        if change and (self.width_field or self.height_field):
+            if self.width_field:
+                setattr(new_object, self.width_field, getattr(original_object, self.width_field))
+            if self.height_field:
+                setattr(new_object, self.height_field, getattr(original_object, self.height_field))
+            new_object.save()
+
+class IntegerField(Field):
+    empty_strings_allowed = False
+    def get_manipulator_field_objs(self):
+        return [oldforms.IntegerField]
+
+    def formfield(self):
+        return forms.IntegerField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class IPAddressField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = 15
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.IPAddressField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidIPAddress4(field_data, None)
+
+class NullBooleanField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['null'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.NullBooleanField]
+
+class PhoneNumberField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PhoneNumberField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidPhone(field_data, all_data)
+
+class PositiveIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PositiveIntegerField]
+
+class PositiveSmallIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.PositiveSmallIntegerField]
+
+class SlugField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = kwargs.get('maxlength', 50)
+        kwargs.setdefault('validator_list', []).append(validators.isSlug)
+        # Set db_index=True unless it's been set manually.
+        if not kwargs.has_key('db_index'):
+            kwargs['db_index'] = True
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.TextField]
+
+class SmallIntegerField(IntegerField):
+    def get_manipulator_field_objs(self):
+        return [oldforms.SmallIntegerField]
+
+class TextField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.LargeTextField]
+
+class TimeField(Field):
+    empty_strings_allowed = False
+    def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
+        self.auto_now, self.auto_now_add = auto_now, auto_now_add
+        if auto_now or auto_now_add:
+            kwargs['editable'] = False
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_db_prep_lookup(self, lookup_type, value):
+        if lookup_type == 'range':
+            value = [str(v) for v in value]
+        else:
+            value = str(value)
+        return Field.get_db_prep_lookup(self, lookup_type, value)
+
+    def pre_save(self, model_instance, add):
+        if self.auto_now or (self.auto_now_add and add):
+            value = datetime.datetime.now().time()
+            setattr(model_instance, self.attname, value)
+            return value
+        else:
+            return super(TimeField, self).pre_save(model_instance, add)
+
+    def get_db_prep_save(self, value):
+        # Casts dates into string format for entry into database.
+        if value is not None:
+            # MySQL will throw a warning if microseconds are given, because it
+            # doesn't support microseconds.
+            if settings.DATABASE_ENGINE == 'mysql' or settings.DATABASE_ENGINE == 'ado_mssql':
+                value = value.replace(microsecond=0)
+            value = str(value)
+        return Field.get_db_prep_save(self, value)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.TimeField]
+
+    def flatten_data(self,follow, obj = None):
+        val = self._get_val_from_obj(obj)
+        return {self.attname: (val is not None and val.strftime("%H:%M:%S") or '')}
+
+    def formfield(self):
+        return forms.TimeField(required=not self.blank, label=capfirst(self.verbose_name))
+
+class URLField(Field):
+    def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
+        if verify_exists:
+            kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
+        self.verify_exists = verify_exists
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [oldforms.URLField]
+
+    def formfield(self):
+        return forms.URLField(required=not self.blank, verify_exists=self.verify_exists, label=capfirst(self.verbose_name))
+
+class USStateField(Field):
+    def get_manipulator_field_objs(self):
+        return [oldforms.USStateField]
+
+class XMLField(TextField):
+    def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs):
+        self.schema_path = schema_path
+        Field.__init__(self, verbose_name, name, **kwargs)
+
+    def get_internal_type(self):
+        return "TextField"
+
+    def get_manipulator_field_objs(self):
+        return [curry(oldforms.XMLLargeTextField, schema_path=self.schema_path)]
+
+class OrderingField(IntegerField):
+    empty_strings_allowed=False
+    def __init__(self, with_respect_to, **kwargs):
+        self.wrt = with_respect_to
+        kwargs['null'] = True
+        IntegerField.__init__(self, **kwargs )
+
+    def get_internal_type(self):
+        return "IntegerField"
+
+    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
+        return [oldforms.HiddenField(name_prefix + self.name)]
Index: newforms/__init__.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\__init__.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: newforms/fields.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\fields.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: newforms/forms.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\forms.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: newforms/models.py
===================================================================
--- newforms/models.py	(revision 0)
+++ newforms/models.py	(revision 0)
@@ -0,0 +1,33 @@
+"""
+Helper functions for creating Form classes from Django models
+and database field objects.
+"""
+
+from forms import BaseForm, DeclarativeFieldsMetaclass, SortedDictFromList
+
+__all__ = ('form_for_model', 'form_for_fields')
+
+def create(self, save=True):
+    "Creates and returns model instance according to self.clean_data."
+    if self.errors:
+        raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name)
+    obj = self._model(**self.clean_data)
+    if save:
+        obj.save()
+    return obj
+
+def form_for_model(model):
+    "Returns a Form class for the given Django model class."
+    opts = model._meta
+    field_list = []
+    for f in opts.fields + opts.many_to_many:
+        formfield = f.formfield()
+        if formfield:
+            field_list.append((f.name, formfield))
+    fields = SortedDictFromList(field_list)
+    return type(opts.object_name + 'Form', (BaseForm,), {'fields': fields, '_model': model, 'create': create})
+
+def form_for_fields(field_list):
+    "Returns a Form class for the given list of Django database field instances."
+    fields = SortedDictFromList([(f.name, f.formfield()) for f in field_list])
+    return type('FormForFields', (BaseForm,), {'fields': fields})
Index: newforms/models.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\models.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: newforms/util.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\util.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Index: newforms/widgets.pyc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: newforms\widgets.pyc
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

