Changeset 6656
- Timestamp:
- 11/06/07 16:25:59 (1 year ago)
- Files:
-
- django/branches/newforms-admin (modified) (1 prop)
- django/branches/newforms-admin/django/conf/locale/es/LC_MESSAGES/django.mo (modified) (previous)
- django/branches/newforms-admin/django/conf/locale/es/LC_MESSAGES/django.po (modified) (1 diff)
- django/branches/newforms-admin/django/contrib/auth/forms.py (modified) (1 diff)
- django/branches/newforms-admin/django/contrib/sessions/middleware.py (modified) (3 diffs)
- django/branches/newforms-admin/django/core/management/commands/startapp.py (modified) (2 diffs)
- django/branches/newforms-admin/django/core/management/__init__.py (modified) (1 diff)
- django/branches/newforms-admin/django/core/management/sql.py (modified) (5 diffs)
- django/branches/newforms-admin/django/core/servers/basehttp.py (modified) (2 diffs)
- django/branches/newforms-admin/django/db/backends/__init__.py (modified) (1 diff)
- django/branches/newforms-admin/django/db/backends/mysql/base.py (modified) (1 diff)
- django/branches/newforms-admin/django/db/backends/mysql_old/base.py (modified) (1 diff)
- django/branches/newforms-admin/django/db/models/fields/__init__.py (modified) (1 diff)
- django/branches/newforms-admin/django/db/models/fields/subclassing.py (copied) (copied from django/trunk/django/db/models/fields/subclassing.py)
- django/branches/newforms-admin/django/db/models/__init__.py (modified) (1 diff)
- django/branches/newforms-admin/django/middleware/http.py (modified) (3 diffs)
- django/branches/newforms-admin/django/newforms/fields.py (modified) (38 diffs)
- django/branches/newforms-admin/django/newforms/models.py (modified) (11 diffs)
- django/branches/newforms-admin/django/newforms/util.py (modified) (2 diffs)
- django/branches/newforms-admin/django/template/defaultfilters.py (modified) (38 diffs)
- django/branches/newforms-admin/django/template/defaulttags.py (modified) (46 diffs)
- django/branches/newforms-admin/django/test/testcases.py (modified) (1 diff)
- django/branches/newforms-admin/django/utils/cache.py (modified) (9 diffs)
- django/branches/newforms-admin/django/utils/dateformat.py (modified) (1 diff)
- django/branches/newforms-admin/django/utils/encoding.py (modified) (2 diffs)
- django/branches/newforms-admin/django/utils/http.py (modified) (2 diffs)
- django/branches/newforms-admin/django/views/static.py (modified) (3 diffs)
- django/branches/newforms-admin/docs/cache.txt (modified) (1 diff)
- django/branches/newforms-admin/docs/custom_model_fields.txt (copied) (copied from django/trunk/docs/custom_model_fields.txt)
- django/branches/newforms-admin/docs/email.txt (modified) (1 diff)
- django/branches/newforms-admin/docs/form_preview.txt (modified) (1 diff)
- django/branches/newforms-admin/docs/model-api.txt (modified) (1 diff)
- django/branches/newforms-admin/docs/modpython.txt (modified) (1 diff)
- django/branches/newforms-admin/docs/newforms.txt (modified) (17 diffs)
- django/branches/newforms-admin/docs/serialization.txt (modified) (4 diffs)
- django/branches/newforms-admin/docs/templates.txt (modified) (2 diffs)
- django/branches/newforms-admin/docs/testing.txt (modified) (1 diff)
- django/branches/newforms-admin/tests/modeltests/field_subclassing (copied) (copied from django/trunk/tests/modeltests/field_subclassing)
- django/branches/newforms-admin/tests/modeltests/field_subclassing/__init__.py (copied) (copied from django/trunk/tests/modeltests/field_subclassing/__init__.py)
- django/branches/newforms-admin/tests/modeltests/field_subclassing/models.py (copied) (copied from django/trunk/tests/modeltests/field_subclassing/models.py)
- django/branches/newforms-admin/tests/regressiontests/defaultfilters/tests.py (modified) (1 diff)
- django/branches/newforms-admin/tests/regressiontests/forms/error_messages.py (copied) (copied from django/trunk/tests/regressiontests/forms/error_messages.py)
- django/branches/newforms-admin/tests/regressiontests/forms/extra.py (modified) (2 diffs)
- django/branches/newforms-admin/tests/regressiontests/forms/regressions.py (modified) (1 diff)
- django/branches/newforms-admin/tests/regressiontests/forms/tests.py (modified) (2 diffs)
- django/branches/newforms-admin/tests/regressiontests/forms/util.py (modified) (1 diff)
- django/branches/newforms-admin/tests/regressiontests/templates/urls.py (modified) (1 diff)
- django/branches/newforms-admin/tests/regressiontests/text/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/newforms-admin
- Property svnmerge-integrated changed from /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-6612 to /django/trunk:1-4345,4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-6390,6392-6655
django/branches/newforms-admin/django/conf/locale/es/LC_MESSAGES/django.po
r6613 r6656 1017 1017 #: contrib/admin/views/main.py:780 1018 1018 msgid "Database error" 1019 msgstr "Er orr en la base de datos"1019 msgstr "Error en la base de datos" 1020 1020 1021 1021 #: contrib/auth/forms.py:17 django/branches/newforms-admin/django/contrib/auth/forms.py
r5828 r6656 105 105 'user': user, 106 106 } 107 send_mail( 'Password reset on %s'% site_name, t.render(Context(c)), None, [user.email])107 send_mail(_('Password reset on %s') % site_name, t.render(Context(c)), None, [user.email]) 108 108 109 109 class PasswordChangeForm(oldforms.Manipulator): django/branches/newforms-admin/django/contrib/sessions/middleware.py
r6613 r6656 1 import time 2 1 3 from django.conf import settings 2 4 from django.utils.cache import patch_vary_headers 3 from email.Utils import formatdate 4 import datetime 5 import time 5 from django.utils.http import cookie_date 6 6 7 7 TEST_COOKIE_NAME = 'testcookie' … … 11 11 12 12 def process_request(self, request): 13 engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) 14 request.session = engine.SessionStore(request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)) 13 engine = __import__(settings.SESSION_ENGINE, {}, {}, ['']) 14 session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None) 15 request.session = engine.SessionStore(session_key) 15 16 16 17 def process_response(self, request, response): … … 31 32 else: 32 33 max_age = settings.SESSION_COOKIE_AGE 33 rfcdate = formatdate(time.time() + settings.SESSION_COOKIE_AGE) 34 35 # Fixed length date must have '-' separation in the format 36 # DD-MMM-YYYY for compliance with Netscape cookie standard 37 expires = datetime.datetime.strftime(datetime.datetime.utcnow() + \ 38 datetime.timedelta(seconds=settings.SESSION_COOKIE_AGE), "%a, %d-%b-%Y %H:%M:%S GMT") 39 34 expires_time = time.time() + settings.SESSION_COOKIE_AGE 35 expires = cookie_date(expires_time) 40 36 # Save the seesion data and refresh the client cookie. 41 37 request.session.save() django/branches/newforms-admin/django/core/management/commands/startapp.py
r6459 r6656 1 from django.core.management.base import copy_helper, CommandError, LabelCommand2 1 import os 3 2 3 from django.core.management.base import copy_helper, CommandError, LabelCommand 4 4 5 class Command(LabelCommand): 5 help = "Creates a Django app directory structure for the given app name in the current directory." 6 help = ("Creates a Django app directory structure for the given app name" 7 " in the current directory.") 6 8 args = "[appname]" 7 9 label = 'application name' … … 15 17 if directory is None: 16 18 directory = os.getcwd() 17 # Determine the project_name a bit naively -- by looking at the name of 18 # the parent directory. 19 project_dir = os.path.normpath(os.path.join(directory, os.pardir)) 20 parent_dir = os.path.basename(project_dir) 19 # Determine the project_name by using the basename of directory, 20 # which should be the full path of the project directory (or the 21 # current directory if no directory was passed). 21 22 project_name = os.path.basename(directory) 22 23 if app_name == project_name: 23 raise CommandError("You cannot create an app with the same name (%r) as your project." % app_name) 24 copy_helper(self.style, 'app', app_name, directory, parent_dir) 24 raise CommandError("You cannot create an app with the same name" 25 " (%r) as your project." % app_name) 26 copy_helper(self.style, 'app', app_name, directory, project_name) 25 27 26 28 class ProjectCommand(Command): 27 help = "Creates a Django app directory structure for the given app name in this project's directory." 29 help = ("Creates a Django app directory structure for the given app name" 30 " in this project's directory.") 28 31 29 32 def __init__(self, project_directory): django/branches/newforms-admin/django/core/management/__init__.py
r6613 r6656 243 243 Configures the runtime environment. This can also be used by external 244 244 scripts wanting to set up a similar environment to manage.py. 245 Returns the project directory (assuming the passed settings module is 246 directly in the project directory). 245 247 """ 246 248 # Add this project to sys.path so that it's importable in the conventional django/branches/newforms-admin/django/core/management/sql.py
r6342 r6656 253 253 pending_references = {} 254 254 qn = connection.ops.quote_name 255 inline_references = connection.features.inline_fk_references 255 256 for f in opts.fields: 256 257 col_type = f.db_type() … … 273 274 field_output.append(connection.ops.tablespace_sql(tablespace, inline=True)) 274 275 if f.rel: 275 if f.rel.to in known_models:276 if inline_references and f.rel.to in known_models: 276 277 field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 277 278 style.SQL_TABLE(qn(f.rel.to._meta.db_table)) + ' (' + \ … … 342 343 from django.db import connection, models 343 344 from django.contrib.contenttypes import generic 345 from django.db.backends.util import truncate_name 344 346 345 347 opts = model._meta 346 348 final_output = [] 347 349 qn = connection.ops.quote_name 350 inline_references = connection.features.inline_fk_references 348 351 for f in opts.many_to_many: 349 352 if not isinstance(f.rel, generic.GenericRel): … … 355 358 table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 356 359 style.SQL_TABLE(qn(f.m2m_db_table())) + ' ('] 357 table_output.append(' %s %s %s%s,' % \360 table_output.append(' %s %s %s%s,' % 358 361 (style.SQL_FIELD(qn('id')), 359 362 style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), 360 363 style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), 361 364 tablespace_sql)) 362 table_output.append(' %s %s %s %s (%s)%s,' % \ 363 (style.SQL_FIELD(qn(f.m2m_column_name())), 364 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 365 style.SQL_KEYWORD('NOT NULL REFERENCES'), 366 style.SQL_TABLE(qn(opts.db_table)), 367 style.SQL_FIELD(qn(opts.pk.column)), 368 connection.ops.deferrable_sql())) 369 table_output.append(' %s %s %s %s (%s)%s,' % \ 370 (style.SQL_FIELD(qn(f.m2m_reverse_name())), 371 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 372 style.SQL_KEYWORD('NOT NULL REFERENCES'), 373 style.SQL_TABLE(qn(f.rel.to._meta.db_table)), 374 style.SQL_FIELD(qn(f.rel.to._meta.pk.column)), 375 connection.ops.deferrable_sql())) 376 table_output.append(' %s (%s, %s)%s' % \ 365 if inline_references: 366 deferred = [] 367 table_output.append(' %s %s %s %s (%s)%s,' % 368 (style.SQL_FIELD(qn(f.m2m_column_name())), 369 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 370 style.SQL_KEYWORD('NOT NULL REFERENCES'), 371 style.SQL_TABLE(qn(opts.db_table)), 372 style.SQL_FIELD(qn(opts.pk.column)), 373 connection.ops.deferrable_sql())) 374 table_output.append(' %s %s %s %s (%s)%s,' % 375 (style.SQL_FIELD(qn(f.m2m_reverse_name())), 376 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 377 style.SQL_KEYWORD('NOT NULL REFERENCES'), 378 style.SQL_TABLE(qn(f.rel.to._meta.db_table)), 379 style.SQL_FIELD(qn(f.rel.to._meta.pk.column)), 380 connection.ops.deferrable_sql())) 381 else: 382 table_output.append(' %s %s %s,' % 383 (style.SQL_FIELD(qn(f.m2m_column_name())), 384 style.SQL_COLTYPE(models.ForeignKey(model).db_type()), 385 style.SQL_KEYWORD('NOT NULL'))) 386 table_output.append(' %s %s %s,' % 387 (style.SQL_FIELD(qn(f.m2m_reverse_name())), 388 style.SQL_COLTYPE(models.ForeignKey(f.rel.to).db_type()), 389 style.SQL_KEYWORD('NOT NULL'))) 390 deferred = [ 391 (f.m2m_db_table(), f.m2m_column_name(), opts.db_table, 392 opts.pk.column), 393 ( f.m2m_db_table(), f.m2m_reverse_name(), 394 f.rel.to._meta.db_table, f.rel.to._meta.pk.column) 395 ] 396 table_output.append(' %s (%s, %s)%s' % 377 397 (style.SQL_KEYWORD('UNIQUE'), 378 398 style.SQL_FIELD(qn(f.m2m_column_name())), … … 385 405 table_output.append(';') 386 406 final_output.append('\n'.join(table_output)) 407 408 for r_table, r_col, table, col in deferred: 409 r_name = '%s_refs_%s_%x' % (r_col, col, 410 abs(hash((r_table, table)))) 411 final_output.append(style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)%s;' % 412 (qn(r_table), 413 truncate_name(r_name, connection.ops.max_name_length()), 414 qn(r_col), qn(table), qn(col), 415 connection.ops.deferrable_sql())) 387 416 388 417 # Add any extra SQL needed to support auto-incrementing PKs django/branches/newforms-admin/django/core/servers/basehttp.py
r5828 r6656 10 10 from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 11 11 from types import ListType, StringType 12 from email.Utils import formatdate13 12 import mimetypes 14 13 import os 15 14 import re 16 15 import sys 17 import time18 16 import urllib 17 18 from django.utils.http import http_date 19 19 20 20 __version__ = "0.1" … … 377 377 if 'Date' not in self.headers: 378 378 self._write( 379 'Date: %s\r\n' % (formatdate()[:26] + "GMT")379 'Date: %s\r\n' % http_date() 380 380 ) 381 381 if self.server_software and 'Server' not in self.headers: django/branches/newforms-admin/django/db/backends/__init__.py
r6613 r6656 44 44 allows_unique_and_pk = True 45 45 autoindexes_primary_keys = True 46 inline_fk_references = True 46 47 needs_datetime_string_cast = True 47 48 needs_upper_for_iops = False django/branches/newforms-admin/django/db/backends/mysql/base.py
r6342 r6656 62 62 class DatabaseFeatures(BaseDatabaseFeatures): 63 63 autoindexes_primary_keys = False 64 inline_fk_references = False 64 65 65 66 class DatabaseOperations(BaseDatabaseOperations): django/branches/newforms-admin/django/db/backends/mysql_old/base.py
r5984 r6656 66 66 class DatabaseFeatures(BaseDatabaseFeatures): 67 67 autoindexes_primary_keys = False 68 inline_fk_references = False 68 69 69 70 class DatabaseOperations(BaseDatabaseOperations): django/branches/newforms-admin/django/db/models/fields/__init__.py
r6613 r6656 146 146 data_types = get_creation_module().DATA_TYPES 147 147 internal_type = self.get_internal_type() 148 if internal_type not in data_types: 149 return None 148 150 return data_types[internal_type] % self.__dict__ 149 151 django/branches/newforms-admin/django/db/models/__init__.py
r5984 r6656 8 8 from django.db.models.base import Model 9 9 from django.db.models.fields import * 10 from django.db.models.fields.subclassing import SubfieldBase 10 11 from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED 11 12 from django.db.models import signals django/branches/newforms-admin/django/middleware/http.py
r6417 r6656 1 from email.Utils import formatdate1 from django.utils.http import http_date 2 2 3 3 class ConditionalGetMiddleware(object): … … 12 12 """ 13 13 def process_response(self, request, response): 14 response['Date'] = formatdate()[:26] + "GMT"14 response['Date'] = http_date() 15 15 if not response.has_header('Content-Length'): 16 16 response['Content-Length'] = str(len(response.content)) … … 24 24 25 25 if response.has_header('Last-Modified'): 26 last_mod = response['Last-Modified']27 26 if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None) 28 27 if if_modified_since == response['Last-Modified']: django/branches/newforms-admin/django/newforms/fields.py
r6613 r6656 1 1 """ 2 Field classes 2 Field classes. 3 3 """ 4 4 … … 7 7 import re 8 8 import time 9 10 from django.utils.translation import ugettext 11 from django.utils.encoding import StrAndUnicode, smart_unicode 12 13 from util import ErrorList, ValidationError 14 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput 15 9 # Python 2.3 fallbacks 16 10 try: 17 11 from decimal import Decimal, DecimalException 18 12 except ImportError: 19 13 from django.utils._decimal import Decimal, DecimalException 14 try: 15 set 16 except NameError: 17 from sets import Set as set 18 19 from django.utils.translation import ugettext_lazy as _ 20 from django.utils.encoding import StrAndUnicode, smart_unicode 21 22 from util import ErrorList, ValidationError 23 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput 24 20 25 21 26 __all__ = ( … … 24 29 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 25 30 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', 26 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField',27 ' ChoiceField', 'NullBooleanField', 'MultipleChoiceField',31 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 32 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 28 33 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 29 34 'SplitDateTimeField', 'IPAddressField', … … 33 38 EMPTY_VALUES = (None, '') 34 39 35 try:36 set37 except NameError:38 from sets import Set as set # Python 2.3 fallback39 40 try:41 from decimal import Decimal42 except ImportError:43 from django.utils._decimal import Decimal # Python 2.3 fallback44 40 45 41 class Field(object): 46 42 widget = TextInput # Default widget to use when rendering this type of Field. 47 43 hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden". 44 default_error_messages = { 45 'required': _(u'This field is required.'), 46 'invalid': _(u'Enter a valid value.'), 47 } 48 48 49 49 # Tracks each time a Field instance is created. Used to retain order. 50 50 creation_counter = 0 51 51 52 def __init__(self, required=True, widget=None, label=None, initial=None, help_text=None): 52 def __init__(self, required=True, widget=None, label=None, initial=None, 53 help_text=None, error_messages=None): 53 54 # required -- Boolean that specifies whether the field is required. 54 55 # True by default. … … 83 84 Field.creation_counter += 1 84 85 86 self.error_messages = self._build_error_messages(error_messages) 87 88 def _build_error_messages(self, extra_error_messages): 89 error_messages = {} 90 91 def get_default_error_messages(klass): 92 for base_class in klass.__bases__: 93 get_default_error_messages(base_class) 94 if hasattr(klass, 'default_error_messages'): 95 error_messages.update(klass.default_error_messages) 96 97 get_default_error_messages(self.__class__) 98 if extra_error_messages: 99 error_messages.update(extra_error_messages) 100 return error_messages 101 85 102 def clean(self, value): 86 103 """ … … 91 108 """ 92 109 if self.required and value in EMPTY_VALUES: 93 raise ValidationError( ugettext(u'This field is required.'))110 raise ValidationError(self.error_messages['required']) 94 111 return value 95 112 … … 109 126 110 127 class CharField(Field): 128 default_error_messages = { 129 'max_length': _(u'Ensure this value has at most %(max)d characters (it has %(length)d).'), 130 'min_length': _(u'Ensure this value has at least %(min)d characters (it has %(length)d).'), 131 } 132 111 133 def __init__(self, max_length=None, min_length=None, *args, **kwargs): 112 134 self.max_length, self.min_length = max_length, min_length … … 121 143 value_length = len(value) 122 144 if self.max_length is not None and value_length > self.max_length: 123 raise ValidationError( ugettext(u'Ensure this value has at most %(max)d characters (it has %(length)d).')% {'max': self.max_length, 'length': value_length})145 raise ValidationError(self.error_messages['max_length'] % {'max': self.max_length, 'length': value_length}) 124 146 if self.min_length is not None and value_length < self.min_length: 125 raise ValidationError( ugettext(u'Ensure this value has at least %(min)d characters (it has %(length)d).')% {'min': self.min_length, 'length': value_length})147 raise ValidationError(self.error_messages['min_length'] % {'min': self.min_length, 'length': value_length}) 126 148 return value 127 149 … … 132 154 133 155 class IntegerField(Field): 156 default_error_messages = { 157 'invalid': _(u'Enter a whole number.'), 158 'max_value': _(u'Ensure this value is less than or equal to %s.'), 159 'min_value': _(u'Ensure this value is greater than or equal to %s.'), 160 } 161 134 162 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 135 163 self.max_value, self.min_value = max_value, min_value … … 147 175 value = int(str(value)) 148 176 except (ValueError, TypeError): 149 raise ValidationError( ugettext(u'Enter a whole number.'))177 raise ValidationError(self.error_messages['invalid']) 150 178 if self.max_value is not None and value > self.max_value: 151 raise ValidationError( ugettext(u'Ensure this value is less than or equal to %s.')% self.max_value)179 raise ValidationError(self.error_messages['max_value'] % self.max_value) 152 180 if self.min_value is not None and value < self.min_value: 153 raise ValidationError( ugettext(u'Ensure this value is greater than or equal to %s.')% self.min_value)181 raise ValidationError(self.error_messages['min_value'] % self.min_value) 154 182 return value 155 183 156 184 class FloatField(Field): 185 default_error_messages = { 186 'invalid': _(u'Enter a number.'), 187 'max_value': _(u'Ensure this value is less than or equal to %s.'), 188 'min_value': _(u'Ensure this value is greater than or equal to %s.'), 189 } 190 157 191 def __init__(self, max_value=None, min_value=None, *args, **kwargs): 158 192 self.max_value, self.min_value = max_value, min_value … … 170 204 value = float(value) 171 205 except (ValueError, TypeError): 172 raise ValidationError( ugettext('Enter a number.'))206 raise ValidationError(self.error_messages['invalid']) 173 207 if self.max_value is not None and value > self.max_value: 174 raise ValidationError( ugettext('Ensure this value is less than or equal to %s.')% self.max_value)208 raise ValidationError(self.error_messages['max_value'] % self.max_value) 175 209 if self.min_value is not None and value < self.min_value: 176 raise ValidationError( ugettext('Ensure this value is greater than or equal to %s.')% self.min_value)210 raise ValidationError(self.error_messages['min_value'] % self.min_value) 177 211 return value 178 212 179 213 class DecimalField(Field): 214 default_error_messages = { 215 'invalid': _(u'Enter a number.'), 216 'max_value': _(u'Ensure this value is less than or equal to %s.'), 217 'min_value': _(u'Ensure this value is greater than or equal to %s.'), 218 'max_digits': _('Ensure that there are no more than %s digits in total.'), 219 'max_decimal_places': _('Ensure that there are no more than %s decimal places.'), 220 'max_whole_digits': _('Ensure that there are no more than %s digits before the decimal point.') 221 } 222 180 223 def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 181 224 self.max_value, self.min_value = max_value, min_value … … 197 240 value = Decimal(value) 198 241 except DecimalException: 199 raise ValidationError( ugettext('Enter a number.'))242 raise ValidationError(self.error_messages['invalid']) 200 243 pieces = str(value).lstrip("-").split('.') 201 244 decimals = (len(pieces) == 2) and len(pieces[1]) or 0 202 245 digits = len(pieces[0]) 203 246 if self.max_value is not None and value > self.max_value: 204 raise ValidationError( ugettext('Ensure this value is less than or equal to %s.')% self.max_value)247 raise ValidationError(self.error_messages['max_value'] % self.max_value) 205 248 if self.min_value is not None and value < self.min_value: 206 raise ValidationError( ugettext('Ensure this value is greater than or equal to %s.')% self.min_value)249 raise ValidationError(self.error_messages['min_value'] % self.min_value) 207 250 if self.max_digits is not None and (digits + decimals) > self.max_digits: 208 raise ValidationError( ugettext('Ensure that there are no more than %s digits in total.')% self.max_digits)251 raise ValidationError(self.error_messages['max_digits'] % self.max_digits) 209 252 if self.decimal_places is not None and decimals > self.decimal_places: 210 raise ValidationError( ugettext('Ensure that there are no more than %s decimal places.')% self.decimal_places)253 raise ValidationError(self.error_messages['max_decimal_places'] % self.decimal_places) 211 254 if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places): 212 raise ValidationError( ugettext('Ensure that there are no more than %s digits before the decimal point.')% (self.max_digits - self.decimal_places))255 raise ValidationError(self.error_messages['max_whole_digits'] % (self.max_digits - self.decimal_places)) 213 256 return value 214 257 … … 222 265 223 266 class DateField(Field): 267 default_error_messages = { 268 'invalid': _(u'Enter a valid date.'), 269 } 270 224 271 def __init__(self, input_formats=None, *args, **kwargs): 225 272 super(DateField, self).__init__(*args, **kwargs) … … 243 290 except ValueError: 244 291 continue 245 raise ValidationError( ugettext(u'Enter a valid date.'))292 raise ValidationError(self.error_messages['invalid']) 246 293 247 294 DEFAULT_TIME_INPUT_FORMATS = ( … … 251 298 252 299 class TimeField(Field): 300 default_error_messages = { 301 'invalid': _(u'Enter a valid time.') 302 } 303 253 304 def __init__(self, input_formats=None, *args, **kwargs): 254 305 super(TimeField, self).__init__(*args, **kwargs) … … 270 321 except ValueError: 271 322 continue 272 raise ValidationError( ugettext(u'Enter a valid time.'))323 raise ValidationError(self.error_messages['invalid']) 273 324 274 325 DEFAULT_DATETIME_INPUT_FORMATS = ( … … 286 337 class DateTimeField(Field): 287 338 widget = DateTimeInput 339 default_error_messages = { 340 'invalid': _(u'Enter a valid date/time.'), 341 } 288 342 289 343 def __init__(self, input_formats=None, *args, **kwargs): … … 307 361 # components: date and time. 308 362 if len(value) != 2: 309 raise ValidationError( ugettext(u'Enter a valid date/time.'))363 raise ValidationError(self.error_messages['invalid']) 310 364 value = '%s %s' % tuple(value) 311 365 for format in self.input_formats: … … 314 368 except ValueError: 315 369 continue 316 raise ValidationError( ugettext(u'Enter a valid date/time.'))370 raise ValidationError(self.error_messages['invalid']) 317 371 318 372 class RegexField(CharField): … … 323 377 'Enter a valid value' is too generic for you. 324 378 """ 379 # error_message is just kept for backwards compatibility: 380 if error_message: 381 error_messages = kwargs.get('error_messages') or {} 382 error_messages['invalid'] = error_message 383 kwargs['error_messages'] = error_messages 325 384 super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) 326 385 if isinstance(regex, basestring): 327 386 regex = re.compile(regex) 328 387 self.regex = regex 329 self.error_message = error_message or ugettext(u'Enter a valid value.')330 388 331 389 def clean(self, value): … … 338 396 return value 339 397 if not self.regex.search(value): 340 raise ValidationError(self.error_message )398 raise ValidationError(self.error_messages['invalid']) 341 399 return value 342 400 … … 347 405 348 406 class EmailField(RegexField): 407 default_error_messages = { 408 'invalid': _(u'Enter a valid e-mail address.'), 409 } 410 349 411 def __init__(self, max_length=None, min_length=None, *args, **kwargs): 350 RegexField.__init__(self, email_re, max_length, min_length, 351 ugettext(u'Enter a valid e-mail address.'), *args,**kwargs)412 RegexField.__init__(self, email_re, max_length, min_length, *args, 413 **kwargs) 352 414 353 415 try: … … 373 435 class FileField(Field): 374 436 widget = FileInput 437 default_error_messages = { 438 'invalid': _(u"No file was submitted. Check the encoding type on the form."), 439 'missing': _(u"No file was submitted."), 440 'empty': _(u"The submitted file is empty."), 441 } 442 375 443 def __init__(self, *args, **kwargs): 376 444 super(FileField, self).__init__(*args, **kwargs) … … 383 451 f = UploadedFile(data['filename'], data['content']) 384 452 except TypeError: 385 raise ValidationError( ugettext(u"No file was submitted. Check the encoding type on the form."))453 raise ValidationError(self.error_messages['invalid']) 386 454 except KeyError: 387 raise ValidationError( ugettext(u"No file was submitted."))455 raise ValidationError(self.error_messages['missing']) 388 456 if not f.content: 389 raise ValidationError( ugettext(u"The submitted file is empty."))457 raise ValidationError(self.error_messages['empty']) 390 458 return f 391 459 392 460 class ImageField(FileField): 461 default_error_messages = { 462 'invalid_image': _(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."), 463 } 464 393 465 def clean(self, data): 394 466 """ … … 411 483 trial_image.verify() 412 484 except Exception: # Python Imaging Library doesn't recognize it as an image 413 raise ValidationError( ugettext(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."))485 raise ValidationError(self.error_messages['invalid_image']) 414 486 return f 415 487 … … 423 495 424 496 class URLField(RegexField): 497 default_error_messages = { 498 'invalid': _(u'Enter a valid URL.'), 499 'invalid_link': _(u'This URL appears to be a broken link.'), 500 } 501 425 502 def __init__(self, max_length=None, min_length=None, verify_exists=False, 426 503 validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs): 427 super(URLField, self).__init__(url_re, max_length, min_length, ugettext(u'Enter a valid URL.'), *args, **kwargs) 504 super(URLField, self).__init__(url_re, max_length, min_length, *args, 505 **kwargs) 428 506 self.verify_exists = verify_exists 429 507 self.user_agent = validator_user_agent … … 450 528 u = urllib2.urlopen(req) 451 529 except ValueError: 452 raise ValidationError( ugettext(u'Enter a valid URL.'))530 raise ValidationError(self.error_messages['invalid']) 453 531 except: # urllib2.URLError, httplib.InvalidURL, etc. 454 raise ValidationError( ugettext(u'This URL appears to be a broken link.'))532 raise ValidationError(self.error_messages['invalid_link']) 455 533 return value 456 534 … … 479 557 class ChoiceField(Field): 480 558 widget = Select 481 482 def __init__(self, choices=(), required=True, widget=None, label=None, initial=None, help_text=None): 483 super(ChoiceField, self).__init__(required, widget, label, initial, help_text) 559 default_error_messages = { 560 'invalid_choice': _(u'Select a valid choice. That choice is not one of the available choices.'), 561 } 562 563 def __init__(self, choices=(), required=True, widget=None, label=None, 564 initial=None, help_text=None, *args, **kwargs): 565 super(ChoiceField, self).__init__(required, widget, label, initial, 566 help_text, *args, **kwargs) 484 567 self.choices = choices 485 568 … … 507 590 valid_values = set([smart_unicode(k) for k, v in self.choices]) 508 591 if value not in valid_values: 509 raise ValidationError( ugettext(u'Select a valid choice. That choice is not one of the available choices.'))592 raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) 510 593 return value 511 594 … … <
