Django

Code

Changeset 6656

Show
Ignore:
Timestamp:
11/06/07 16:25:59 (1 year ago)
Author:
jkocherhans
Message:

newforms-admin: Merged to [6652]

Files:

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  
    10171017#: contrib/admin/views/main.py:780 
    10181018msgid "Database error" 
    1019 msgstr "Erorr en la base de datos" 
     1019msgstr "Error en la base de datos" 
    10201020 
    10211021#: contrib/auth/forms.py:17 
  • django/branches/newforms-admin/django/contrib/auth/forms.py

    r5828 r6656  
    105105                'user': user, 
    106106                } 
    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]) 
    108108 
    109109class PasswordChangeForm(oldforms.Manipulator): 
  • django/branches/newforms-admin/django/contrib/sessions/middleware.py

    r6613 r6656  
     1import time 
     2 
    13from django.conf import settings 
    24from django.utils.cache import patch_vary_headers 
    3 from email.Utils import formatdate 
    4 import datetime 
    5 import time 
     5from django.utils.http import cookie_date 
    66 
    77TEST_COOKIE_NAME = 'testcookie' 
     
    1111 
    1212    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) 
    1516 
    1617    def process_response(self, request, response): 
     
    3132                else: 
    3233                    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) 
    4036                # Save the seesion data and refresh the client cookie. 
    4137                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, LabelCommand 
    21import os 
    32 
     3from django.core.management.base import copy_helper, CommandError, LabelCommand 
     4 
    45class 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.") 
    68    args = "[appname]" 
    79    label = 'application name' 
     
    1517        if directory is None: 
    1618            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). 
    2122        project_name = os.path.basename(directory) 
    2223        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) 
    2527 
    2628class 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.") 
    2831 
    2932    def __init__(self, project_directory): 
  • django/branches/newforms-admin/django/core/management/__init__.py

    r6613 r6656  
    243243    Configures the runtime environment. This can also be used by external 
    244244    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). 
    245247    """ 
    246248    # 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  
    253253    pending_references = {} 
    254254    qn = connection.ops.quote_name 
     255    inline_references = connection.features.inline_fk_references 
    255256    for f in opts.fields: 
    256257        col_type = f.db_type() 
     
    273274            field_output.append(connection.ops.tablespace_sql(tablespace, inline=True)) 
    274275        if f.rel: 
    275             if f.rel.to in known_models: 
     276            if inline_references and f.rel.to in known_models: 
    276277                field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \ 
    277278                    style.SQL_TABLE(qn(f.rel.to._meta.db_table)) + ' (' + \ 
     
    342343    from django.db import connection, models 
    343344    from django.contrib.contenttypes import generic 
     345    from django.db.backends.util import truncate_name 
    344346 
    345347    opts = model._meta 
    346348    final_output = [] 
    347349    qn = connection.ops.quote_name 
     350    inline_references = connection.features.inline_fk_references 
    348351    for f in opts.many_to_many: 
    349352        if not isinstance(f.rel, generic.GenericRel): 
     
    355358            table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \ 
    356359                style.SQL_TABLE(qn(f.m2m_db_table())) + ' ('] 
    357             table_output.append('    %s %s %s%s,' % \ 
     360            table_output.append('    %s %s %s%s,' % 
    358361                (style.SQL_FIELD(qn('id')), 
    359362                style.SQL_COLTYPE(models.AutoField(primary_key=True).db_type()), 
    360363                style.SQL_KEYWORD('NOT NULL PRIMARY KEY'), 
    361364                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' % 
    377397                (style.SQL_KEYWORD('UNIQUE'), 
    378398                style.SQL_FIELD(qn(f.m2m_column_name())), 
     
    385405            table_output.append(';') 
    386406            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())) 
    387416 
    388417            # Add any extra SQL needed to support auto-incrementing PKs 
  • django/branches/newforms-admin/django/core/servers/basehttp.py

    r5828 r6656  
    1010from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
    1111from types import ListType, StringType 
    12 from email.Utils import formatdate 
    1312import mimetypes 
    1413import os 
    1514import re 
    1615import sys 
    17 import time 
    1816import urllib 
     17 
     18from django.utils.http import http_date 
    1919 
    2020__version__ = "0.1" 
     
    377377                if 'Date' not in self.headers: 
    378378                    self._write( 
    379                         'Date: %s\r\n' % (formatdate()[:26] + "GMT"
     379                        'Date: %s\r\n' % http_date(
    380380                    ) 
    381381                if self.server_software and 'Server' not in self.headers: 
  • django/branches/newforms-admin/django/db/backends/__init__.py

    r6613 r6656  
    4444    allows_unique_and_pk = True 
    4545    autoindexes_primary_keys = True 
     46    inline_fk_references = True 
    4647    needs_datetime_string_cast = True 
    4748    needs_upper_for_iops = False 
  • django/branches/newforms-admin/django/db/backends/mysql/base.py

    r6342 r6656  
    6262class DatabaseFeatures(BaseDatabaseFeatures): 
    6363    autoindexes_primary_keys = False 
     64    inline_fk_references = False 
    6465 
    6566class DatabaseOperations(BaseDatabaseOperations): 
  • django/branches/newforms-admin/django/db/backends/mysql_old/base.py

    r5984 r6656  
    6666class DatabaseFeatures(BaseDatabaseFeatures): 
    6767    autoindexes_primary_keys = False 
     68    inline_fk_references = False 
    6869 
    6970class DatabaseOperations(BaseDatabaseOperations): 
  • django/branches/newforms-admin/django/db/models/fields/__init__.py

    r6613 r6656  
    146146        data_types = get_creation_module().DATA_TYPES 
    147147        internal_type = self.get_internal_type() 
     148        if internal_type not in data_types: 
     149            return None 
    148150        return data_types[internal_type] % self.__dict__ 
    149151 
  • django/branches/newforms-admin/django/db/models/__init__.py

    r5984 r6656  
    88from django.db.models.base import Model 
    99from django.db.models.fields import * 
     10from django.db.models.fields.subclassing import SubfieldBase 
    1011from django.db.models.fields.related import ForeignKey, OneToOneField, ManyToManyField, ManyToOneRel, ManyToManyRel, OneToOneRel, TABULAR, STACKED 
    1112from django.db.models import signals 
  • django/branches/newforms-admin/django/middleware/http.py

    r6417 r6656  
    1 from email.Utils import formatdate 
     1from django.utils.http import http_date 
    22 
    33class ConditionalGetMiddleware(object): 
     
    1212    """ 
    1313    def process_response(self, request, response): 
    14         response['Date'] = formatdate()[:26] + "GMT" 
     14        response['Date'] = http_date() 
    1515        if not response.has_header('Content-Length'): 
    1616            response['Content-Length'] = str(len(response.content)) 
     
    2424 
    2525        if response.has_header('Last-Modified'): 
    26             last_mod = response['Last-Modified'] 
    2726            if_modified_since = request.META.get('HTTP_IF_MODIFIED_SINCE', None) 
    2827            if if_modified_since == response['Last-Modified']: 
  • django/branches/newforms-admin/django/newforms/fields.py

    <
    r6613 r6656  
    11""" 
    2 Field classes 
     2Field classes. 
    33""" 
    44 
     
    77import re 
    88import 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 
    1610try: 
    1711    from decimal import Decimal, DecimalException 
    1812except ImportError: 
    1913    from django.utils._decimal import Decimal, DecimalException 
     14try: 
     15    set 
     16except NameError: 
     17    from sets import Set as set 
     18 
     19from django.utils.translation import ugettext_lazy as _ 
     20from django.utils.encoding import StrAndUnicode, smart_unicode 
     21 
     22from util import ErrorList, ValidationError 
     23from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput 
     24 
    2025 
    2126__all__ = ( 
     
    2429    'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 
    2530    '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', 
    2833    'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 
    2934    'SplitDateTimeField', 'IPAddressField', 
     
    3338EMPTY_VALUES = (None, '') 
    3439 
    35 try: 
    36     set 
    37 except NameError: 
    38     from sets import Set as set   # Python 2.3 fallback 
    39  
    40 try: 
    41     from decimal import Decimal 
    42 except ImportError: 
    43     from django.utils._decimal import Decimal   # Python 2.3 fallback 
    4440 
    4541class Field(object): 
    4642    widget = TextInput # Default widget to use when rendering this type of Field. 
    4743    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    } 
    4848 
    4949    # Tracks each time a Field instance is created. Used to retain order. 
    5050    creation_counter = 0 
    5151 
    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): 
    5354        # required -- Boolean that specifies whether the field is required. 
    5455        #             True by default. 
     
    8384        Field.creation_counter += 1 
    8485 
     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 
    85102    def clean(self, value): 
    86103        """ 
     
    91108        """ 
    92109        if self.required and value in EMPTY_VALUES: 
    93             raise ValidationError(ugettext(u'This field is required.')
     110            raise ValidationError(self.error_messages['required']
    94111        return value 
    95112 
     
    109126 
    110127class 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 
    111133    def __init__(self, max_length=None, min_length=None, *args, **kwargs): 
    112134        self.max_length, self.min_length = max_length, min_length 
     
    121143        value_length = len(value) 
    122144        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}) 
    124146        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}) 
    126148        return value 
    127149 
     
    132154 
    133155class 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 
    134162    def __init__(self, max_value=None, min_value=None, *args, **kwargs): 
    135163        self.max_value, self.min_value = max_value, min_value 
     
    147175            value = int(str(value)) 
    148176        except (ValueError, TypeError): 
    149             raise ValidationError(ugettext(u'Enter a whole number.')
     177            raise ValidationError(self.error_messages['invalid']
    150178        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) 
    152180        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) 
    154182        return value 
    155183 
    156184class 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 
    157191    def __init__(self, max_value=None, min_value=None, *args, **kwargs): 
    158192        self.max_value, self.min_value = max_value, min_value 
     
    170204            value = float(value) 
    171205        except (ValueError, TypeError): 
    172             raise ValidationError(ugettext('Enter a number.')
     206            raise ValidationError(self.error_messages['invalid']
    173207        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) 
    175209        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) 
    177211        return value 
    178212 
    179213class 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 
    180223    def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, *args, **kwargs): 
    181224        self.max_value, self.min_value = max_value, min_value 
     
    197240            value = Decimal(value) 
    198241        except DecimalException: 
    199             raise ValidationError(ugettext('Enter a number.')
     242            raise ValidationError(self.error_messages['invalid']
    200243        pieces = str(value).lstrip("-").split('.') 
    201244        decimals = (len(pieces) == 2) and len(pieces[1]) or 0 
    202245        digits = len(pieces[0]) 
    203246        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) 
    205248        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) 
    207250        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) 
    209252        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) 
    211254        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)) 
    213256        return value 
    214257 
     
    222265 
    223266class DateField(Field): 
     267    default_error_messages = { 
     268        'invalid': _(u'Enter a valid date.'), 
     269    } 
     270 
    224271    def __init__(self, input_formats=None, *args, **kwargs): 
    225272        super(DateField, self).__init__(*args, **kwargs) 
     
    243290            except ValueError: 
    244291                continue 
    245         raise ValidationError(ugettext(u'Enter a valid date.')
     292        raise ValidationError(self.error_messages['invalid']
    246293 
    247294DEFAULT_TIME_INPUT_FORMATS = ( 
     
    251298 
    252299class TimeField(Field): 
     300    default_error_messages = { 
     301        'invalid': _(u'Enter a valid time.') 
     302    } 
     303 
    253304    def __init__(self, input_formats=None, *args, **kwargs): 
    254305        super(TimeField, self).__init__(*args, **kwargs) 
     
    270321            except ValueError: 
    271322                continue 
    272         raise ValidationError(ugettext(u'Enter a valid time.')
     323        raise ValidationError(self.error_messages['invalid']
    273324 
    274325DEFAULT_DATETIME_INPUT_FORMATS = ( 
     
    286337class DateTimeField(Field): 
    287338    widget = DateTimeInput 
     339    default_error_messages = { 
     340        'invalid': _(u'Enter a valid date/time.'), 
     341    } 
    288342 
    289343    def __init__(self, input_formats=None, *args, **kwargs): 
     
    307361            # components: date and time. 
    308362            if len(value) != 2: 
    309                 raise ValidationError(ugettext(u'Enter a valid date/time.')
     363                raise ValidationError(self.error_messages['invalid']
    310364            value = '%s %s' % tuple(value) 
    311365        for format in self.input_formats: 
     
    314368            except ValueError: 
    315369                continue 
    316         raise ValidationError(ugettext(u'Enter a valid date/time.')
     370        raise ValidationError(self.error_messages['invalid']
    317371 
    318372class RegexField(CharField): 
     
    323377        'Enter a valid value' is too generic for you. 
    324378        """ 
     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 
    325384        super(RegexField, self).__init__(max_length, min_length, *args, **kwargs) 
    326385        if isinstance(regex, basestring): 
    327386            regex = re.compile(regex) 
    328387        self.regex = regex 
    329         self.error_message = error_message or ugettext(u'Enter a valid value.') 
    330388 
    331389    def clean(self, value): 
     
    338396            return value 
    339397        if not self.regex.search(value): 
    340             raise ValidationError(self.error_message
     398            raise ValidationError(self.error_messages['invalid']
    341399        return value 
    342400 
     
    347405 
    348406class EmailField(RegexField): 
     407    default_error_messages = { 
     408        'invalid': _(u'Enter a valid e-mail address.'), 
     409    } 
     410 
    349411    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) 
    352414 
    353415try: 
     
    373435class FileField(Field): 
    374436    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 
    375443    def __init__(self, *args, **kwargs): 
    376444        super(FileField, self).__init__(*args, **kwargs) 
     
    383451            f = UploadedFile(data['filename'], data['content']) 
    384452        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']
    386454        except KeyError: 
    387             raise ValidationError(ugettext(u"No file was submitted.")
     455            raise ValidationError(self.error_messages['missing']
    388456        if not f.content: 
    389             raise ValidationError(ugettext(u"The submitted file is empty.")
     457            raise ValidationError(self.error_messages['empty']
    390458        return f 
    391459 
    392460class 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 
    393465    def clean(self, data): 
    394466        """ 
     
    411483            trial_image.verify() 
    412484        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']
    414486        return f 
    415487 
     
    423495 
    424496class 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 
    425502    def __init__(self, max_length=None, min_length=None, verify_exists=False, 
    426503            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) 
    428506        self.verify_exists = verify_exists 
    429507        self.user_agent = validator_user_agent 
     
    450528                u = urllib2.urlopen(req) 
    451529            except ValueError: 
    452                 raise ValidationError(ugettext(u'Enter a valid URL.')
     530                raise ValidationError(self.error_messages['invalid']
    453531            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']
    455533        return value 
    456534 
     
    479557class ChoiceField(Field): 
    480558    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) 
    484567        self.choices = choices 
    485568 
     
    507590        valid_values = set([smart_unicode(k) for k, v in self.choices]) 
    508591        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}
    510593        return value 
    511594