summaryrefslogtreecommitdiff
path: root/django/db/models/fields
diff options
context:
space:
mode:
authorGary Wilson Jr <gary.wilson@gmail.com>2008-08-27 07:19:44 +0000
committerGary Wilson Jr <gary.wilson@gmail.com>2008-08-27 07:19:44 +0000
commitc2ba59fc1da5287d6286e2c2aca4083d5bafe056 (patch)
tree26c05bc1b845efadd28126adee8f2a3726f09424 /django/db/models/fields
parenta1575766604205b3bddf0f05d13ad698c78a7582 (diff)
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
Diffstat (limited to 'django/db/models/fields')
-rw-r--r--django/db/models/fields/__init__.py313
-rw-r--r--django/db/models/fields/files.py54
-rw-r--r--django/db/models/fields/related.py98
3 files changed, 93 insertions, 372 deletions
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index b8d05671b1..5c21e7db73 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1,6 +1,7 @@
import copy
import datetime
import os
+import re
import time
try:
import decimal
@@ -12,10 +13,8 @@ from django.db.models import signals
from django.db.models.query_utils import QueryWrapper
from django.dispatch import dispatcher
from django.conf import settings
-from django.core import validators
-from django import oldforms
from django import forms
-from django.core.exceptions import ObjectDoesNotExist
+from django.core import exceptions
from django.utils.datastructures import DictWrapper
from django.utils.functional import curry
from django.utils.itercompat import tee
@@ -34,17 +33,6 @@ BLANK_CHOICE_NONE = [("", "None")]
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, _("%(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.
@@ -73,11 +61,10 @@ class Field(object):
def __init__(self, verbose_name=None, name=None, primary_key=False,
max_length=None, unique=False, blank=False, null=False,
- db_index=False, core=False, rel=None, default=NOT_PROVIDED,
- editable=True, serialize=True, unique_for_date=None,
- unique_for_month=None, unique_for_year=None, validator_list=None,
- choices=None, help_text='', db_column=None, db_tablespace=None,
- auto_created=False):
+ db_index=False, rel=None, default=NOT_PROVIDED, editable=True,
+ serialize=True, unique_for_date=None, unique_for_month=None,
+ unique_for_year=None, choices=None, help_text='', db_column=None,
+ db_tablespace=None, auto_created=False):
self.name = name
self.verbose_name = verbose_name
self.primary_key = primary_key
@@ -87,10 +74,10 @@ class Field(object):
# option whenever '' is a possible value.
if self.empty_strings_allowed and connection.features.interprets_empty_strings_as_nulls:
self.null = True
- self.core, self.rel, self.default = core, rel, default
+ self.rel = rel
+ self.default = default
self.editable = editable
self.serialize = serialize
- self.validator_list = validator_list or []
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 []
@@ -126,8 +113,8 @@ class Field(object):
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.
+ django.core.exceptions.ValidationError if the data can't be converted.
+ Returns the converted value. Subclasses should override this.
"""
return value
@@ -252,93 +239,9 @@ class Field(object):
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.max_length and not self.choices: # Don't give SelectFields a max_length parameter.
- params['max_length'] = self.max_length
-
- if self.choices:
- field_objs = [oldforms.SelectField]
-
- params['choices'] = self.get_flatchoices()
- 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 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, ugettext_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 choices with a default blank choices included, for use
as SelectField choices for this field."""
@@ -366,19 +269,12 @@ class Field(object):
else:
return self.get_default()
- def flatten_data(self, follow, obj=None):
+ def value_to_string(self, obj):
"""
- 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.
+ Returns a string value of this field from the passed obj.
+ This is used by the serialization framework.
"""
- return {self.attname: self._get_val_from_obj(obj)}
-
- def get_follow(self, override=None):
- if override != None:
- return override
- else:
- return self.editable
+ return smart_unicode(self._get_val_from_obj(obj))
def bind(self, fieldmapping, original, bound_field_class):
return bound_field_class(self, fieldmapping, original)
@@ -432,29 +328,14 @@ class AutoField(Field):
try:
return int(value)
except (TypeError, ValueError):
- raise validators.ValidationError, _("This value must be an integer.")
+ raise exceptions.ValidationError(
+ _("This value must be an integer."))
def get_db_prep_value(self, value):
if value is None:
return None
return int(value)
- 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)
@@ -478,25 +359,20 @@ class BooleanField(Field):
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, _("This value must be either True or False.")
+ raise exceptions.ValidationError(
+ _("This value must be either True or False."))
def get_db_prep_value(self, value):
if value is None:
return None
return bool(value)
- def get_manipulator_field_objs(self):
- return [oldforms.CheckboxField]
-
def formfield(self, **kwargs):
defaults = {'form_class': forms.BooleanField}
defaults.update(kwargs)
return super(BooleanField, self).formfield(**defaults)
class CharField(Field):
- def get_manipulator_field_objs(self):
- return [oldforms.TextField]
-
def get_internal_type(self):
return "CharField"
@@ -507,7 +383,8 @@ class CharField(Field):
if self.null:
return value
else:
- raise validators.ValidationError, ugettext_lazy("This field cannot be null.")
+ raise exceptions.ValidationError(
+ ugettext_lazy("This field cannot be null."))
return smart_unicode(value)
def formfield(self, **kwargs):
@@ -517,8 +394,9 @@ class CharField(Field):
# TODO: Maybe move this into contrib, because it's specialized.
class CommaSeparatedIntegerField(CharField):
- def get_manipulator_field_objs(self):
- return [oldforms.CommaSeparatedIntegerField]
+ pass
+
+ansi_date_re = re.compile(r'^\d{4}-\d{1,2}-\d{1,2}$')
class DateField(Field):
empty_strings_allowed = False
@@ -540,11 +418,20 @@ class DateField(Field):
return value.date()
if isinstance(value, datetime.date):
return value
- validators.isValidANSIDate(value, None)
+
+ if not ansi_date_re.search(value):
+ raise exceptions.ValidationError(
+ _('Enter a valid date in YYYY-MM-DD format.'))
+ # Now that we have the date string in YYYY-MM-DD format, check to make
+ # sure it's a valid date.
+ # We could use time.strptime here and catch errors, but datetime.date
+ # produces much friendlier error messages.
+ year, month, day = map(int, value.split('-'))
try:
- return datetime.date(*time.strptime(value, '%Y-%m-%d')[:3])
- except ValueError:
- raise validators.ValidationError, _('Enter a valid date in YYYY-MM-DD format.')
+ return datetime.date(year, month, day)
+ except ValueError, e:
+ msg = _('Invalid date: %s') % _(str(e))
+ raise exceptions.ValidationError(msg)
def pre_save(self, model_instance, add):
if self.auto_now or (self.auto_now_add and add):
@@ -562,13 +449,6 @@ class DateField(Field):
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_lookup(self, lookup_type, value):
# For "__month" and "__day" lookups, convert the value to a string so
# the database backend always sees a consistent type.
@@ -580,16 +460,13 @@ class DateField(Field):
# Casts dates into the format expected by the backend
return connection.ops.value_to_db_date(self.to_python(value))
- def get_manipulator_field_objs(self):
- return [oldforms.DateField]
-
- def flatten_data(self, follow, obj=None):
+ def value_to_string(self, obj):
val = self._get_val_from_obj(obj)
if val is None:
data = ''
else:
data = datetime_safe.new_date(val).strftime("%Y-%m-%d")
- return {self.attname: data}
+ return data
def formfield(self, **kwargs):
defaults = {'form_class': forms.DateField}
@@ -616,7 +493,8 @@ class DateTimeField(DateField):
value, usecs = value.split('.')
usecs = int(usecs)
except ValueError:
- raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.')
+ raise exceptions.ValidationError(
+ _('Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.'))
else:
usecs = 0
kwargs = {'microsecond': usecs}
@@ -633,40 +511,21 @@ class DateTimeField(DateField):
return datetime.datetime(*time.strptime(value, '%Y-%m-%d')[:3],
**kwargs)
except ValueError:
- raise validators.ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.')
+ raise exceptions.ValidationError(
+ _('Enter a valid date/time in YYYY-MM-DD HH:MM[:ss[.uuuuuu]] format.'))
def get_db_prep_value(self, value):
# Casts dates into the format expected by the backend
return connection.ops.value_to_db_datetime(self.to_python(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):
+ def value_to_string(self, obj):
val = self._get_val_from_obj(obj)
- date_field, time_field = self.get_manipulator_field_names('')
if val is None:
- date_data = time_data = ''
+ data = ''
else:
d = datetime_safe.new_datetime(val)
- date_data = d.strftime('%Y-%m-%d')
- time_data = d.strftime('%H:%M:%S')
- return {date_field: date_data, time_field: time_data}
+ data = d.strftime('%Y-%m-%d %H:%M:%S')
+ return data
def formfield(self, **kwargs):
defaults = {'form_class': forms.DateTimeField}
@@ -688,7 +547,7 @@ class DecimalField(Field):
try:
return decimal.Decimal(value)
except decimal.InvalidOperation:
- raise validators.ValidationError(
+ raise exceptions.ValidationError(
_("This value must be a decimal number."))
def _format(self, value):
@@ -715,9 +574,6 @@ class DecimalField(Field):
return connection.ops.value_to_db_decimal(self.to_python(value),
self.max_digits, self.decimal_places)
- def get_manipulator_field_objs(self):
- return [curry(oldforms.DecimalField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
-
def formfield(self, **kwargs):
defaults = {
'max_digits': self.max_digits,
@@ -732,9 +588,6 @@ class EmailField(CharField):
kwargs['max_length'] = kwargs.get('max_length', 75)
CharField.__init__(self, *args, **kwargs)
- def get_manipulator_field_objs(self):
- return [oldforms.EmailField]
-
def formfield(self, **kwargs):
defaults = {'form_class': forms.EmailField}
defaults.update(kwargs)
@@ -756,9 +609,6 @@ class FilePathField(Field):
defaults.update(kwargs)
return super(FilePathField, self).formfield(**defaults)
- def get_manipulator_field_objs(self):
- return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
-
def get_internal_type(self):
return "FilePathField"
@@ -770,9 +620,6 @@ class FloatField(Field):
return None
return float(value)
- def get_manipulator_field_objs(self):
- return [oldforms.FloatField]
-
def get_internal_type(self):
return "FloatField"
@@ -788,9 +635,6 @@ class IntegerField(Field):
return None
return int(value)
- def get_manipulator_field_objs(self):
- return [oldforms.IntegerField]
-
def get_internal_type(self):
return "IntegerField"
@@ -800,8 +644,9 @@ class IntegerField(Field):
try:
return int(value)
except (TypeError, ValueError):
- raise validators.ValidationError, _("This value must be an integer.")
-
+ raise exceptions.ValidationError(
+ _("This value must be an integer."))
+
def formfield(self, **kwargs):
defaults = {'form_class': forms.IntegerField}
defaults.update(kwargs)
@@ -813,9 +658,6 @@ class IPAddressField(Field):
kwargs['max_length'] = 15
Field.__init__(self, *args, **kwargs)
- def get_manipulator_field_objs(self):
- return [oldforms.IPAddressField]
-
def get_internal_type(self):
return "IPAddressField"
@@ -838,16 +680,14 @@ class NullBooleanField(Field):
if value in ('None'): return None
if value in ('t', 'True', '1'): return True
if value in ('f', 'False', '0'): return False
- raise validators.ValidationError, _("This value must be either None, True or False.")
+ raise exceptions.ValidationError(
+ _("This value must be either None, True or False."))
def get_db_prep_value(self, value):
if value is None:
return None
return bool(value)
- def get_manipulator_field_objs(self):
- return [oldforms.NullBooleanField]
-
def formfield(self, **kwargs):
defaults = {
'form_class': forms.NullBooleanField,
@@ -858,9 +698,6 @@ class NullBooleanField(Field):
return super(NullBooleanField, self).formfield(**defaults)
class PhoneNumberField(Field):
- def get_manipulator_field_objs(self):
- return [oldforms.PhoneNumberField]
-
def get_internal_type(self):
return "PhoneNumberField"
@@ -871,9 +708,6 @@ class PhoneNumberField(Field):
return super(PhoneNumberField, self).formfield(**defaults)
class PositiveIntegerField(IntegerField):
- def get_manipulator_field_objs(self):
- return [oldforms.PositiveIntegerField]
-
def get_internal_type(self):
return "PositiveIntegerField"
@@ -883,9 +717,6 @@ class PositiveIntegerField(IntegerField):
return super(PositiveIntegerField, self).formfield(**defaults)
class PositiveSmallIntegerField(IntegerField):
- def get_manipulator_field_objs(self):
- return [oldforms.PositiveSmallIntegerField]
-
def get_internal_type(self):
return "PositiveSmallIntegerField"
@@ -897,7 +728,6 @@ class PositiveSmallIntegerField(IntegerField):
class SlugField(CharField):
def __init__(self, *args, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 50)
- kwargs.setdefault('validator_list', []).append(validators.isSlug)
# Set db_index=True unless it's been set manually.
if 'db_index' not in kwargs:
kwargs['db_index'] = True
@@ -907,23 +737,15 @@ class SlugField(CharField):
return "SlugField"
def formfield(self, **kwargs):
- defaults = {'form_class': forms.RegexField, 'regex': r'^[a-zA-Z0-9_-]+$',
- 'error_messages': {'invalid': _(u"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.")},
- }
+ defaults = {'form_class': forms.SlugField}
defaults.update(kwargs)
return super(SlugField, self).formfield(**defaults)
class SmallIntegerField(IntegerField):
- def get_manipulator_field_objs(self):
- return [oldforms.SmallIntegerField]
-
def get_internal_type(self):
return "SmallIntegerField"
class TextField(Field):
- def get_manipulator_field_objs(self):
- return [oldforms.LargeTextField]
-
def get_internal_type(self):
return "TextField"
@@ -957,7 +779,8 @@ class TimeField(Field):
value, usecs = value.split('.')
usecs = int(usecs)
except ValueError:
- raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.')
+ raise exceptions.ValidationError(
+ _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.'))
else:
usecs = 0
kwargs = {'microsecond': usecs}
@@ -970,7 +793,8 @@ class TimeField(Field):
return datetime.time(*time.strptime(value, '%H:%M')[3:5],
**kwargs)
except ValueError:
- raise validators.ValidationError, _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.')
+ raise exceptions.ValidationError(
+ _('Enter a valid time in HH:MM[:ss[.uuuuuu]] format.'))
def pre_save(self, model_instance, add):
if self.auto_now or (self.auto_now_add and add):
@@ -984,12 +808,13 @@ class TimeField(Field):
# Casts times into the format expected by the backend
return connection.ops.value_to_db_time(self.to_python(value))
- def get_manipulator_field_objs(self):
- return [oldforms.TimeField]
-
- def flatten_data(self,follow, obj = None):
+ def value_to_string(self, obj):
val = self._get_val_from_obj(obj)
- return {self.attname: (val is not None and val.strftime("%H:%M:%S") or '')}
+ if val is None:
+ data = ''
+ else:
+ data = val.strftime("%H:%M:%S")
+ return data
def formfield(self, **kwargs):
defaults = {'form_class': forms.TimeField}
@@ -999,23 +824,15 @@ class TimeField(Field):
class URLField(CharField):
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 200)
- if verify_exists:
- kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
self.verify_exists = verify_exists
CharField.__init__(self, verbose_name, name, **kwargs)
- def get_manipulator_field_objs(self):
- return [oldforms.URLField]
-
def formfield(self, **kwargs):
defaults = {'form_class': forms.URLField, 'verify_exists': self.verify_exists}
defaults.update(kwargs)
return super(URLField, self).formfield(**defaults)
class USStateField(Field):
- def get_manipulator_field_objs(self):
- return [oldforms.USStateField]
-
def get_internal_type(self):
return "USStateField"
@@ -1029,7 +846,3 @@ 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_manipulator_field_objs(self):
- return [curry(oldforms.XMLLargeTextField, schema_path=self.schema_path)]
-
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index 935dee6162..f83f0cf575 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -11,9 +11,7 @@ from django.utils.functional import curry
from django.db.models import signals
from django.utils.encoding import force_unicode, smart_str
from django.utils.translation import ugettext_lazy, ugettext as _
-from django import oldforms
from django import forms
-from django.core import validators
from django.db.models.loading import cache
class FieldFile(File):
@@ -126,7 +124,7 @@ class FileField(Field):
attr_class = FieldFile
def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs):
- for arg in ('core', 'primary_key', 'unique'):
+ for arg in ('primary_key', 'unique'):
if arg in kwargs:
raise TypeError("'%s' is not a valid argument for %s." % (arg, self.__class__))
@@ -153,42 +151,6 @@ class FileField(Field):
return None
return unicode(value)
- 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, ugettext_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, ugettext_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, self.name, FileDescriptor(self))
@@ -206,14 +168,9 @@ class FileField(Field):
# Otherwise, just close the file, so it doesn't tie up resources.
file.close()
- 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, save=True):
- upload_field_name = self.get_manipulator_field_names('')[0]
+ def save_file(self, new_data, new_object, original_object, change, rel,
+ save=True):
+ upload_field_name = self.name + '_file'
if new_data.get(upload_field_name, False):
if rel:
file = new_data[upload_field_name][0]
@@ -282,9 +239,6 @@ class ImageField(FileField):
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 formfield(self, **kwargs):
defaults = {'form_class': forms.ImageField}
defaults.update(kwargs)
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 7601911f0c..db606e5042 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -4,10 +4,10 @@ from django.db.models.fields import AutoField, Field, IntegerField, PositiveInte
from django.db.models.related import RelatedObject
from django.db.models.query import QuerySet
from django.db.models.query_utils import QueryWrapper
+from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy, string_concat, ungettext, ugettext as _
from django.utils.functional import curry
-from django.core import validators
-from django import oldforms
+from django.core import exceptions
from django import forms
try:
@@ -15,9 +15,6 @@ try:
except NameError:
from sets import Set as set # Python 2.3 fallback
-# Values for Relation.edit_inline.
-TABULAR, STACKED = 1, 2
-
RECURSIVE_RELATIONSHIP_CONSTANT = 'self'
pending_lookups = {}
@@ -83,14 +80,6 @@ def do_pending_lookups(sender, **kwargs):
signals.class_prepared.connect(do_pending_lookups)
-def manipulator_valid_rel_key(f, self, field_data, all_data):
- "Validates that the value is a valid foreign key"
- klass = f.rel.to
- try:
- klass._default_manager.get(**{f.rel.field_name: field_data})
- except klass.DoesNotExist:
- raise validators.ValidationError, _("Please enter a valid %s.") % f.verbose_name
-
#HACK
class RelatedField(object):
def contribute_to_class(self, cls, name):
@@ -580,18 +569,14 @@ class ReverseManyRelatedObjectsDescriptor(object):
manager.add(*value)
class ManyToOneRel(object):
- def __init__(self, to, field_name, num_in_admin=3, min_num_in_admin=None,
- max_num_in_admin=None, num_extra_on_change=1, edit_inline=False,
- related_name=None, limit_choices_to=None, lookup_overrides=None,
- parent_link=False):
+ def __init__(self, to, field_name, related_name=None,
+ limit_choices_to=None, lookup_overrides=None, parent_link=False):
try:
to._meta
except AttributeError: # to._meta doesn't exist, so it must be RECURSIVE_RELATIONSHIP_CONSTANT
assert isinstance(to, basestring), "'to' must be either a model, a model name or the string %r" % RECURSIVE_RELATIONSHIP_CONSTANT
self.to, self.field_name = to, field_name
- self.num_in_admin, self.edit_inline = num_in_admin, edit_inline
- self.min_num_in_admin, self.max_num_in_admin = min_num_in_admin, max_num_in_admin
- self.num_extra_on_change, self.related_name = num_extra_on_change, related_name
+ self.related_name = related_name
if limit_choices_to is None:
limit_choices_to = {}
self.limit_choices_to = limit_choices_to
@@ -611,29 +596,21 @@ class ManyToOneRel(object):
return data[0]
class OneToOneRel(ManyToOneRel):
- def __init__(self, to, field_name, num_in_admin=0, min_num_in_admin=None,
- max_num_in_admin=None, num_extra_on_change=None, edit_inline=False,
- related_name=None, limit_choices_to=None, lookup_overrides=None,
- parent_link=False):
- # NOTE: *_num_in_admin and num_extra_on_change are intentionally
- # ignored here. We accept them as parameters only to match the calling
- # signature of ManyToOneRel.__init__().
- super(OneToOneRel, self).__init__(to, field_name, num_in_admin,
- edit_inline=edit_inline, related_name=related_name,
- limit_choices_to=limit_choices_to,
+ def __init__(self, to, field_name, related_name=None,
+ limit_choices_to=None, lookup_overrides=None, parent_link=False):
+ super(OneToOneRel, self).__init__(to, field_name,
+ related_name=related_name, limit_choices_to=limit_choices_to,
lookup_overrides=lookup_overrides, parent_link=parent_link)
self.multiple = False
class ManyToManyRel(object):
- def __init__(self, to, num_in_admin=0, related_name=None,
- limit_choices_to=None, symmetrical=True, through=None):
+ def __init__(self, to, related_name=None, limit_choices_to=None,
+ symmetrical=True, through=None):
self.to = to
- self.num_in_admin = num_in_admin
self.related_name = related_name
if limit_choices_to is None:
limit_choices_to = {}
self.limit_choices_to = limit_choices_to
- self.edit_inline = False
self.symmetrical = symmetrical
self.multiple = True
self.through = through
@@ -651,11 +628,6 @@ class ForeignKey(RelatedField, Field):
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
kwargs['rel'] = rel_class(to, to_field,
- num_in_admin=kwargs.pop('num_in_admin', 3),
- min_num_in_admin=kwargs.pop('min_num_in_admin', None),
- max_num_in_admin=kwargs.pop('max_num_in_admin', None),
- num_extra_on_change=kwargs.pop('num_extra_on_change', 1),
- edit_inline=kwargs.pop('edit_inline', False),
related_name=kwargs.pop('related_name', None),
limit_choices_to=kwargs.pop('limit_choices_to', None),
lookup_overrides=kwargs.pop('lookup_overrides', None),
@@ -670,15 +642,6 @@ class ForeignKey(RelatedField, Field):
def get_validator_unique_lookup_type(self):
return '%s__%s__exact' % (self.name, self.rel.get_related_field().name)
- def prepare_field_objs_and_params(self, manipulator, name_prefix):
- params = {'validator_list': self.validator_list[:], 'member_name': name_prefix + self.attname}
- if self.null:
- field_objs = [oldforms.NullSelectField]
- else:
- field_objs = [oldforms.SelectField]
- params['choices'] = self.get_choices_default()
- return field_objs, params
-
def get_default(self):
"Here we check if the default value is an object and return the to_field if so."
field_default = super(ForeignKey, self).get_default()
@@ -686,17 +649,13 @@ class ForeignKey(RelatedField, Field):
return getattr(field_default, self.rel.get_related_field().attname)
return field_default
- def get_manipulator_field_objs(self):
- rel_field = self.rel.get_related_field()
- return [oldforms.IntegerField]
-
def get_db_prep_save(self, value):
if value == '' or value == None:
return None
else:
return self.rel.get_related_field().get_db_prep_save(value)
- def flatten_data(self, follow, obj=None):
+ def value_to_string(self, obj):
if not obj:
# In required many-to-one fields with only one available choice,
# select that one available choice. Note: For SelectFields
@@ -705,8 +664,8 @@ class ForeignKey(RelatedField, Field):
if not self.blank and self.choices:
choice_list = self.get_choices_default()
if len(choice_list) == 2:
- return {self.attname: choice_list[1][0]}
- return Field.flatten_data(self, follow, obj)
+ return smart_unicode(choice_list[1][0])
+ return Field.value_to_string(self, obj)
def contribute_to_class(self, cls, name):
super(ForeignKey, self).contribute_to_class(cls, name)
@@ -744,8 +703,6 @@ class OneToOneField(ForeignKey):
"""
def __init__(self, to, to_field=None, **kwargs):
kwargs['unique'] = True
- if 'num_in_admin' not in kwargs:
- kwargs['num_in_admin'] = 0
super(OneToOneField, self).__init__(to, to_field, OneToOneRel, **kwargs)
def contribute_to_related_class(self, cls, related):
@@ -768,7 +725,6 @@ class ManyToManyField(RelatedField, Field):
kwargs['verbose_name'] = kwargs.get('verbose_name', None)
kwargs['rel'] = ManyToManyRel(to,
- num_in_admin=kwargs.pop('num_in_admin', 0),
related_name=kwargs.pop('related_name', None),
limit_choices_to=kwargs.pop('limit_choices_to', None),
symmetrical=kwargs.pop('symmetrical', True),
@@ -786,10 +742,6 @@ class ManyToManyField(RelatedField, Field):
msg = ugettext_lazy('Hold down "Control", or "Command" on a Mac, to select more than one.')
self.help_text = string_concat(self.help_text, ' ', msg)
- def get_manipulator_field_objs(self):
- choices = self.get_choices_default()
- return [curry(oldforms.SelectMultipleField, size=min(max(len(choices), 5), 15), choices=choices)]
-
def get_choices_default(self):
return Field.get_choices(self, include_blank=False)
@@ -863,25 +815,27 @@ class ManyToManyField(RelatedField, Field):
objects = mod._default_manager.in_bulk(pks)
if len(objects) != len(pks):
badkeys = [k for k in pks if k not in objects]
- raise validators.ValidationError, ungettext("Please enter valid %(self)s IDs. The value %(value)r is invalid.",
- "Please enter valid %(self)s IDs. The values %(value)r are invalid.", len(badkeys)) % {
+ raise exceptions.ValidationError(
+ ungettext("Please enter valid %(self)s IDs. The value %(value)r is invalid.",
+ "Please enter valid %(self)s IDs. The values %(value)r are invalid.",
+ len(badkeys)) % {
'self': self.verbose_name,
'value': len(badkeys) == 1 and badkeys[0] or tuple(badkeys),
- }
+ })
- def flatten_data(self, follow, obj = None):
- new_data = {}
+ def value_to_string(self, obj):
+ data = ''
if obj:
- instance_ids = [instance._get_pk_val() for instance in getattr(obj, self.name).all()]
- new_data[self.name] = instance_ids
+ qs = getattr(obj, self.name).all()
+ data = [instance._get_pk_val() for instance in qs]
else:
# In required many-to-many fields with only one available choice,
# select that one available choice.
- if not self.blank and not self.rel.edit_inline:
+ if not self.blank:
choices_list = self.get_choices_default()
if len(choices_list) == 1:
- new_data[self.name] = [choices_list[0][0]]
- return new_data
+ data = [choices_list[0][0]]
+ return smart_unicode(data)
def contribute_to_class(self, cls, name):
super(ManyToManyField, self).contribute_to_class(cls, name)