Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Removed oldforms, validators, and related code:

 * Removed `Manipulator`, `AutomaticManipulator`, and related classes.
 * Removed oldforms specific bits from model fields:
   * Removed `validator_list` and `core` arguments from constructors.
   * Removed the methods:
     * `get_manipulator_field_names`
     * `get_manipulator_field_objs`
     * `get_manipulator_fields`
     * `get_manipulator_new_data`
     * `prepare_field_objs_and_params`
     * `get_follow`
   * Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
 * Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
 * Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
 * Serialization framework
   * `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
   * Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
 * Removed `django.core.validators`:
   * Moved `ValidationError` exception to `django.core.exceptions`.
   * For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
 * Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
 * Removed an oldforms-style model creation hack (refs #2160).

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c2ba59fc1da5287d6286e2c2aca4083d5bafe056 1 parent a157576
Gary Wilson Jr. authored August 27, 2008

Showing 35 changed files with 158 additions and 3,468 deletions. Show diff stats Hide diff stats

  1. 6  django/contrib/admin/util.py
  2. 19  django/contrib/auth/management/commands/createsuperuser.py
  3. 1  django/contrib/auth/models.py
  4. 3  django/contrib/comments/forms.py
  5. 2  django/contrib/comments/models.py
  6. 21  django/contrib/contenttypes/generic.py
  7. 1  django/contrib/flatpages/models.py
  8. 1  django/contrib/localflavor/jp/forms.py
  9. 3  django/core/exceptions.py
  10. 7  django/core/serializers/base.py
  11. 598  django/core/validators.py
  12. 3  django/db/models/__init__.py
  13. 8  django/db/models/base.py
  14. 313  django/db/models/fields/__init__.py
  15. 54  django/db/models/fields/files.py
  16. 98  django/db/models/fields/related.py
  17. 333  django/db/models/manipulators.py
  18. 47  django/db/models/options.py
  19. 98  django/db/models/related.py
  20. 13  django/forms/fields.py
  21. 1,056  django/oldforms/__init__.py
  22. 37  docs/howto/custom-model-fields.txt
  23. 4  docs/intro/whatsnext.txt
  24. 692  docs/obsolete/forms.txt
  25. 48  docs/obsolete/newforms-migration.txt
  26. 5  docs/ref/forms/fields.txt
  27. 29  docs/ref/models/fields.txt
  28. 3  docs/topics/forms/modelforms.txt
  29. 3  docs/topics/testing.txt
  30. 3  tests/modeltests/field_subclassing/models.py
  31. 8  tests/modeltests/invalid_models/models.py
  32. 0  tests/modeltests/manipulators/__init__.py
  33. 105  tests/modeltests/manipulators/models.py
  34. 2  tests/modeltests/mutually_referential/models.py
  35. 2  tests/regressiontests/model_fields/tests.py
6  django/contrib/admin/util.py
@@ -85,7 +85,7 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
85 85
                         perms_needed.add(related.opts.verbose_name)
86 86
                         # We don't care about populating deleted_objects now.
87 87
                         continue
88  
-                if related.field.rel.edit_inline or not has_admin:
  88
+                if not has_admin:
89 89
                     # Don't display link to edit, because it either has no
90 90
                     # admin or is edited inline.
91 91
                     nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
@@ -101,7 +101,7 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
101 101
             has_related_objs = False
102 102
             for sub_obj in getattr(obj, rel_opts_name).all():
103 103
                 has_related_objs = True
104  
-                if related.field.rel.edit_inline or not has_admin:
  104
+                if not has_admin:
105 105
                     # Don't display link to edit, because it either has no
106 106
                     # admin or is edited inline.
107 107
                     nh(deleted_objects, current_depth, [u'%s: %s' % (force_unicode(capfirst(related.opts.verbose_name)), sub_obj), []])
@@ -132,7 +132,7 @@ def get_deleted_objects(deleted_objects, perms_needed, user, obj, opts, current_
132 132
 
133 133
         if has_related_objs:
134 134
             for sub_obj in rel_objs.all():
135  
-                if related.field.rel.edit_inline or not has_admin:
  135
+                if not has_admin:
136 136
                     # Don't display link to edit, because it either has no
137 137
                     # admin or is edited inline.
138 138
                     nh(deleted_objects, current_depth, [_('One or more %(fieldname)s in %(name)s: %(obj)s') % \
19  django/contrib/auth/management/commands/createsuperuser.py
@@ -8,10 +8,19 @@
8 8
 import sys
9 9
 from optparse import make_option
10 10
 from django.contrib.auth.models import User
11  
-from django.core import validators
  11
+from django.core import exceptions
12 12
 from django.core.management.base import BaseCommand, CommandError
  13
+from django.utils.translation import ugettext as _
13 14
 
14 15
 RE_VALID_USERNAME = re.compile('\w+$')
  16
+EMAIL_RE = re.compile(
  17
+    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
  18
+    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"' # quoted-string
  19
+    r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
  20
+
  21
+def is_valid_email(value):
  22
+    if not EMAIL_RE.search(value):
  23
+        raise exceptions.ValidationError(_('Enter a valid e-mail address.'))
15 24
 
16 25
 class Command(BaseCommand):
17 26
     option_list = BaseCommand.option_list + (
@@ -39,8 +48,8 @@ def handle(self, *args, **options):
39 48
             if not RE_VALID_USERNAME.match(username):
40 49
                 raise CommandError("Invalid username. Use only letters, digits, and underscores")
41 50
             try:
42  
-                validators.isValidEmail(email, None)
43  
-            except validators.ValidationError:
  51
+                is_valid_email(email)
  52
+            except exceptions.ValidationError:
44 53
                 raise CommandError("Invalid email address.")
45 54
 
46 55
         password = ''
@@ -94,8 +103,8 @@ def handle(self, *args, **options):
94 103
                     if not email:
95 104
                         email = raw_input('E-mail address: ')
96 105
                     try:
97  
-                        validators.isValidEmail(email, None)
98  
-                    except validators.ValidationError:
  106
+                        is_valid_email(email)
  107
+                    except exceptions.ValidationError:
99 108
                         sys.stderr.write("Error: That e-mail address is invalid.\n")
100 109
                         email = None
101 110
                     else:
1  django/contrib/auth/models.py
... ...
@@ -1,5 +1,4 @@
1 1
 from django.contrib import auth
2  
-from django.core import validators
3 2
 from django.core.exceptions import ImproperlyConfigured
4 3
 from django.db import models
5 4
 from django.db.models.manager import EmptyManager
3  django/contrib/comments/forms.py
@@ -117,9 +117,6 @@ def clean_comment(self):
117 117
         """
118 118
         comment = self.cleaned_data["comment"]
119 119
         if settings.COMMENTS_ALLOW_PROFANITIES == False:
120  
-            # Logic adapted from django.core.validators; it's not clear if they
121  
-            # should be used in newforms or will be deprecated along with the
122  
-            # rest of oldforms
123 120
             bad_words = [w for w in settings.PROFANITIES_LIST if w in comment.lower()]
124 121
             if bad_words:
125 122
                 plural = len(bad_words) > 1
2  django/contrib/comments/models.py
@@ -5,7 +5,7 @@
5 5
 from django.contrib.contenttypes.models import ContentType
6 6
 from django.contrib.sites.models import Site
7 7
 from django.db import models
8  
-from django.core import urlresolvers, validators
  8
+from django.core import urlresolvers
9 9
 from django.utils.translation import ugettext_lazy as _
10 10
 from django.conf import settings
11 11
 
21  django/contrib/contenttypes/generic.py
@@ -2,18 +2,16 @@
2 2
 Classes allowing "generic" relations through ContentType and object-id fields.
3 3
 """
4 4
 
5  
-from django import oldforms
6 5
 from django.core.exceptions import ObjectDoesNotExist
7 6
 from django.db import connection
8 7
 from django.db.models import signals
9 8
 from django.db import models
10 9
 from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
11 10
 from django.db.models.loading import get_model
12  
-from django.utils.functional import curry
13  
-
14 11
 from django.forms import ModelForm
15 12
 from django.forms.models import BaseModelFormSet, modelformset_factory, save_instance
16 13
 from django.contrib.admin.options import InlineModelAdmin, flatten_fieldsets
  14
+from django.utils.encoding import smart_unicode
17 15
 
18 16
 class GenericForeignKey(object):
19 17
     """
@@ -120,19 +118,12 @@ def __init__(self, to, **kwargs):
120 118
         kwargs['serialize'] = False
121 119
         Field.__init__(self, **kwargs)
122 120
 
123  
-    def get_manipulator_field_objs(self):
124  
-        choices = self.get_choices_default()
125  
-        return [curry(oldforms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
126  
-
127 121
     def get_choices_default(self):
128 122
         return Field.get_choices(self, include_blank=False)
129 123
 
130  
-    def flatten_data(self, follow, obj = None):
131  
-        new_data = {}
132  
-        if obj:
133  
-            instance_ids = [instance._get_pk_val() for instance in getattr(obj, self.name).all()]
134  
-            new_data[self.name] = instance_ids
135  
-        return new_data
  124
+    def value_to_string(self, obj):
  125
+        qs = getattr(obj, self.name).all()
  126
+        return smart_unicode([instance._get_pk_val() for instance in qs])
136 127
 
137 128
     def m2m_db_table(self):
138 129
         return self.rel.to._meta.db_table
@@ -290,7 +281,6 @@ def __init__(self, to, related_name=None, limit_choices_to=None, symmetrical=Tru
290 281
         self.to = to
291 282
         self.related_name = related_name
292 283
         self.limit_choices_to = limit_choices_to or {}
293  
-        self.edit_inline = False
294 284
         self.symmetrical = symmetrical
295 285
         self.multiple = True
296 286
 
@@ -300,7 +290,7 @@ class BaseGenericInlineFormSet(BaseModelFormSet):
300 290
     """
301 291
     ct_field_name = "content_type"
302 292
     ct_fk_field_name = "object_id"
303  
-    
  293
+
304 294
     def __init__(self, data=None, files=None, instance=None, save_as_new=None):
305 295
         opts = self.model._meta
306 296
         self.instance = instance
@@ -395,4 +385,3 @@ class GenericStackedInline(GenericInlineModelAdmin):
395 385
 
396 386
 class GenericTabularInline(GenericInlineModelAdmin):
397 387
     template = 'admin/edit_inline/tabular.html'
398  
-
1  django/contrib/flatpages/models.py
... ...
@@ -1,4 +1,3 @@
1  
-from django.core import validators
2 1
 from django.db import models
3 2
 from django.contrib.sites.models import Site
4 3
 from django.utils.translation import ugettext_lazy as _
1  django/contrib/localflavor/jp/forms.py
@@ -2,7 +2,6 @@
2 2
 JP-specific Form helpers
3 3
 """
4 4
 
5  
-from django.core import validators
6 5
 from django.forms import ValidationError
7 6
 from django.utils.translation import ugettext_lazy as _
8 7
 from django.forms.fields import RegexField, Select
3  django/core/exceptions.py
@@ -32,3 +32,6 @@ class FieldError(Exception):
32 32
     """Some kind of problem with a model field."""
33 33
     pass
34 34
 
  35
+class ValidationError(Exception):
  36
+    """An error while validating data."""
  37
+    pass
7  django/core/serializers/base.py
@@ -57,12 +57,7 @@ def get_string_value(self, obj, field):
57 57
         """
58 58
         Convert a field's value to a string.
59 59
         """
60  
-        if isinstance(field, models.DateTimeField):
61  
-            d = datetime_safe.new_datetime(getattr(obj, field.name))
62  
-            value = d.strftime("%Y-%m-%d %H:%M:%S")
63  
-        else:
64  
-            value = field.flatten_data(follow=None, obj=obj).get(field.name, "")
65  
-        return smart_unicode(value)
  60
+        return smart_unicode(field.value_to_string(obj))
66 61
 
67 62
     def start_serialization(self):
68 63
         """
598  django/core/validators.py
... ...
@@ -1,598 +0,0 @@
1  
-"""
2  
-A library of validators that return None and raise ValidationError when the
3  
-provided data isn't valid.
4  
-
5  
-Validators may be callable classes, and they may have an 'always_test'
6  
-attribute. If an 'always_test' attribute exists (regardless of value), the
7  
-validator will *always* be run, regardless of whether its associated
8  
-form field is required.
9  
-"""
10  
-
11  
-import urllib2
12  
-import re
13  
-try:
14  
-    from decimal import Decimal, DecimalException
15  
-except ImportError:
16  
-    from django.utils._decimal import Decimal, DecimalException    # Python 2.3
17  
-
18  
-from django.conf import settings
19  
-from django.utils.translation import ugettext as _, ugettext_lazy, ungettext
20  
-from django.utils.functional import Promise, lazy
21  
-from django.utils.encoding import force_unicode, smart_str
22  
-
23  
-_datere = r'\d{4}-\d{1,2}-\d{1,2}'
24  
-_timere = r'(?:[01]?[0-9]|2[0-3]):[0-5][0-9](?::[0-5][0-9])?'
25  
-alnum_re = re.compile(r'^\w+$')
26  
-alnumurl_re = re.compile(r'^[-\w/]+$')
27  
-ansi_date_re = re.compile('^%s$' % _datere)
28  
-ansi_time_re = re.compile('^%s$' % _timere)
29  
-ansi_datetime_re = re.compile('^%s %s$' % (_datere, _timere))
30  
-email_re = re.compile(
31  
-    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
32  
-    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"' # quoted-string
33  
-    r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
34  
-integer_re = re.compile(r'^-?\d+$')
35  
-ip4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
36  
-phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$', re.IGNORECASE)
37  
-slug_re = re.compile(r'^[-\w]+$')
38  
-url_re = re.compile(r'^https?://\S+$')
39  
-
40  
-lazy_inter = lazy(lambda a,b: force_unicode(a) % b, unicode)
41  
-
42  
-class ValidationError(Exception):
43  
-    def __init__(self, message):
44  
-        "ValidationError can be passed a string or a list."
45  
-        if isinstance(message, list):
46  
-            self.messages = [force_unicode(msg) for msg in message]
47  
-        else:
48  
-            assert isinstance(message, (basestring, Promise)), ("%s should be a string" % repr(message))
49  
-            self.messages = [force_unicode(message)]
50  
-
51  
-    def __str__(self):
52  
-        # This is needed because, without a __str__(), printing an exception
53  
-        # instance would result in this:
54  
-        # AttributeError: ValidationError instance has no attribute 'args'
55  
-        # See http://www.python.org/doc/current/tut/node10.html#handling
56  
-        return str(self.messages)
57  
-
58  
-class CriticalValidationError(Exception):
59  
-    def __init__(self, message):
60  
-        "ValidationError can be passed a string or a list."
61  
-        if isinstance(message, list):
62  
-            self.messages = [force_unicode(msg) for msg in message]
63  
-        else:
64  
-            assert isinstance(message, (basestring, Promise)), ("'%s' should be a string" % message)
65  
-            self.messages = [force_unicode(message)]
66  
-
67  
-    def __str__(self):
68  
-        return str(self.messages)
69  
-
70  
-def isAlphaNumeric(field_data, all_data):
71  
-    if not alnum_re.search(field_data):
72  
-        raise ValidationError, _("This value must contain only letters, numbers and underscores.")
73  
-
74  
-def isAlphaNumericURL(field_data, all_data):
75  
-    if not alnumurl_re.search(field_data):
76  
-        raise ValidationError, _("This value must contain only letters, numbers, underscores, dashes or slashes.")
77  
-
78  
-def isSlug(field_data, all_data):
79  
-    if not slug_re.search(field_data):
80  
-        raise ValidationError, _("This value must contain only letters, numbers, underscores or hyphens.")
81  
-
82  
-def isLowerCase(field_data, all_data):
83  
-    if field_data.lower() != field_data:
84  
-        raise ValidationError, _("Uppercase letters are not allowed here.")
85  
-
86  
-def isUpperCase(field_data, all_data):
87  
-    if field_data.upper() != field_data:
88  
-        raise ValidationError, _("Lowercase letters are not allowed here.")
89  
-
90  
-def isCommaSeparatedIntegerList(field_data, all_data):
91  
-    for supposed_int in field_data.split(','):
92  
-        try:
93  
-            int(supposed_int)
94  
-        except ValueError:
95  
-            raise ValidationError, _("Enter only digits separated by commas.")
96  
-
97  
-def isCommaSeparatedEmailList(field_data, all_data):
98  
-    """
99  
-    Checks that field_data is a string of e-mail addresses separated by commas.
100  
-    Blank field_data values will not throw a validation error, and whitespace
101  
-    is allowed around the commas.
102  
-    """
103  
-    for supposed_email in field_data.split(','):
104  
-        try:
105  
-            isValidEmail(supposed_email.strip(), '')
106  
-        except ValidationError:
107  
-            raise ValidationError, _("Enter valid e-mail addresses separated by commas.")
108  
-
109  
-def isValidIPAddress4(field_data, all_data):
110  
-    if not ip4_re.search(field_data):
111  
-        raise ValidationError, _("Please enter a valid IP address.")
112  
-
113  
-def isNotEmpty(field_data, all_data):
114  
-    if field_data.strip() == '':
115  
-        raise ValidationError, _("Empty values are not allowed here.")
116  
-
117  
-def isOnlyDigits(field_data, all_data):
118  
-    if not field_data.isdigit():
119  
-        raise ValidationError, _("Non-numeric characters aren't allowed here.")
120  
-
121  
-def isNotOnlyDigits(field_data, all_data):
122  
-    if field_data.isdigit():
123  
-        raise ValidationError, _("This value can't be comprised solely of digits.")
124  
-
125  
-def isInteger(field_data, all_data):
126  
-    # This differs from isOnlyDigits because this accepts the negative sign
127  
-    if not integer_re.search(field_data):
128  
-        raise ValidationError, _("Enter a whole number.")
129  
-
130  
-def isOnlyLetters(field_data, all_data):
131  
-    if not field_data.isalpha():
132  
-        raise ValidationError, _("Only alphabetical characters are allowed here.")
133  
-
134  
-def _isValidDate(date_string):
135  
-    """
136  
-    A helper function used by isValidANSIDate and isValidANSIDatetime to
137  
-    check if the date is valid.  The date string is assumed to already be in
138  
-    YYYY-MM-DD format.
139  
-    """
140  
-    from datetime import date
141  
-    # Could use time.strptime here and catch errors, but datetime.date below
142  
-    # produces much friendlier error messages.
143  
-    year, month, day = map(int, date_string.split('-'))
144  
-    try:
145  
-        date(year, month, day)
146  
-    except ValueError, e:
147  
-        msg = _('Invalid date: %s') % _(str(e))
148  
-        raise ValidationError, msg
149  
-
150  
-def isValidANSIDate(field_data, all_data):
151  
-    if not ansi_date_re.search(field_data):
152  
-        raise ValidationError, _('Enter a valid date in YYYY-MM-DD format.')
153  
-    _isValidDate(field_data)
154  
-
155  
-def isValidANSITime(field_data, all_data):
156  
-    if not ansi_time_re.search(field_data):
157  
-        raise ValidationError, _('Enter a valid time in HH:MM format.')
158  
-
159  
-def isValidANSIDatetime(field_data, all_data):
160  
-    if not ansi_datetime_re.search(field_data):
161  
-        raise ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM format.')
162  
-    _isValidDate(field_data.split()[0])
163  
-
164  
-def isValidEmail(field_data, all_data):
165  
-    if not email_re.search(field_data):
166  
-        raise ValidationError, _('Enter a valid e-mail address.')
167  
-
168  
-def isValidImage(field_data, all_data):
169  
-    """
170  
-    Checks that the file-upload field data contains a valid image (GIF, JPG,
171  
-    PNG, possibly others -- whatever the Python Imaging Library supports).
172  
-    """
173  
-    from PIL import Image
174  
-    from cStringIO import StringIO
175  
-    try:
176  
-        content = field_data.read()
177  
-    except TypeError:
178  
-        raise ValidationError, _("No file was submitted. Check the encoding type on the form.")
179  
-    try:
180  
-        # load() is the only method that can spot a truncated JPEG,
181  
-        #  but it cannot be called sanely after verify()
182  
-        trial_image = Image.open(StringIO(content))
183  
-        trial_image.load()
184  
-        # verify() is the only method that can spot a corrupt PNG,
185  
-        #  but it must be called immediately after the constructor
186  
-        trial_image = Image.open(StringIO(content))
187  
-        trial_image.verify()
188  
-    except Exception: # Python Imaging Library doesn't recognize it as an image
189  
-        raise ValidationError, _("Upload a valid image. The file you uploaded was either not an image or a corrupted image.")
190  
-
191  
-def isValidImageURL(field_data, all_data):
192  
-    uc = URLMimeTypeCheck(('image/jpeg', 'image/gif', 'image/png'))
193  
-    try:
194  
-        uc(field_data, all_data)
195  
-    except URLMimeTypeCheck.InvalidContentType:
196  
-        raise ValidationError, _("The URL %s does not point to a valid image.") % field_data
197  
-
198  
-def isValidPhone(field_data, all_data):
199  
-    if not phone_re.search(field_data):
200  
-        raise ValidationError, _('Phone numbers must be in XXX-XXX-XXXX format. "%s" is invalid.') % field_data
201  
-
202  
-def isValidQuicktimeVideoURL(field_data, all_data):
203  
-    "Checks that the given URL is a video that can be played by QuickTime (qt, mpeg)"
204  
-    uc = URLMimeTypeCheck(('video/quicktime', 'video/mpeg',))
205  
-    try:
206  
-        uc(field_data, all_data)
207  
-    except URLMimeTypeCheck.InvalidContentType:
208  
-        raise ValidationError, _("The URL %s does not point to a valid QuickTime video.") % field_data
209  
-
210  
-def isValidURL(field_data, all_data):
211  
-    if not url_re.search(field_data):
212  
-        raise ValidationError, _("A valid URL is required.")
213  
-
214  
-def isValidHTML(field_data, all_data):
215  
-    import urllib, urllib2
216  
-    try:
217  
-        u = urllib2.urlopen('http://validator.w3.org/check', urllib.urlencode({'fragment': field_data, 'output': 'xml'}))
218  
-    except:
219  
-        # Validator or Internet connection is unavailable. Fail silently.
220  
-        return
221  
-    html_is_valid = (u.headers.get('x-w3c-validator-status', 'Invalid') == 'Valid')
222  
-    if html_is_valid:
223  
-        return
224  
-    from xml.dom.minidom import parseString
225  
-    error_messages = [e.firstChild.wholeText for e in parseString(u.read()).getElementsByTagName('messages')[0].getElementsByTagName('msg')]
226  
-    raise ValidationError, _("Valid HTML is required. Specific errors are:\n%s") % "\n".join(error_messages)
227  
-
228  
-def isWellFormedXml(field_data, all_data):
229  
-    from xml.dom.minidom import parseString
230  
-    try:
231  
-        parseString(field_data)
232  
-    except Exception, e: # Naked except because we're not sure what will be thrown
233  
-        raise ValidationError, _("Badly formed XML: %s") % str(e)
234  
-
235  
-def isWellFormedXmlFragment(field_data, all_data):
236  
-    isWellFormedXml('<root>%s</root>' % field_data, all_data)
237  
-
238  
-def isExistingURL(field_data, all_data):
239  
-    try:
240  
-        headers = {
241  
-            "Accept" : "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
242  
-            "Accept-Language" : "en-us,en;q=0.5",
243  
-            "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
244  
-            "Connection" : "close",
245  
-            "User-Agent": settings.URL_VALIDATOR_USER_AGENT
246  
-            }
247  
-        req = urllib2.Request(field_data,None, headers)
248  
-        u = urllib2.urlopen(req)
249  
-    except ValueError:
250  
-        raise ValidationError, _("Invalid URL: %s") % field_data
251  
-    except urllib2.HTTPError, e:
252  
-        # 401s are valid; they just mean authorization is required.
253  
-        # 301 and 302 are redirects; they just mean look somewhere else.
254  
-        if str(e.code) not in ('401','301','302'):
255  
-            raise ValidationError, _("The URL %s is a broken link.") % field_data
256  
-    except: # urllib2.URLError, httplib.InvalidURL, etc.
257  
-        raise ValidationError, _("The URL %s is a broken link.") % field_data
258  
-
259  
-def isValidUSState(field_data, all_data):
260  
-    "Checks that the given string is a valid two-letter U.S. state abbreviation"
261  
-    states = ['AA', 'AE', 'AK', 'AL', 'AP', 'AR', 'AS', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'FM', 'GA', 'GU', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MH', 'MI', 'MN', 'MO', 'MP', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'PR', 'PW', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VI', 'VT', 'WA', 'WI', 'WV', 'WY']
262  
-    if field_data.upper() not in states:
263  
-        raise ValidationError, _("Enter a valid U.S. state abbreviation.")
264  
-
265  
-def hasNoProfanities(field_data, all_data):
266  
-    """
267  
-    Checks that the given string has no profanities in it. This does a simple
268  
-    check for whether each profanity exists within the string, so 'fuck' will
269  
-    catch 'motherfucker' as well. Raises a ValidationError such as:
270  
-        Watch your mouth! The words "f--k" and "s--t" are not allowed here.
271  
-    """
272  
-    field_data = field_data.lower() # normalize
273  
-    words_seen = [w for w in settings.PROFANITIES_LIST if w in field_data]
274  
-    if words_seen:
275  
-        from django.utils.text import get_text_list
276  
-        plural = len(words_seen)
277  
-        raise ValidationError, ungettext("Watch your mouth! The word %s is not allowed here.",
278  
-            "Watch your mouth! The words %s are not allowed here.", plural) % \
279  
-            get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], _('and'))
280  
-
281  
-class AlwaysMatchesOtherField(object):
282  
-    def __init__(self, other_field_name, error_message=None):
283  
-        self.other = other_field_name
284  
-        self.error_message = error_message or lazy_inter(ugettext_lazy("This field must match the '%s' field."), self.other)
285  
-        self.always_test = True
286  
-
287  
-    def __call__(self, field_data, all_data):
288  
-        if field_data != all_data[self.other]:
289  
-            raise ValidationError, self.error_message
290  
-
291  
-class ValidateIfOtherFieldEquals(object):
292  
-    def __init__(self, other_field, other_value, validator_list):
293  
-        self.other_field, self.other_value = other_field, other_value
294  
-        self.validator_list = validator_list
295  
-        self.always_test = True
296  
-
297  
-    def __call__(self, field_data, all_data):
298  
-        if self.other_field in all_data and all_data[self.other_field] == self.other_value:
299  
-            for v in self.validator_list:
300  
-                v(field_data, all_data)
301  
-
302  
-class RequiredIfOtherFieldNotGiven(object):
303  
-    def __init__(self, other_field_name, error_message=ugettext_lazy("Please enter something for at least one field.")):
304  
-        self.other, self.error_message = other_field_name, error_message
305  
-        self.always_test = True
306  
-
307  
-    def __call__(self, field_data, all_data):
308  
-        if not all_data.get(self.other, False) and not field_data:
309  
-            raise ValidationError, self.error_message
310  
-
311  
-class RequiredIfOtherFieldsGiven(object):
312  
-    def __init__(self, other_field_names, error_message=ugettext_lazy("Please enter both fields or leave them both empty.")):
313  
-        self.other, self.error_message = other_field_names, error_message
314  
-        self.always_test = True
315  
-
316  
-    def __call__(self, field_data, all_data):
317  
-        for field in self.other:
318  
-            if all_data.get(field, False) and not field_data:
319  
-                raise ValidationError, self.error_message
320  
-
321  
-class RequiredIfOtherFieldGiven(RequiredIfOtherFieldsGiven):
322  
-    "Like RequiredIfOtherFieldsGiven, but takes a single field name instead of a list."
323  
-    def __init__(self, other_field_name, error_message=ugettext_lazy("Please enter both fields or leave them both empty.")):
324  
-        RequiredIfOtherFieldsGiven.__init__(self, [other_field_name], error_message)
325  
-
326  
-class RequiredIfOtherFieldEquals(object):
327  
-    def __init__(self, other_field, other_value, error_message=None, other_label=None):
328  
-        self.other_field = other_field
329  
-        self.other_value = other_value
330  
-        other_label = other_label or other_value
331  
-        self.error_message = error_message or lazy_inter(ugettext_lazy("This field must be given if %(field)s is %(value)s"), {
332  
-            'field': other_field, 'value': other_label})
333  
-        self.always_test = True
334  
-
335  
-    def __call__(self, field_data, all_data):
336  
-        if self.other_field in all_data and all_data[self.other_field] == self.other_value and not field_data:
337  
-            raise ValidationError(self.error_message)
338  
-
339  
-class RequiredIfOtherFieldDoesNotEqual(object):
340  
-    def __init__(self, other_field, other_value, other_label=None, error_message=None):
341  
-        self.other_field = other_field
342  
-        self.other_value = other_value
343  
-        other_label = other_label or other_value
344  
-        self.error_message = error_message or lazy_inter(ugettext_lazy("This field must be given if %(field)s is not %(value)s"), {
345  
-            'field': other_field, 'value': other_label})
346  
-        self.always_test = True
347  
-
348  
-    def __call__(self, field_data, all_data):
349  
-        if self.other_field in all_data and all_data[self.other_field] != self.other_value and not field_data:
350  
-            raise ValidationError(self.error_message)
351  
-
352  
-class IsLessThanOtherField(object):
353  
-    def __init__(self, other_field_name, error_message):
354  
-        self.other, self.error_message = other_field_name, error_message
355  
-
356  
-    def __call__(self, field_data, all_data):
357  
-        if field_data > all_data[self.other]:
358  
-            raise ValidationError, self.error_message
359  
-
360  
-class UniqueAmongstFieldsWithPrefix(object):
361  
-    def __init__(self, field_name, prefix, error_message):
362  
-        self.field_name, self.prefix = field_name, prefix
363  
-        self.error_message = error_message or ugettext_lazy("Duplicate values are not allowed.")
364  
-
365  
-    def __call__(self, field_data, all_data):
366  
-        for field_name, value in all_data.items():
367  
-            if field_name != self.field_name and value == field_data:
368  
-                raise ValidationError, self.error_message
369  
-
370  
-class NumberIsInRange(object):
371  
-    """
372  
-    Validator that tests if a value is in a range (inclusive).
373  
-    """
374  
-    def __init__(self, lower=None, upper=None, error_message=''):
375  
-        self.lower, self.upper = lower, upper
376  
-        if not error_message:
377  
-            if lower and upper:
378  
-                 self.error_message = _("This value must be between %(lower)s and %(upper)s.") % {'lower': lower, 'upper': upper}
379  
-            elif lower:
380  
-                self.error_message = _("This value must be at least %s.") % lower
381  
-            elif upper:
382  
-                self.error_message = _("This value must be no more than %s.") % upper
383  
-        else:
384  
-            self.error_message = error_message
385  
-
386  
-    def __call__(self, field_data, all_data):
387  
-        # Try to make the value numeric. If this fails, we assume another
388  
-        # validator will catch the problem.
389  
-        try:
390  
-            val = float(field_data)
391  
-        except ValueError:
392  
-            return
393  
-
394  
-        # Now validate
395  
-        if self.lower and self.upper and (val < self.lower or val > self.upper):
396  
-            raise ValidationError(self.error_message)
397  
-        elif self.lower and val < self.lower:
398  
-            raise ValidationError(self.error_message)
399  
-        elif self.upper and val > self.upper:
400  
-            raise ValidationError(self.error_message)
401  
-
402  
-class IsAPowerOf(object):
403  
-    """
404  
-    Usage: If you create an instance of the IsPowerOf validator:
405  
-        v = IsAPowerOf(2)
406  
-
407  
-    The following calls will succeed:
408  
-        v(4, None)
409  
-        v(8, None)
410  
-        v(16, None)
411  
-
412  
-    But this call:
413  
-        v(17, None)
414  
-    will raise "django.core.validators.ValidationError: ['This value must be a power of 2.']"
415  
-    """
416  
-    def __init__(self, power_of):
417  
-        self.power_of = power_of
418  
-
419  
-    def __call__(self, field_data, all_data):
420  
-        from math import log
421  
-        val = log(int(field_data)) / log(self.power_of)
422  
-        if val != int(val):
423  
-            raise ValidationError, _("This value must be a power of %s.") % self.power_of
424  
-
425  
-class IsValidDecimal(object):
426  
-    def __init__(self, max_digits, decimal_places):
427  
-        self.max_digits, self.decimal_places = max_digits, decimal_places
428  
-
429  
-    def __call__(self, field_data, all_data):
430  
-        try:
431  
-            val = Decimal(field_data)
432  
-        except DecimalException:
433  
-            raise ValidationError, _("Please enter a valid decimal number.")
434  
-
435  
-        pieces = str(val).lstrip("-").split('.')
436  
-        decimals = (len(pieces) == 2) and len(pieces[1]) or 0
437  
-        digits = len(pieces[0])
438  
-
439  
-        if digits + decimals > self.max_digits:
440  
-            raise ValidationError, ungettext("Please enter a valid decimal number with at most %s total digit.",
441  
-                "Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits
442  
-        if digits > (self.max_digits - self.decimal_places):
443  
-            raise ValidationError, ungettext( "Please enter a valid decimal number with a whole part of at most %s digit.",
444  
-                "Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places)
445  
-        if decimals > self.decimal_places:
446  
-            raise ValidationError, ungettext("Please enter a valid decimal number with at most %s decimal place.",
447  
-                "Please enter a valid decimal number with at most %s decimal places.", self.decimal_places) % self.decimal_places
448  
-
449  
-def isValidFloat(field_data, all_data):
450  
-    data = smart_str(field_data)
451  
-    try:
452  
-        float(data)
453  
-    except ValueError:
454  
-        raise ValidationError, _("Please enter a valid floating point number.")
455  
-
456  
-class HasAllowableSize(object):
457  
-    """
458  
-    Checks that the file-upload field data is a certain size. min_size and
459  
-    max_size are measurements in bytes.
460  
-    """
461  
-    def __init__(self, min_size=None, max_size=None, min_error_message=None, max_error_message=None):
462  
-        self.min_size, self.max_size = min_size, max_size
463  
-        self.min_error_message = min_error_message or lazy_inter(ugettext_lazy("Make sure your uploaded file is at least %s bytes big."), min_size)
464  
-        self.max_error_message = max_error_message or lazy_inter(ugettext_lazy("Make sure your uploaded file is at most %s bytes big."), max_size)
465  
-
466  
-    def __call__(self, field_data, all_data):
467  
-        try:
468  
-            content = field_data.read()
469  
-        except TypeError:
470  
-            raise ValidationError, ugettext_lazy("No file was submitted. Check the encoding type on the form.")
471  
-        if self.min_size is not None and len(content) < self.min_size:
472  
-            raise ValidationError, self.min_error_message
473  
-        if self.max_size is not None and len(content) > self.max_size:
474  
-            raise ValidationError, self.max_error_message
475  
-
476  
-class MatchesRegularExpression(object):
477  
-    """
478  
-    Checks that the field matches the given regular-expression. The regex
479  
-    should be in string format, not already compiled.
480  
-    """
481  
-    def __init__(self, regexp, error_message=ugettext_lazy("The format for this field is wrong.")):
482  
-        self.regexp = re.compile(regexp)
483  
-        self.error_message = error_message
484  
-
485  
-    def __call__(self, field_data, all_data):
486  
-        if not self.regexp.search(field_data):
487  
-            raise ValidationError(self.error_message)
488  
-
489  
-class AnyValidator(object):
490  
-    """
491  
-    This validator tries all given validators. If any one of them succeeds,
492  
-    validation passes. If none of them succeeds, the given message is thrown
493  
-    as a validation error. The message is rather unspecific, so it's best to
494  
-    specify one on instantiation.
495  
-    """
496  
-    def __init__(self, validator_list=None, error_message=ugettext_lazy("This field is invalid.")):
497  
-        if validator_list is None: validator_list = []
498  
-        self.validator_list = validator_list
499  
-        self.error_message = error_message
500  
-        for v in validator_list:
501  
-            if hasattr(v, 'always_test'):
502  
-                self.always_test = True
503  
-
504  
-    def __call__(self, field_data, all_data):
505  
-        for v in self.validator_list:
506  
-            try:
507  
-                v(field_data, all_data)
508  
-                return
509  
-            except ValidationError, e:
510  
-                pass
511  
-        raise ValidationError(self.error_message)
512  
-
513  
-class URLMimeTypeCheck(object):
514  
-    "Checks that the provided URL points to a document with a listed mime type"
515  
-    class CouldNotRetrieve(ValidationError):
516  
-        pass
517  
-    class InvalidContentType(ValidationError):
518  
-        pass
519  
-
520  
-    def __init__(self, mime_type_list):
521  
-        self.mime_type_list = mime_type_list
522  
-
523  
-    def __call__(self, field_data, all_data):
524  
-        import urllib2
525  
-        try:
526  
-            isValidURL(field_data, all_data)
527  
-        except ValidationError:
528  
-            raise
529  
-        try:
530  
-            info = urllib2.urlopen(field_data).info()
531  
-        except (urllib2.HTTPError, urllib2.URLError):
532  
-            raise URLMimeTypeCheck.CouldNotRetrieve, _("Could not retrieve anything from %s.") % field_data
533  
-        content_type = info['content-type']
534  
-        if content_type not in self.mime_type_list:
535  
-            raise URLMimeTypeCheck.InvalidContentType, _("The URL %(url)s returned the invalid Content-Type header '%(contenttype)s'.") % {
536  
-                'url': field_data, 'contenttype': content_type}
537  
-
538  
-class RelaxNGCompact(object):
539  
-    "Validate against a Relax NG compact schema"
540  
-    def __init__(self, schema_path, additional_root_element=None):
541  
-        self.schema_path = schema_path
542  
-        self.additional_root_element = additional_root_element
543  
-
544  
-    def __call__(self, field_data, all_data):
545  
-        import os, tempfile
546  
-        if self.additional_root_element:
547  
-            field_data = '<%(are)s>%(data)s\n</%(are)s>' % {
548  
-                'are': self.additional_root_element,
549  
-                'data': field_data
550  
-            }
551  
-        filename = tempfile.mktemp() # Insecure, but nothing else worked
552  
-        fp = open(filename, 'w')
553  
-        fp.write(field_data)
554  
-        fp.close()
555  
-        if not os.path.exists(settings.JING_PATH):
556  
-            raise Exception, "%s not found!" % settings.JING_PATH
557  
-        p = os.popen('%s -c %s %s' % (settings.JING_PATH, self.schema_path, filename))
558  
-        errors = [line.strip() for line in p.readlines()]
559  
-        p.close()
560  
-        os.unlink(filename)
561  
-        display_errors = []
562  
-        lines = field_data.split('\n')
563  
-        for error in errors:
564  
-            ignored, line, level, message = error.split(':', 3)
565  
-            # Scrape the Jing error messages to reword them more nicely.
566  
-            m = re.search(r'Expected "(.*?)" to terminate element starting on line (\d+)', message)
567  
-            if m:
568  
-                display_errors.append(_('Please close the unclosed %(tag)s tag from line %(line)s. (Line starts with "%(start)s".)') % \
569  
-                    {'tag':m.group(1).replace('/', ''), 'line':m.group(2), 'start':lines[int(m.group(2)) - 1][:30]})
570  
-                continue
571  
-            if message.strip() == 'text not allowed here':
572  
-                display_errors.append(_('Some text starting on line %(line)s is not allowed in that context. (Line starts with "%(start)s".)') % \
573  
-                    {'line':line, 'start':lines[int(line) - 1][:30]})
574  
-                continue
575  
-            m = re.search(r'\s*attribute "(.*?)" not allowed at this point; ignored', message)
576  
-            if m:
577  
-                display_errors.append(_('"%(attr)s" on line %(line)s is an invalid attribute. (Line starts with "%(start)s".)') % \
578  
-                    {'attr':m.group(1), 'line':line, 'start':lines[int(line) - 1][:30]})
579  
-                continue
580  
-            m = re.search(r'\s*unknown element "(.*?)"', message)
581  
-            if m:
582  
-                display_errors.append(_('"<%(tag)s>" on line %(line)s is an invalid tag. (Line starts with "%(start)s".)') % \
583  
-                    {'tag':m.group(1), 'line':line, 'start':lines[int(line) - 1][:30]})
584  
-                continue
585  
-            if message.strip() == 'required attributes missing':
586  
-                display_errors.append(_('A tag on line %(line)s is missing one or more required attributes. (Line starts with "%(start)s".)') % \
587  
-                    {'line':line, 'start':lines[int(line) - 1][:30]})
588  
-                continue
589  
-            m = re.search(r'\s*bad value for attribute "(.*?)"', message)
590  
-            if m:
591  
-                display_errors.append(_('The "%(attr)s" attribute on line %(line)s has an invalid value. (Line starts with "%(start)s".)') % \
592  
-                    {'attr':m.group(1), 'line':line, 'start':lines[int(line) - 1][:30]})
593  
-                continue
594  
-            # Failing all those checks, use the default error message.
595  
-            display_error = 'Line %s: %s [%s]' % (line, message, level.strip())
596  
-            display_errors.append(display_error)
597  
-        if len(display_errors) > 0:
598  
-            raise ValidationError, display_errors
3  django/db/models/__init__.py
... ...
@@ -1,6 +1,5 @@
1 1
 from django.conf import settings
2 2
 from django.core.exceptions import ObjectDoesNotExist, ImproperlyConfigured
3  
-from django.core import validators
4 3
 from django.db import connection
5 4
 from django.db.models.loading import get_apps, get_app, get_models, get_model, register_models
6 5
 from django.db.models.query import Q
@@ -9,7 +8,7 @@
9 8
 from django.db.models.fields import *
10 9
 from django.db.models.fields.subclassing import SubfieldBase
11 10
 from django.db.models.fields.files import FileField, ImageField
12  
-from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED
  11
+from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel
13 12
 from django.db.models import signals
14 13
 
15 14
 # Admin stages.
8  django/db/models/base.py
@@ -8,9 +8,7 @@
8 8
 except NameError:
9 9
     from sets import Set as set     # Python 2.3 fallback.
10 10
 
11  
-import django.db.models.manipulators    # Imported to register signal handler.
12  
-import django.db.models.manager         # Ditto.
13  
-from django.core import validators
  11
+import django.db.models.manager     # Imported to register signal handler.
14 12
 from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned, FieldError
15 13
 from django.db.models.fields import AutoField
16 14
 from django.db.models.fields.related import OneToOneRel, ManyToOneRel, OneToOneField
@@ -320,9 +318,7 @@ def save_base(self, raw=False, cls=None, force_insert=False,
320 318
 
321 319
         # First, try an UPDATE. If that doesn't update anything, do an INSERT.
322 320
         pk_val = self._get_pk_val(meta)
323  
-        # Note: the comparison with '' is required for compatibility with
324  
-        # oldforms-style model creation.
325  
-        pk_set = pk_val is not None and smart_unicode(pk_val) != u''
  321
+        pk_set = pk_val is not None
326 322
         record_exists = True
327 323
         manager = cls._default_manager
328 324
         if pk_set:
313  django/db/models/fields/__init__.py
... ...
@@ -1,6 +1,7 @@
1 1
 import copy
2 2
 import datetime
3 3
 import os
  4
+import re
4 5
 import time
5 6
 try:
6 7
     import decimal
@@ -12,10 +13,8 @@
12 13
 from django.db.models.query_utils import QueryWrapper
13 14
 from django.dispatch import dispatcher
14 15
 from django.conf import settings
15  
-from django.core import validators
16  
-from django import oldforms
17 16
 from django import forms
18  
-from django.core.exceptions import ObjectDoesNotExist
  17
+from django.core import exceptions
19 18
 from django.utils.datastructures import DictWrapper
20 19
 from django.utils.functional import curry
21 20
 from django.utils.itercompat import tee
@@ -34,17 +33,6 @@ class NOT_PROVIDED:
34 33
 class FieldDoesNotExist(Exception):
35 34
     pass
36 35
 
37  
-def manipulator_validator_unique(f, opts, self, field_data, all_data):
38  
-    "Validates that the value is unique for this field."
39  
-    lookup_type = f.get_validator_unique_lookup_type()
40  
-    try:
41  
-        old_obj = self.manager.get(**{lookup_type: field_data})
42  
-    except ObjectDoesNotExist:
43  
-        return
44  
-    if getattr(self, 'original_object', None) and self.original_object._get_pk_val() == old_obj._get_pk_val():
45  
-        return
46  
-    raise validators.ValidationError, _("%(optname)s with this %(fieldname)s already exists.") % {'optname': capfirst(opts.verbose_name), 'fieldname': f.verbose_name}
47  
-
48 36
 # A guide to Field parameters:
49 37
 #
50 38
 #   * name:      The name of the field specifed in the model.
@@ -73,11 +61,10 @@ class Field(object):
73 61
 
74 62
     def __init__(self, verbose_name=None, name=None, primary_key=False,
75 63
             max_length=None, unique=False, blank=False, null=False,
76  
-            db_index=False, core=False, rel=None, default=NOT_PROVIDED,
77  
-            editable=True, serialize=True, unique_for_date=None,
78  
-            unique_for_month=None, unique_for_year=None, validator_list=None,
79  
-            choices=None, help_text='', db_column=None, db_tablespace=None,
80  
-            auto_created=False):
  64
+            db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
  65
+            serialize=True, unique_for_date=None, unique_for_month=None,
  66
+            unique_for_year=None, choices=None, help_text='', db_column=None,
  67
+            db_tablespace=None, auto_created=False):
81 68
         self.name = name
82 69
         self.verbose_name = verbose_name
83 70
         self.primary_key = primary_key
@@ -87,10 +74,10 @@ def __init__(self, verbose_name=None, name=None, primary_key=False,
87 74
         # option whenever '' is a possible value.
88 75
         if self.empty_strings_allowed and connection.features.interprets_empty_strings_as_nulls:
89 76
             self.null = True
90  
-        self.core, self.rel, self.default = core, rel, default
  77
+        self.rel = rel
  78
+        self.default = default
91 79
         self.editable = editable
92 80
         self.serialize = serialize
93  
-        self.validator_list = validator_list or []
94 81
         self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
95 82
         self.unique_for_year = unique_for_year
96 83
         self._choices = choices or []
@@ -126,8 +113,8 @@ def __deepcopy__(self, memodict):
126 113
     def to_python(self, value):
127 114
         """
128 115
         Converts the input value into the expected Python data type, raising
129  
-        validators.ValidationError if the data can't be converted. Returns the
130  
-        converted value. Subclasses should override this.
  116
+        django.core.exceptions.ValidationError if the data can't be converted.
  117
+        Returns the converted value. Subclasses should override this.
131 118
         """
132 119
         return value
133 120
 
@@ -252,93 +239,9 @@ def get_default(self):
252 239
             return None
253 240
         return ""
254 241
 
255  
-    def get_manipulator_field_names(self, name_prefix):
256  
-        """
257  
-        Returns a list of field names that this object adds to the manipulator.
258  
-        """
259  
-        return [name_prefix + self.name]
260  
-
261  
-    def prepare_field_objs_and_params(self, manipulator, name_prefix):
262  
-        params = {'validator_list': self.validator_list[:]}
263  
-        if self.max_length and not self.choices: # Don't give SelectFields a max_length parameter.
264  
-            params['max_length'] = self.max_length
265  
-
266  
-        if self.choices:
267  
-            field_objs = [oldforms.SelectField]
268  
-
269  
-            params['choices'] = self.get_flatchoices()
270  
-        else:
271  
-            field_objs = self.get_manipulator_field_objs()
272  
-        return (field_objs, params)
273  
-
274  
-    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
275  
-        """
276  
-        Returns a list of oldforms.FormField instances for this field. It
277  
-        calculates the choices at runtime, not at compile time.
278  
-
279  
-        name_prefix is a prefix to prepend to the "field_name" argument.
280  
-        rel is a boolean specifying whether this field is in a related context.
281  
-        """
282  
-        field_objs, params = self.prepare_field_objs_and_params(manipulator, name_prefix)
283  
-
284  
-        # Add the "unique" validator(s).
285  
-        for field_name_list in opts.unique_together:
286  
-            if field_name_list[0] == self.name:
287  
-                params['validator_list'].append(getattr(manipulator, 'isUnique%s' % '_'.join(field_name_list)))
288  
-
289  
-        # Add the "unique for..." validator(s).
290  
-        if self.unique_for_date:
291  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_date)))
292  
-        if self.unique_for_month:
293  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_month)))
294  
-        if self.unique_for_year:
295  
-            params['validator_list'].append(getattr(manipulator, 'isUnique%sFor%s' % (self.name, self.unique_for_year)))
296  
-        if self.unique and not rel:
297  
-            params['validator_list'].append(curry(manipulator_validator_unique, self, opts, manipulator))
298  
-
299  
-        # Only add is_required=True if the field cannot be blank. Primary keys
300  
-        # are a special case, and fields in a related context should set this
301  
-        # as False, because they'll be caught by a separate validator --
302  
-        # RequiredIfOtherFieldGiven.
303  
-        params['is_required'] = not self.blank and not self.primary_key and not rel
304  
-
305  
-        # BooleanFields (CheckboxFields) are a special case. They don't take
306  
-        # is_required.
307  
-        if isinstance(self, BooleanField):
308  
-            del params['is_required']
309  
-
310  
-        # If this field is in a related context, check whether any other fields
311  
-        # in the related object have core=True. If so, add a validator --
312  
-        # RequiredIfOtherFieldsGiven -- to this FormField.
313  
-        if rel and not self.blank and not isinstance(self, AutoField) and not isinstance(self, FileField):
314  
-            # First, get the core fields, if any.
315  
-            core_field_names = []
316  
-            for f in opts.fields:
317  
-                if f.core and f != self:
318  
-                    core_field_names.extend(f.get_manipulator_field_names(name_prefix))
319  
-            # Now, if there are any, add the validator to this FormField.
320  
-            if core_field_names:
321  
-                params['validator_list'].append(validators.RequiredIfOtherFieldsGiven(core_field_names, ugettext_lazy("This field is required.")))
322  
-
323  
-        # Finally, add the field_names.
324  
-        field_names = self.get_manipulator_field_names(name_prefix)
325  
-        return [man(field_name=field_names[i], **params) for i, man in enumerate(field_objs)]
326  
-
327 242
     def get_validator_unique_lookup_type(self):
328 243
         return '%s__exact' % self.name
329 244
 
330  
-    def get_manipulator_new_data(self, new_data, rel=False):
331  
-        """
332  
-        Given the full new_data dictionary (from the manipulator), returns this
333  
-        field's data.
334  
-        """
335  
-        if rel:
336  
-            return new_data.get(self.name, [self.get_default()])[0]
337  
-        val = new_data.get(self.name, self.get_default())
338  
-        if not self.empty_strings_allowed and val == '' and self.null:
339  
-            val = None
340  
-        return val
341  
-
342 245
     def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
343 246
         """Returns choices with a default blank choices included, for use
344 247
         as SelectField choices for this field."""
@@ -366,19 +269,12 @@ def _get_val_from_obj(self, obj):
366 269
         else:
367 270
             return self.get_default()
368 271
 
369  
-    def flatten_data(self, follow, obj=None):
  272
+    def value_to_string(self, obj):
370 273
         """
371  
-        Returns a dictionary mapping the field's manipulator field names to its
372  
-        "flattened" string values for the admin view. obj is the instance to
373  
-        extract the values from.
  274
+        Returns a string value of this field from the passed obj.
  275
+        This is used by the serialization framework.
374 276
         """
375  
-        return {self.attname: self._get_val_from_obj(obj)}
376  
-
377  
-    def get_follow(self, override=None):
378  
-        if override != None:
379  
-            return override
380  
-        else:
381  
-            return self.editable
  277
+        return smart_unicode(self._get_val_from_obj(obj))
382 278
 
383 279
     def bind(self, fieldmapping, original, bound_field_class):
384 280
         return bound_field_class(self, fieldmapping, original)
@@ -432,29 +328,14 @@ def to_python(self, value):
432 328
         try:
433 329
             return int(value)
434 330
         except (TypeError, ValueError):
435  
-            raise validators.ValidationError, _("This value must be an integer.")
  331
+            raise exceptions.ValidationError(
  332
+                _("This value must be an integer."))
436 333
 
437 334
     def get_db_prep_value(self, value):
438 335
         if value is None:
439 336
             return None
440 337
         return int(value)
441 338
 
442  
-    def get_manipulator_fields(self, opts, manipulator, change, name_prefix='', rel=False, follow=True):
443  
-        if not rel:
444  
-            return [] # Don't add a FormField unless it's in a related context.
445  
-        return Field.get_manipulator_fields(self, opts, manipulator, change, name_prefix, rel, follow)
446  
-
447  
-    def get_manipulator_field_objs(self):
448  
-        return [oldforms.HiddenField]
449  
-
450  
-    def get_manipulator_new_data(self, new_data, rel=False):
451  
-        # Never going to be called
452  
-        # Not in main change pages
453  
-        # ignored in related context
454  
-        if not rel:
455  
-            return None
456  
-        return Field.get_manipulator_new_data(self, new_data, rel)
457  
-
458 339
     def contribute_to_class(self, cls, name):
459 340
         assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
460 341
         super(AutoField, self).contribute_to_class(cls, name)
@@ -478,25 +359,20 @@ def to_python(self, value):
478 359
         if value in (True, False): return value
479 360
         if value in ('t', 'True', '1'): return True
480 361
         if value in ('f', 'False', '0'): return False
481  
-        raise validators.ValidationError, _("This value must be either True or False.")
  362
+        raise exceptions.ValidationError(
  363
+            _("This value must be either True or False."))
482 364
 
483 365
     def get_db_prep_value(self, value):
484 366
         if value is None:
485 367
             return None
486 368
         return bool(value)
487 369
 
488  
-    def get_manipulator_field_objs(self):
489  
-        return [oldforms.CheckboxField]
490  
-
491 370
     def formfield(self, **kwargs):
492 371
         defaults = {'form_class': forms.BooleanField}
493 372
         defaults.update(kwargs)
494 373
         return super(BooleanField, self).formfield(**defaults)
495 374
 
496 375
 class CharField(Field):
497  
-    def get_manipulator_field_objs(self):
498  
-        return [oldforms.TextField]
499  
-
500 376
     def get_internal_type(self):
501 377
         return "CharField"
502 378
 
@@ -507,7 +383,8 @@ def to_python(self, value):
507 383
             if self.null:
508 384
                 return value
509 385
             else:
510  
-                raise validators.ValidationError, ugettext_lazy("This field cannot be null.")
  386
+                raise exceptions.ValidationError(
  387
+                    ugettext_lazy("This field cannot be null."))