1. Luke Plant
  2. django

Commits

dand...@bcc190cf-cafb-0310-a4f2-bffc1f526a37  committed b9032b3

schema-evolution: update from HEAD (v5821)

  • Participants
  • Parent commits 9f3313b
  • Branches schema-evolution

Comments (0)

Files changed (111)

File AUTHORS

View file
  • Ignore whitespace
     Marty Alchin <gulopine@gamemusic.org>
     Daniel Alves Barbosa de Oliveira Vaz <danielvaz@gmail.com>
     AgarFu <heaven@croasanaso.sytes.net>
+    Derek Anderson <public@kered.org>
     Andreas
     andy@jadedplanet.net
     Fabrice Aneche <akh@nobugware.com>
     Maximillian Dornseif <md@hudora.de>
     Jeremy Dunck <http://dunck.us/>
     Andrew Durdin <adurdin@gmail.com>
+    dusk@woofle.net
     Andy Dustman <farcepest@gmail.com>
     Clint Ecker
     enlight

File django/contrib/admin/models.py

View file
  • Ignore whitespace
     user = models.ForeignKey(User)
     content_type = models.ForeignKey(ContentType, blank=True, null=True)
     object_id = models.TextField(_('object id'), blank=True, null=True)
-    object_repr = models.CharField(_('object repr'), maxlength=200)
+    object_repr = models.CharField(_('object repr'), max_length=200)
     action_flag = models.PositiveSmallIntegerField(_('action flag'))
     change_message = models.TextField(_('change message'), blank=True)
     objects = LogEntryManager()

File django/contrib/admin/templatetags/admin_modify.py

View file
  • Ignore whitespace
             t.append(u'document.getElementById("id_%s").onkeyup = function() {' \
                      ' var e = document.getElementById("id_%s");' \
                      ' if(!e._changed) { e.value = URLify(%s, %s);} }; ' % (
-                     f, field.name, add_values, field.maxlength))
+                     f, field.name, add_values, field.max_length))
     return u''.join(t)
 auto_populated_field_script = register.simple_tag(auto_populated_field_script)
 

File django/contrib/admin/views/doc.py

View file
  • Ignore whitespace
 DATA_TYPE_MAPPING = {
     'AutoField'                 : _('Integer'),
     'BooleanField'              : _('Boolean (Either True or False)'),
-    'CharField'                 : _('String (up to %(maxlength)s)'),
+    'CharField'                 : _('String (up to %(max_length)s)'),
     'CommaSeparatedIntegerField': _('Comma-separated integers'),
     'DateField'                 : _('Date (without time)'),
     'DateTimeField'             : _('Date (with time)'),
     'PhoneNumberField'          : _('Phone number'),
     'PositiveIntegerField'      : _('Integer'),
     'PositiveSmallIntegerField' : _('Integer'),
-    'SlugField'                 : _('String (up to %(maxlength)s)'),
+    'SlugField'                 : _('String (up to %(max_length)s)'),
     'SmallIntegerField'         : _('Integer'),
     'TextField'                 : _('Text'),
     'TimeField'                 : _('Time'),

File django/contrib/admin/views/main.py

View file
  • Ignore whitespace
                     try:
                         attr = getattr(lookup_opts.admin.manager.model, field_name)
                         order_field = attr.admin_order_field
-                    except IndexError:
+                    except AttributeError:
                         pass
                 else:
                     if not isinstance(f.rel, models.ManyToOneRel) or not f.null:

File django/contrib/auth/forms.py

View file
  • Ignore whitespace
     "A form that creates a user, with no privileges, from the given username and password."
     def __init__(self):
         self.fields = (
-            oldforms.TextField(field_name='username', length=30, maxlength=30, is_required=True,
+            oldforms.TextField(field_name='username', length=30, max_length=30, is_required=True,
                 validator_list=[validators.isAlphaNumeric, self.isValidUsername]),
-            oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
-            oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
+            oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
+            oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
                 validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
         )
 
         """
         self.request = request
         self.fields = [
-            oldforms.TextField(field_name="username", length=15, maxlength=30, is_required=True,
+            oldforms.TextField(field_name="username", length=15, max_length=30, is_required=True,
                 validator_list=[self.isValidUser, self.hasCookiesEnabled]),
-            oldforms.PasswordField(field_name="password", length=15, maxlength=30, is_required=True),
+            oldforms.PasswordField(field_name="password", length=15, max_length=30, is_required=True),
         ]
         self.user_cache = None
 
     def __init__(self, user):
         self.user = user
         self.fields = (
-            oldforms.PasswordField(field_name="old_password", length=30, maxlength=30, is_required=True,
+            oldforms.PasswordField(field_name="old_password", length=30, max_length=30, is_required=True,
                 validator_list=[self.isValidOldPassword]),
-            oldforms.PasswordField(field_name="new_password1", length=30, maxlength=30, is_required=True,
+            oldforms.PasswordField(field_name="new_password1", length=30, max_length=30, is_required=True,
                 validator_list=[validators.AlwaysMatchesOtherField('new_password2', _("The two 'new password' fields didn't match."))]),
-            oldforms.PasswordField(field_name="new_password2", length=30, maxlength=30, is_required=True),
+            oldforms.PasswordField(field_name="new_password2", length=30, max_length=30, is_required=True),
         )
 
     def isValidOldPassword(self, new_data, all_data):
     def __init__(self, user):
         self.user = user
         self.fields = (
-            oldforms.PasswordField(field_name='password1', length=30, maxlength=60, is_required=True),
-            oldforms.PasswordField(field_name='password2', length=30, maxlength=60, is_required=True,
+            oldforms.PasswordField(field_name='password1', length=30, max_length=60, is_required=True),
+            oldforms.PasswordField(field_name='password2', length=30, max_length=60, is_required=True,
                 validator_list=[validators.AlwaysMatchesOtherField('password1', _("The two password fields didn't match."))]),
         )
 

File django/contrib/auth/models.py

View file
  • Ignore whitespace
 
     Three basic permissions -- add, change and delete -- are automatically created for each Django model.
     """
-    name = models.CharField(_('name'), maxlength=50)
+    name = models.CharField(_('name'), max_length=50)
     content_type = models.ForeignKey(ContentType)
-    codename = models.CharField(_('codename'), maxlength=100)
+    codename = models.CharField(_('codename'), max_length=100)
 
     class Meta:
         verbose_name = _('permission')
 
     Beyond permissions, groups are a convenient way to categorize users to apply some label, or extended functionality, to them. For example, you could create a group 'Special users', and you could write code that would do special things to those users -- such as giving them access to a members-only portion of your site, or sending them members-only e-mail messages.
     """
-    name = models.CharField(_('name'), maxlength=80, unique=True)
+    name = models.CharField(_('name'), max_length=80, unique=True)
     permissions = models.ManyToManyField(Permission, verbose_name=_('permissions'), blank=True, filter_interface=models.HORIZONTAL)
 
     class Meta:
 
     Username and password are required. Other fields are optional.
     """
-    username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
-    first_name = models.CharField(_('first name'), maxlength=30, blank=True)
-    last_name = models.CharField(_('last name'), maxlength=30, blank=True)
+    username = models.CharField(_('username'), max_length=30, unique=True, validator_list=[validators.isAlphaNumeric], help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
+    first_name = models.CharField(_('first name'), max_length=30, blank=True)
+    last_name = models.CharField(_('last name'), max_length=30, blank=True)
     email = models.EmailField(_('e-mail address'), blank=True)
-    password = models.CharField(_('password'), maxlength=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
+    password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the <a href=\"password/\">change password form</a>."))
     is_staff = models.BooleanField(_('staff status'), default=False, help_text=_("Designates whether the user can log into this admin site."))
     is_active = models.BooleanField(_('active'), default=True, help_text=_("Designates whether this user can log into the Django admin. Unselect this instead of deleting accounts."))
     is_superuser = models.BooleanField(_('superuser status'), default=False, help_text=_("Designates that this user has all permissions without explicitly assigning them."))

File django/contrib/comments/models.py

View file
  • Ignore whitespace
     user = models.ForeignKey(User, raw_id_admin=True)
     content_type = models.ForeignKey(ContentType)
     object_id = models.IntegerField(_('object ID'))
-    headline = models.CharField(_('headline'), maxlength=255, blank=True)
-    comment = models.TextField(_('comment'), maxlength=3000)
+    headline = models.CharField(_('headline'), max_length=255, blank=True)
+    comment = models.TextField(_('comment'), max_length=3000)
     rating1 = models.PositiveSmallIntegerField(_('rating #1'), blank=True, null=True)
     rating2 = models.PositiveSmallIntegerField(_('rating #2'), blank=True, null=True)
     rating3 = models.PositiveSmallIntegerField(_('rating #3'), blank=True, null=True)
     # A FreeComment is a comment by a non-registered user.
     content_type = models.ForeignKey(ContentType)
     object_id = models.IntegerField(_('object ID'))
-    comment = models.TextField(_('comment'), maxlength=3000)
-    person_name = models.CharField(_("person's name"), maxlength=50)
+    comment = models.TextField(_('comment'), max_length=3000)
+    person_name = models.CharField(_("person's name"), max_length=50)
     submit_date = models.DateTimeField(_('date/time submitted'), auto_now_add=True)
     is_public = models.BooleanField(_('is public'))
     ip_address = models.IPAddressField(_('ip address'))

File django/contrib/comments/views/comments.py

View file
  • Ignore whitespace
             else:
                 return []
         self.fields.extend([
-            oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
+            oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
                 validator_list=[self.hasNoProfanities]),
             oldforms.RadioSelectField(field_name="rating1", choices=choices,
                 is_required=ratings_required and num_rating_choices > 0,
     "Manipulator that handles public free (unregistered) comments"
     def __init__(self):
         self.fields = (
-            oldforms.TextField(field_name="person_name", maxlength=50, is_required=True,
+            oldforms.TextField(field_name="person_name", max_length=50, is_required=True,
                 validator_list=[self.hasNoProfanities]),
-            oldforms.LargeTextField(field_name="comment", maxlength=3000, is_required=True,
+            oldforms.LargeTextField(field_name="comment", max_length=3000, is_required=True,
                 validator_list=[self.hasNoProfanities]),
         )
 

File django/contrib/contenttypes/models.py

View file
  • Ignore whitespace
         CONTENT_TYPE_CACHE = {}
 
 class ContentType(models.Model):
-    name = models.CharField(maxlength=100)
-    app_label = models.CharField(maxlength=100)
-    model = models.CharField(_('python model class name'), maxlength=100)
+    name = models.CharField(max_length=100)
+    app_label = models.CharField(max_length=100)
+    model = models.CharField(_('python model class name'), max_length=100)
     objects = ContentTypeManager()
     class Meta:
         verbose_name = _('content type')

File django/contrib/flatpages/models.py

View file
  • Ignore whitespace
 from django.utils.translation import ugettext_lazy as _
 
 class FlatPage(models.Model):
-    url = models.CharField(_('URL'), maxlength=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
+    url = models.CharField(_('URL'), max_length=100, validator_list=[validators.isAlphaNumericURL], db_index=True,
         help_text=_("Example: '/about/contact/'. Make sure to have leading and trailing slashes."))
-    title = models.CharField(_('title'), maxlength=200)
+    title = models.CharField(_('title'), max_length=200)
     content = models.TextField(_('content'))
     enable_comments = models.BooleanField(_('enable comments'))
-    template_name = models.CharField(_('template name'), maxlength=70, blank=True,
+    template_name = models.CharField(_('template name'), max_length=70, blank=True,
         help_text=_("Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."))
     registration_required = models.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
     sites = models.ManyToManyField(Site)

File django/contrib/redirects/models.py

View file
  • Ignore whitespace
 
 class Redirect(models.Model):
     site = models.ForeignKey(Site, radio_admin=models.VERTICAL)
-    old_path = models.CharField(_('redirect from'), maxlength=200, db_index=True,
+    old_path = models.CharField(_('redirect from'), max_length=200, db_index=True,
         help_text=_("This should be an absolute path, excluding the domain name. Example: '/events/search/'."))
-    new_path = models.CharField(_('redirect to'), maxlength=200, blank=True,
+    new_path = models.CharField(_('redirect to'), max_length=200, blank=True,
         help_text=_("This can be either an absolute path (as above) or a full URL starting with 'http://'."))
 
     class Meta:

File django/contrib/sessions/models.py

View file
  • Ignore whitespace
     the sessions documentation that is shipped with Django (also available
     on the Django website).
     """
-    session_key = models.CharField(_('session key'), maxlength=40, primary_key=True)
+    session_key = models.CharField(_('session key'), max_length=40, primary_key=True)
     session_data = models.TextField(_('session data'))
     expire_date = models.DateTimeField(_('expire date'))
     objects = SessionManager()

File django/contrib/sites/models.py

View file
  • Ignore whitespace
         return self.get(pk=sid)
 
 class Site(models.Model):
-    domain = models.CharField(_('domain name'), maxlength=100)
-    name = models.CharField(_('display name'), maxlength=50)
+    domain = models.CharField(_('domain name'), max_length=100)
+    name = models.CharField(_('display name'), max_length=50)
     objects = SiteManager()
     class Meta:
         db_table = 'django_site'

File django/core/management.py

View file
  • Ignore whitespace
                     field_type, new_params = field_type
                     extra_params.update(new_params)
 
-                # Add maxlength for all CharFields.
+                # Add max_length for all CharFields.
                 if field_type == 'CharField' and row[3]:
-                    extra_params['maxlength'] = row[3]
+                    extra_params['max_length'] = row[3]
 
                 if field_type == 'DecimalField':
                     extra_params['max_digits'] = row[4]
         for f in opts.fields:
             if f.name == 'id' and not f.primary_key and opts.pk.name == 'id':
                 e.add(opts, '"%s": You can\'t use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.' % f.name)
-            if isinstance(f, models.CharField) and f.maxlength in (None, 0):
-                e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name)
+            if isinstance(f, models.CharField) and f.max_length in (None, 0):
+                e.add(opts, '"%s": CharFields require a "max_length" attribute.' % f.name)
             if isinstance(f, models.DecimalField):
                 if f.decimal_places is None:
                     e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name)
             if f.db_index not in (None, True, False):
                 e.add(opts, '"%s": "db_index" should be either None, True or False.' % f.name)
 
-            # Check that maxlength <= 255 if using older MySQL versions.
+            # Check that max_length <= 255 if using older MySQL versions.
             if settings.DATABASE_ENGINE == 'mysql':
                 db_version = connection.get_server_version()
-                if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.maxlength > 255:
-                    e.add(opts, '"%s": %s cannot have a "maxlength" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
+                if db_version < (5, 0, 3) and isinstance(f, (models.CharField, models.CommaSeparatedIntegerField, models.SlugField)) and f.max_length > 255:
+                    e.add(opts, '"%s": %s cannot have a "max_length" greater than 255 when you are using a version of MySQL prior to 5.0.3 (you are using %s).' % (f.name, f.__class__.__name__, '.'.join([str(n) for n in db_version[:3]])))
 
             # Check to see if the related field will clash with any
             # existing fields, m2m fields, m2m related objects or related objects
     from django.db import backend, connection, transaction, models
     fields = (
         # "key" is a reserved word in MySQL, so use "cache_key" instead.
-        models.CharField(name='cache_key', maxlength=255, unique=True, primary_key=True),
+        models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
         models.TextField(name='value'),
         models.DateTimeField(name='expires', db_index=True),
     )
         shell.mainloop()
     except ImportError:
         import code
+        # Set up a dictionary to serve as the environment for the shell, so
+        # that tab completion works on objects that are imported at runtime.
+        # See ticket 5082.
+        imported_objects = {}
         try: # Try activating rlcompleter, because it's handy.
             import readline
         except ImportError:
             # We don't have to wrap the following import in a 'try', because
             # we already know 'readline' was imported successfully.
             import rlcompleter
+            readline.set_completer(rlcompleter.Completer(imported_objects).complete)
             readline.parse_and_bind("tab:complete")
-        code.interact()
+        code.interact(local=imported_objects)
 run_shell.args = '[--plain]'
 
 def dbshell():
                             print "Installing %s fixture '%s' from %s." % \
                                 (format, fixture_name, humanize(fixture_dir))
                         try:
-                            objects =  serializers.deserialize(format, fixture)
+                            objects = serializers.deserialize(format, fixture)
                             for obj in objects:
                                 count[0] += 1
                                 models.add(obj.object.__class__)

File django/core/validators.py

View file
  • Ignore whitespace
     try:
         float(data)
     except ValueError:
-        raise ValidationError, ugettext("Please enter a valid floating point number.")
+        raise ValidationError, _("Please enter a valid floating point number.")
 
 class HasAllowableSize(object):
     """

File django/db/backends/ado_mssql/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':         'int IDENTITY (1, 1)',
     'BooleanField':      'bit',
-    'CharField':         'varchar(%(maxlength)s)',
-    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'CharField':         'varchar(%(max_length)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
     'DateField':         'smalldatetime',
     'DateTimeField':     'smalldatetime',
     'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
     'PhoneNumberField':  'varchar(20)',
     'PositiveIntegerField': 'int CONSTRAINT [CK_int_pos_%(column)s] CHECK ([%(column)s] > 0)',
     'PositiveSmallIntegerField': 'smallint CONSTRAINT [CK_smallint_pos_%(column)s] CHECK ([%(column)s] > 0)',
-    'SlugField':         'varchar(%(maxlength)s)',
+    'SlugField':         'varchar(%(max_length)s)',
     'SmallIntegerField': 'smallint',
     'TextField':         'text',
     'TimeField':         'time',

File django/db/backends/mysql/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':         'integer AUTO_INCREMENT',
     'BooleanField':      'bool',
-    'CharField':         'varchar(%(maxlength)s)',
-    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'CharField':         'varchar(%(max_length)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
     'DateField':         'date',
     'DateTimeField':     'datetime',
     'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
     'PhoneNumberField':  'varchar(20)',
     'PositiveIntegerField': 'integer UNSIGNED',
     'PositiveSmallIntegerField': 'smallint UNSIGNED',
-    'SlugField':         'varchar(%(maxlength)s)',
+    'SlugField':         'varchar(%(max_length)s)',
     'SmallIntegerField': 'smallint',
     'TextField':         'longtext',
     'TimeField':         'time',

File django/db/backends/mysql_old/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':         'integer AUTO_INCREMENT',
     'BooleanField':      'bool',
-    'CharField':         'varchar(%(maxlength)s)',
-    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'CharField':         'varchar(%(max_length)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
     'DateField':         'date',
     'DateTimeField':     'datetime',
     'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
     'PhoneNumberField':  'varchar(20)',
     'PositiveIntegerField': 'integer UNSIGNED',
     'PositiveSmallIntegerField': 'smallint UNSIGNED',
-    'SlugField':         'varchar(%(maxlength)s)',
+    'SlugField':         'varchar(%(max_length)s)',
     'SmallIntegerField': 'smallint',
     'TextField':         'longtext',
     'TimeField':         'time',

File django/db/backends/oracle/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':                    'NUMBER(11)',
     'BooleanField':                 'NUMBER(1) CHECK (%(column)s IN (0,1))',
-    'CharField':                    'NVARCHAR2(%(maxlength)s)',
-    'CommaSeparatedIntegerField':   'VARCHAR2(%(maxlength)s)',
+    'CharField':                    'NVARCHAR2(%(max_length)s)',
+    'CommaSeparatedIntegerField':   'VARCHAR2(%(max_length)s)',
     'DateField':                    'DATE',
     'DateTimeField':                'TIMESTAMP',
     'DecimalField':                 'NUMBER(%(max_digits)s, %(decimal_places)s)',

File django/db/backends/postgresql/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':         'serial',
     'BooleanField':      'boolean',
-    'CharField':         'varchar(%(maxlength)s)',
-    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
+    'CharField':         'varchar(%(max_length)s)',
+    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
     'DateField':         'date',
     'DateTimeField':     'timestamp with time zone',
     'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
     'PhoneNumberField':  'varchar(20)',
     'PositiveIntegerField': 'integer CHECK ("%(column)s" >= 0)',
     'PositiveSmallIntegerField': 'smallint CHECK ("%(column)s" >= 0)',
-    'SlugField':         'varchar(%(maxlength)s)',
+    'SlugField':         'varchar(%(max_length)s)',
     'SmallIntegerField': 'smallint',
     'TextField':         'text',
     'TimeField':         'time',

File django/db/backends/sqlite3/creation.py

View file
  • Ignore whitespace
 DATA_TYPES = {
     'AutoField':                    'integer',
     'BooleanField':                 'bool',
-    'CharField':                    'varchar(%(maxlength)s)',
-    'CommaSeparatedIntegerField':   'varchar(%(maxlength)s)',
+    'CharField':                    'varchar(%(max_length)s)',
+    'CommaSeparatedIntegerField':   'varchar(%(max_length)s)',
     'DateField':                    'date',
     'DateTimeField':                'datetime',
     'DecimalField':                 'decimal',
     'PhoneNumberField':             'varchar(20)',
     'PositiveIntegerField':         'integer unsigned',
     'PositiveSmallIntegerField':    'smallint unsigned',
-    'SlugField':                    'varchar(%(maxlength)s)',
+    'SlugField':                    'varchar(%(max_length)s)',
     'SmallIntegerField':            'smallint',
     'TextField':                    'text',
     'TimeField':                    'time',

File django/db/backends/sqlite3/introspection.py

View file
  • Ignore whitespace
             import re
             m = re.search(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$', key)
             if m:
-                return ('CharField', {'maxlength': int(m.group(1))})
+                return ('CharField', {'max_length': int(m.group(1))})
             raise KeyError
 
 DATA_TYPES_REVERSE = FlexibleFieldLookupDict()

File django/db/models/fields/__init__.py

View file
  • Ignore whitespace
 from django.utils.text import capfirst
 from django.utils.translation import ugettext_lazy, ugettext as _
 from django.utils.encoding import smart_unicode, force_unicode, smart_str
+from django.utils.maxlength import LegacyMaxlength
 import datetime, os, time
 try:
     import decimal
 #     getattr(obj, opts.pk.attname)
 
 class Field(object):
+    # Provide backwards compatibility for the maxlength attribute and
+    # argument for this class and all subclasses.
+    __metaclass__ = LegacyMaxlength
 
     # Designates whether empty strings fundamentally are allowed at the
     # database level.
     creation_counter = 0
 
     def __init__(self, verbose_name=None, name=None, primary_key=False,
-        maxlength=None, unique=False, blank=False, null=False, db_index=False,
+        max_length=None, unique=False, blank=False, null=False, db_index=False,
         core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
         prepopulate_from=None, unique_for_date=None, unique_for_month=None,
         unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
         self.name = name
         self.verbose_name = verbose_name
         self.primary_key = primary_key
-        self.maxlength, self.unique = maxlength, unique
+        self.max_length, self.unique = max_length, unique
         self.blank, self.null = blank, null
         # Oracle treats the empty string ('') as null, so coerce the null
         # option whenever '' is a possible value.
 
     def prepare_field_objs_and_params(self, manipulator, name_prefix):
         params = {'validator_list': self.validator_list[:]}
-        if self.maxlength and not self.choices: # Don't give SelectFields a maxlength parameter.
-            params['maxlength'] = self.maxlength
+        if self.max_length and not self.choices: # Don't give SelectFields a max_length parameter.
+            params['max_length'] = self.max_length
 
         if self.choices:
             if self.radio_admin:
             return self._choices
     choices = property(_get_choices)
 
+    def save_form_data(self, instance, data):
+        setattr(instance, self.name, data)
+        
     def formfield(self, form_class=forms.CharField, **kwargs):
         "Returns a django.newforms.Field instance for this database Field."
         defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
         return smart_unicode(value)
 
     def formfield(self, **kwargs):
-        defaults = {'max_length': self.maxlength}
+        defaults = {'max_length': self.max_length}
         defaults.update(kwargs)
         return super(CharField, self).formfield(**defaults)
 
 
 class EmailField(CharField):
     def __init__(self, *args, **kwargs):
-        kwargs['maxlength'] = 75
+        kwargs['max_length'] = 75
         CharField.__init__(self, *args, **kwargs)
 
     def get_internal_type(self):
         self.upload_to = upload_to
         Field.__init__(self, verbose_name, name, **kwargs)
 
+    def get_db_prep_save(self, value):
+        "Returns field's value prepared for saving into a database."
+        # Need to convert UploadedFile objects provided via a form to unicode for database insertion
+        if value is None:
+            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:
         f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename)))
         return os.path.normpath(f)
 
+    def save_form_data(self, instance, data):
+        if data:
+            getattr(instance, "save_%s_file" % self.name)(os.path.join(self.upload_to, data.filename), data.content, save=False)
+        
+    def formfield(self, **kwargs):
+        defaults = {'form_class': forms.FileField}
+        # If a file has been provided previously, then the form doesn't require 
+        # that a new file is provided this time.
+        if 'initial' in kwargs:
+            defaults['required'] = False
+        defaults.update(kwargs)
+        return super(FileField, self).formfield(**defaults)
+
 class FilePathField(Field):
     def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs):
         self.path, self.match, self.recursive = path, match, recursive
                 setattr(new_object, self.height_field, getattr(original_object, self.height_field))
             new_object.save()
 
+    def formfield(self, **kwargs):
+        defaults = {'form_class': forms.ImageField}
+        return super(ImageField, self).formfield(**defaults)
+
 class IntegerField(Field):
     empty_strings_allowed = False
     def get_manipulator_field_objs(self):
 class IPAddressField(Field):
     empty_strings_allowed = False
     def __init__(self, *args, **kwargs):
-        kwargs['maxlength'] = 15
+        kwargs['max_length'] = 15
         Field.__init__(self, *args, **kwargs)
 
     def get_manipulator_field_objs(self):
 
 class SlugField(Field):
     def __init__(self, *args, **kwargs):
-        kwargs['maxlength'] = kwargs.get('maxlength', 50)
+        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:
 
 class URLField(CharField):
     def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
-        kwargs['maxlength'] = kwargs.get('maxlength', 200)
+        kwargs['max_length'] = kwargs.get('max_length', 200)
         if verify_exists:
             kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
         self.verify_exists = verify_exists

File django/db/models/fields/related.py

View file
  • Ignore whitespace
         "Returns the value of this field in the given model instance."
         return getattr(obj, self.attname).all()
 
+    def save_form_data(self, instance, data):
+        setattr(instance, self.attname, data)
+        
     def formfield(self, **kwargs):
         defaults = {'form_class': forms.ModelMultipleChoiceField, 'queryset': self.rel.to._default_manager.all()}
         defaults.update(kwargs)

File django/newforms/extras/widgets.py

View file
  • Ignore whitespace
 
         return u'\n'.join(output)
 
-    def value_from_datadict(self, data, name):
+    def value_from_datadict(self, data, files, name):
         y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name)
         if y and m and d:
             return '%s-%s-%s' % (y, m, d)

File django/newforms/fields.py

View file
  • Ignore whitespace
 import time
 
 from django.utils.translation import ugettext
-from django.utils.encoding import smart_unicode
+from django.utils.encoding import StrAndUnicode, smart_unicode
 
 from util import ErrorList, ValidationError
-from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
+from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple
 
 try:
     from decimal import Decimal, DecimalException
     'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
     'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
     'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField',
-    'RegexField', 'EmailField', 'URLField', 'BooleanField',
+    'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField',
     'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
     'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
     'SplitDateTimeField',
 
     def widget_attrs(self, widget):
         if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)):
+            # The HTML attribute is maxlength, not max_length.
             return {'maxlength': str(self.max_length)}
 
 class IntegerField(Field):
     # It's OK if Django settings aren't configured.
     URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
 
+class UploadedFile(StrAndUnicode):
+    "A wrapper for files uploaded in a FileField"
+    def __init__(self, filename, content):
+        self.filename = filename
+        self.content = content
+        
+    def __unicode__(self):
+        """
+        The unicode representation is the filename, so that the pre-database-insertion
+        logic can use UploadedFile objects
+        """
+        return self.filename
+
+class FileField(Field):
+    widget = FileInput
+    def __init__(self, *args, **kwargs):
+        super(FileField, self).__init__(*args, **kwargs)
+
+    def clean(self, data):
+        super(FileField, self).clean(data)
+        if not self.required and data in EMPTY_VALUES:
+            return None
+        try:
+            f = UploadedFile(data['filename'], data['content'])
+        except TypeError:
+            raise ValidationError(ugettext(u"No file was submitted. Check the encoding type on the form."))
+        except KeyError:
+            raise ValidationError(ugettext(u"No file was submitted."))
+        if not f.content:
+            raise ValidationError(ugettext(u"The submitted file is empty."))
+        return f
+
+class ImageField(FileField):
+    def clean(self, data):
+        """
+        Checks that the file-upload field data contains a valid image (GIF, JPG,
+        PNG, possibly others -- whatever the Python Imaging Library supports).
+        """
+        f = super(ImageField, self).clean(data)
+        if f is None:
+            return None
+        from PIL import Image
+        from cStringIO import StringIO
+        try:
+            Image.open(StringIO(f.content))
+        except IOError: # Python Imaging Library doesn't recognize it as an image
+            raise ValidationError(ugettext(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."))
+        return f
+        
 class URLField(RegexField):
     def __init__(self, max_length=None, min_length=None, verify_exists=False,
             validator_user_agent=URL_VALIDATOR_USER_AGENT, *args, **kwargs):

File django/newforms/forms.py

View file
  • Ignore whitespace
     # class is different than Form. See the comments by the Form class for more
     # information. Any improvements to the form API should be made to *this*
     # class, not to the Form class.
-    def __init__(self, data=None, auto_id='id_%s', prefix=None, initial=None):
-        self.is_bound = data is not None
+    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None):
+        self.is_bound = data is not None or files is not None
         self.data = data or {}
+        self.files = files or {}
         self.auto_id = auto_id
         self.prefix = prefix
         self.initial = initial or {}
         return BoundField(self, field, name)
 
     def _get_errors(self):
-        "Returns an ErrorDict for self.data"
+        "Returns an ErrorDict for the data provided for the form"
         if self._errors is None:
             self.full_clean()
         return self._errors
             return
         self.cleaned_data = {}
         for name, field in self.fields.items():
-            # value_from_datadict() gets the data from the dictionary.
+            # value_from_datadict() gets the data from the data dictionaries.
             # Each widget type knows how to retrieve its own data, because some
             # widgets split data over several HTML fields.
-            value = field.widget.value_from_datadict(self.data, self.add_prefix(name))
+            value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
             try:
                 value = field.clean(value)
                 self.cleaned_data[name] = value
         """
         Returns the data for this BoundField, or None if it wasn't given.
         """
-        return self.field.widget.value_from_datadict(self.form.data, self.html_name)
+        return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name)
     data = property(_data)
 
     def label_tag(self, contents=None, attrs=None):

File django/newforms/models.py

View file
  • Ignore whitespace
             continue
         if fields and f.name not in fields:
             continue
-        setattr(instance, f.name, cleaned_data[f.name])
-    if commit:
-        instance.save()
+        f.save_form_data(instance, cleaned_data[f.name])        
+    # Wrap up the saving of m2m data as a function
+    def save_m2m():
+        opts = instance.__class__._meta
+        cleaned_data = form.cleaned_data
         for f in opts.many_to_many:
             if fields and f.name not in fields:
                 continue
             if f.name in cleaned_data:
-                setattr(instance, f.attname, cleaned_data[f.name])
-    # GOTCHA: If many-to-many data is given and commit=False, the many-to-many
-    # data will be lost. This happens because a many-to-many options cannot be
-    # set on an object until after it's saved. Maybe we should raise an
-    # exception in that case.
+                f.save_form_data(instance, cleaned_data[f.name])
+    if commit:
+        # If we are committing, save the instance and the m2m data immediately
+        instance.save()
+        save_m2m()
+    else:
+        # We're not committing. Add a method to the form to allow deferred 
+        # saving of m2m data
+        form.save_m2m = save_m2m
     return instance
 
 def make_model_save(model, fields, fail_message):

File django/newforms/widgets.py

View file
  • Ignore whitespace
             attrs.update(extra_attrs)
         return attrs
 
-    def value_from_datadict(self, data, name):
+    def value_from_datadict(self, data, files, name):
         """
         Given a dictionary of data and this widget's name, returns the value
         of this widget. Returns None if it's not provided.
         final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
         return u'\n'.join([(u'<input%s />' % flatatt(dict(value=force_unicode(v), **final_attrs))) for v in value])
 
-    def value_from_datadict(self, data, name):
+    def value_from_datadict(self, data, files, name):
         if isinstance(data, MultiValueDict):
             return data.getlist(name)
         return data.get(name, None)
 class FileInput(Input):
     input_type = 'file'
 
+    def render(self, name, value, attrs=None):
+        return super(FileInput, self).render(name, None, attrs=attrs)
+        
+    def value_from_datadict(self, data, files, name):
+        "File widgets take data from FILES, not POST"
+        return files.get(name, None)
+
 class Textarea(Widget):
     def __init__(self, attrs=None):
         # The 'rows' and 'cols' attributes are required for HTML correctness.
             value = u'1'
         return super(NullBooleanSelect, self).render(name, value, attrs, choices)
 
-    def value_from_datadict(self, data, name):
+    def value_from_datadict(self, data, files, name):
         value = data.get(name, None)
         return {u'2': True, u'3': False, True: True, False: False}.get(value, None)
 
         output.append(u'</select>')
         return u'\n'.join(output)
 
-    def value_from_datadict(self, data, name):
+    def value_from_datadict(self, data, files, name):
         if isinstance(data, MultiValueDict):
             return data.getlist(name)
         return data.get(name, None)
         return id_
     id_for_label = classmethod(id_for_label)
 
-    def value_from_datadict(self, data, name):
-        return [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
+    def value_from_datadict(self, data, files, name):
+        return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)]
 
     def format_output(self, rendered_widgets):
         """

File django/oldforms/__init__.py

View file
  • Ignore whitespace
 from django.conf import settings
 from django.utils.translation import ugettext, ungettext
 from django.utils.encoding import smart_unicode, force_unicode
+from django.utils.maxlength import LegacyMaxlength
 
 FORM_FIELD_ID_PREFIX = 'id_'
 
     Subclasses should also implement a render(data) method, which is responsible
     for rending the form field in XHTML.
     """
+    # Provide backwards compatibility for the maxlength attribute and
+    # argument for this class and all subclasses.
+    __metaclass__ = LegacyMaxlength
 
     def __str__(self):
         return unicode(self).encode('utf-8')
 
 class TextField(FormField):
     input_type = "text"
-    def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=None, member_name=None):
+    def __init__(self, field_name, length=30, max_length=None, is_required=False, validator_list=None, member_name=None):
         if validator_list is None: validator_list = []
         self.field_name = field_name
-        self.length, self.maxlength = length, maxlength
+        self.length, self.max_length = length, max_length
         self.is_required = is_required
         self.validator_list = [self.isValidLength, self.hasNoNewlines] + validator_list
         if member_name != None:
             self.member_name = member_name
 
     def isValidLength(self, data, form):
-        if data and self.maxlength and len(smart_unicode(data)) > self.maxlength:
+        if data and self.max_length and len(smart_unicode(data)) > self.max_length:
             raise validators.ValidationError, ungettext("Ensure your text is less than %s character.",
-                "Ensure your text is less than %s characters.", self.maxlength) % self.maxlength
+                "Ensure your text is less than %s characters.", self.max_length) % self.max_length
 
     def hasNoNewlines(self, data, form):
         if data and '\n' in data:
     def render(self, data):
         if data is None:
             data = u''
-        maxlength = u''
-        if self.maxlength:
-            maxlength = u'maxlength="%s" ' % self.maxlength
+        max_length = u''
+        if self.max_length:
+            max_length = u'maxlength="%s" ' % self.max_length
         return u'<input type="%s" id="%s" class="v%s%s" name="%s" size="%s" value="%s" %s/>' % \
             (self.input_type, self.get_id(), self.__class__.__name__, self.is_required and u' required' or '',
-            self.field_name, self.length, escape(data), maxlength)
+            self.field_name, self.length, escape(data), max_length)
 
     def html2python(data):
         return data
     input_type = "password"
 
 class LargeTextField(TextField):
-    def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_list=None, maxlength=None):
+    def __init__(self, field_name, rows=10, cols=40, is_required=False, validator_list=None, max_length=None):
         if validator_list is None: validator_list = []
         self.field_name = field_name
         self.rows, self.cols, self.is_required = rows, cols, is_required
         self.validator_list = validator_list[:]
-        if maxlength:
+        if max_length:
             self.validator_list.append(self.isValidLength)
-            self.maxlength = maxlength
+            self.max_length = max_length
 
     def render(self, data):
         if data is None:
 ####################
 
 class IntegerField(TextField):
-    def __init__(self, field_name, length=10, maxlength=None, is_required=False, validator_list=None, member_name=None):
+    def __init__(self, field_name, length=10, max_length=None, is_required=False, validator_list=None, member_name=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isInteger] + validator_list
         if member_name is not None:
             self.member_name = member_name
-        TextField.__init__(self, field_name, length, maxlength, is_required, validator_list)
+        TextField.__init__(self, field_name, length, max_length, is_required, validator_list)
 
     def isInteger(self, field_data, all_data):
         try:
     html2python = staticmethod(html2python)
 
 class SmallIntegerField(IntegerField):
-    def __init__(self, field_name, length=5, maxlength=5, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=5, max_length=5, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isSmallInteger] + validator_list
-        IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
+        IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
 
     def isSmallInteger(self, field_data, all_data):
         if not -32768 <= int(field_data) <= 32767:
             raise validators.CriticalValidationError, ugettext("Enter a whole number between -32,768 and 32,767.")
 
 class PositiveIntegerField(IntegerField):
-    def __init__(self, field_name, length=10, maxlength=None, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=10, max_length=None, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isPositive] + validator_list
-        IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
+        IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
 
     def isPositive(self, field_data, all_data):
         if int(field_data) < 0:
             raise validators.CriticalValidationError, ugettext("Enter a positive number.")
 
 class PositiveSmallIntegerField(IntegerField):
-    def __init__(self, field_name, length=5, maxlength=None, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=5, max_length=None, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isPositiveSmall] + validator_list
-        IntegerField.__init__(self, field_name, length, maxlength, is_required, validator_list)
+        IntegerField.__init__(self, field_name, length, max_length, is_required, validator_list)
 
     def isPositiveSmall(self, field_data, all_data):
         if not 0 <= int(field_data) <= 32767:
             raise validators.CriticalValidationError, ugettext("Enter a whole number between 0 and 32,767.")
 
 class FloatField(TextField):
-    def __init__(self, field_name, is_required=False, validator_list=None): 
-        if validator_list is None: validator_list = [] 
-        validator_list = [validators.isValidFloat] + validator_list 
-        TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list) 
- 
-    def html2python(data): 
-        if data == '' or data is None: 
-            return None 
-        return float(data) 
-    html2python = staticmethod(html2python) 
- 
-class DecimalField(TextField): 
+    def __init__(self, field_name, is_required=False, validator_list=None):
+        if validator_list is None: validator_list = []
+        validator_list = [validators.isValidFloat] + validator_list
+        TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list)
+
+    def html2python(data):
+        if data == '' or data is None:
+            return None
+        return float(data)
+    html2python = staticmethod(html2python)
+
+class DecimalField(TextField):
     def __init__(self, field_name, max_digits, decimal_places, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         self.max_digits, self.decimal_places = max_digits, decimal_places
-        validator_list = [self.isValidDecimal] + validator_list 
-        # Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point. 
-        super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list) 
+        validator_list = [self.isValidDecimal] + validator_list
+        # Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point.
+        super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list)
 
-    def isValidDecimal(self, field_data, all_data): 
-        v = validators.IsValidDecimal(self.max_digits, self.decimal_places) 
+    def isValidDecimal(self, field_data, all_data):
+        v = validators.IsValidDecimal(self.max_digits, self.decimal_places)
         try:
             v(field_data, all_data)
         except validators.ValidationError, e:
     def html2python(data):
         if data == '' or data is None:
             return None
-        try: 
-            import decimal 
+        try:
+            import decimal
         except ImportError:
             from django.utils import _decimal as decimal
-        try: 
-            return decimal.Decimal(data) 
-        except decimal.InvalidOperation, e: 
-            raise ValueError, e 
+        try:
+            return decimal.Decimal(data)
+        except decimal.InvalidOperation, e:
+            raise ValueError, e
     html2python = staticmethod(html2python)
 
 ####################
 class DatetimeField(TextField):
     """A FormField that automatically converts its data to a datetime.datetime object.
     The data should be in the format YYYY-MM-DD HH:MM:SS."""
-    def __init__(self, field_name, length=30, maxlength=None, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=30, max_length=None, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         self.field_name = field_name
-        self.length, self.maxlength = length, maxlength
+        self.length, self.max_length = length, max_length
         self.is_required = is_required
         self.validator_list = [validators.isValidANSIDatetime] + validator_list
 
     def __init__(self, field_name, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidDate] + validator_list
-        TextField.__init__(self, field_name, length=10, maxlength=10,
+        TextField.__init__(self, field_name, length=10, max_length=10,
             is_required=is_required, validator_list=validator_list)
 
     def isValidDate(self, field_data, all_data):
     def __init__(self, field_name, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidTime] + validator_list
-        TextField.__init__(self, field_name, length=8, maxlength=8,
+        TextField.__init__(self, field_name, length=8, max_length=8,
             is_required=is_required, validator_list=validator_list)
 
     def isValidTime(self, field_data, all_data):
 
 class EmailField(TextField):
     "A convenience FormField for validating e-mail addresses"
-    def __init__(self, field_name, length=50, maxlength=75, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=50, max_length=75, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidEmail] + validator_list
-        TextField.__init__(self, field_name, length, maxlength=maxlength,
+        TextField.__init__(self, field_name, length, max_length=max_length,
             is_required=is_required, validator_list=validator_list)
 
     def isValidEmail(self, field_data, all_data):
 
 class URLField(TextField):
     "A convenience FormField for validating URLs"
-    def __init__(self, field_name, length=50, maxlength=200, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=50, max_length=200, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidURL] + validator_list
-        TextField.__init__(self, field_name, length=length, maxlength=maxlength,
+        TextField.__init__(self, field_name, length=length, max_length=max_length,
             is_required=is_required, validator_list=validator_list)
 
     def isValidURL(self, field_data, all_data):
             raise validators.CriticalValidationError, e.messages
 
 class IPAddressField(TextField):
-    def __init__(self, field_name, length=15, maxlength=15, is_required=False, validator_list=None):
+    def __init__(self, field_name, length=15, max_length=15, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidIPAddress] + validator_list
-        TextField.__init__(self, field_name, length=length, maxlength=maxlength,
+        TextField.__init__(self, field_name, length=length, max_length=max_length,
             is_required=is_required, validator_list=validator_list)
 
     def isValidIPAddress(self, field_data, all_data):
     def __init__(self, field_name, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidPhone] + validator_list
-        TextField.__init__(self, field_name, length=12, maxlength=12,
+        TextField.__init__(self, field_name, length=12, max_length=12,
             is_required=is_required, validator_list=validator_list)
 
     def isValidPhone(self, field_data, all_data):
     def __init__(self, field_name, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isValidUSState] + validator_list
-        TextField.__init__(self, field_name, length=2, maxlength=2,
+        TextField.__init__(self, field_name, length=2, max_length=2,
             is_required=is_required, validator_list=validator_list)
 
     def isValidUSState(self, field_data, all_data):
 
 class CommaSeparatedIntegerField(TextField):
     "A convenience FormField for validating comma-separated integer fields"
-    def __init__(self, field_name, maxlength=None, is_required=False, validator_list=None):
+    def __init__(self, field_name, max_length=None, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
         validator_list = [self.isCommaSeparatedIntegerList] + validator_list
-        TextField.__init__(self, field_name, length=20, maxlength=maxlength,
+        TextField.__init__(self, field_name, length=20, max_length=max_length,
             is_required=is_required, validator_list=validator_list)
 
     def isCommaSeparatedIntegerList(self, field_data, all_data):

File django/template/defaulttags.py

View file
  • Ignore whitespace
     As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
     will be displayed if the test fails.
 
-    ``if`` tags may use ``or`` or ``not`` to test a number of variables or to
-    negate a given variable::
+    ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of
+    variables or to negate a given variable::
 
         {% if not athlete_list %}
             There are no athletes.
             There are some athletes or some coaches.
         {% endif %}
 
+        {% if athlete_list and coach_list %}
+            Both atheletes and coaches are available.
+        {% endif %}
+
         {% if not athlete_list or coach_list %}
             There are no athletes, or there are some coaches.
         {% endif %}
 
-    For simplicity, ``if`` tags do not allow ``and`` clauses. Use nested ``if``
-    tags instead::
+        {% if athlete_list and not coach_list %}
+            There are some athletes and absolutely no coaches.
+        {% endif %}
 
-        {% if athlete_list %}
-            {% if coach_list %}
-                Number of athletes: {{ athlete_list|count }}.
-                Number of coaches: {{ coach_list|count }}.
-            {% endif %}
+    ``if`` tags do not allow ``and`` and ``or`` clauses with the same
+    tag, because the order of logic would be ambigous. For example,
+    this is invalid::
+
+    {% if athlete_list and coach_list or cheerleader_list %}
+
+    If you need to combine and and or to do advanced logic, just use
+    nested if tags. For example:
+
+    {% if athlete_list %}
+        {% if coach_list or cheerleader_list %}
+            We have athletes, and either coaches or cheerleaders!
         {% endif %}
+    {% endif %}
     """
     bits = token.contents.split()
     del bits[0]

File django/utils/encoding.py

View file
  • Ignore whitespace
 import types
 import urllib
-from django.conf import settings
 from django.utils.functional import Promise
 
 class StrAndUnicode(object):

File django/utils/maxlength.py

View file
  • Ignore whitespace
+"""
+Utilities for providing backwards compatibility for the maxlength argument,
+which has been replaced by max_length, see ticket #2101.
+"""
+
+from warnings import warn
+
+def get_maxlength(self):
+    return self.max_length
+
+def set_maxlength(self, value):
+    self.max_length = value
+
+def legacy_maxlength(max_length, maxlength):
+    """
+    Consolidates max_length and maxlength, providing backwards compatibilty
+    for the legacy "maxlength" argument.
+    If one of max_length or maxlength is given, then that value is returned.
+    If both are given, a TypeError is raised.
+    If maxlength is used at all, a deprecation warning is issued.
+    """
+    if maxlength is not None:
+        warn("maxlength is deprecated, use max_length instead.",
+             PendingDeprecationWarning,
+             stacklevel=3)
+        if max_length is not None:
+            raise TypeError("field can not take both the max_length"
+                            " argument and the legacy maxlength argument.")
+        max_length = maxlength
+    return max_length
+
+def remove_maxlength(func):
+    """
+    A decorator to be used on a class's __init__ that provides backwards
+    compatibilty for the legacy "maxlength" keyword argument, i.e.
+      name = models.CharField(maxlength=20)
+    It does this by changing the passed "maxlength" keyword argument
+    (if it exists) into a "max_length" keyword argument.
+    """
+    def inner(self, *args, **kwargs):
+        max_length = kwargs.get('max_length', None)
+        # pop maxlength because we don't want this going to __init__.
+        maxlength = kwargs.pop('maxlength', None)
+        max_length = legacy_maxlength(max_length, maxlength)
+        # Only set the max_length keyword argument if we got a value back.
+        if max_length is not None:
+            kwargs['max_length'] = max_length
+        func(self, *args, **kwargs)
+    return inner
+
+# This metaclass is used in two places, and should be removed when legacy
+# support for maxlength is dropped.
+#   * oldforms.FormField
+#   * db.models.fields.Field
+
+class LegacyMaxlength(type):
+    """
+    Metaclass for providing backwards compatibility support for the
+    "maxlength" keyword argument.
+    """
+
+    def __init__(cls, name, bases, attrs):
+        super(LegacyMaxlength, cls).__init__(name, bases, attrs)
+        # Decorate the class's __init__ to remove any maxlength keyword.
+        cls.__init__ = remove_maxlength(cls.__init__)
+        # Support accessing and setting to the legacy maxlength attribute.
+        cls.maxlength = property(get_maxlength, set_maxlength)

File docs/add_ons.txt

View file
  • Ignore whitespace
 
 See the `syndication documentation`_.
 
-.. _syndication documentation: ../syndication/
+.. _syndication documentation: ../syndication_feeds/
 
 Other add-ons
 =============

File docs/api_stability.txt

View file
  • Ignore whitespace
 That said, these APIs should *not* be considered stable, and are likely to
 change:
 
-   - `Forms and validation`_ will most likely be completely rewritten to
-     deemphasize Manipulators in favor of validation-aware models.
-
    - `Serialization`_ is under heavy development; changes are likely.
 
    - The `authentication`_ framework is changing to be far more flexible, and
 .. _sending email: ../email/
 .. _sessions: ../sessions/
 .. _settings: ../settings/
-.. _syndication: ../syndication/
+.. _syndication: ../syndication_feeds/
 .. _template language: ../templates/
 .. _transactions: ../transactions/
 .. _url dispatch: ../url_dispatch/

File docs/authentication.txt

View file
  • Ignore whitespace
 
 Previous Django versions, such as 0.90, used simple MD5 hashes without password
 salts. For backwards compatibility, those are still supported; they'll be
-converted automatically to the new style the first time ``check_password()``
+converted automatically to the new style the first time ``User.check_password()``
 works correctly for a given user.
 
 Anonymous users

File docs/contributing.txt

View file
  • Ignore whitespace
       Do this::
 
           class Person(models.Model):
-              first_name = models.CharField(maxlength=20)
-              last_name = models.CharField(maxlength=40)
+              first_name = models.CharField(max_length=20)
+              last_name = models.CharField(max_length=40)
 
       Don't do this::
 
           class Person(models.Model):
-              FirstName = models.CharField(maxlength=20)
-              Last_Name = models.CharField(maxlength=40)
+              FirstName = models.CharField(max_length=20)
+              Last_Name = models.CharField(max_length=40)
 
     * The ``class Meta`` should appear *after* the fields are defined, with
       a single blank line separating the fields and the class definition.
       Do this::
 
           class Person(models.Model):
-              first_name = models.CharField(maxlength=20)
-              last_name = models.CharField(maxlength=40)
+              first_name = models.CharField(max_length=20)
+              last_name = models.CharField(max_length=40)
 
               class Meta:
                   verbose_name_plural = 'people'
       Don't do this::
 
           class Person(models.Model):
-              first_name = models.CharField(maxlength=20)
-              last_name = models.CharField(maxlength=40)
+              first_name = models.CharField(max_length=20)
+              last_name = models.CharField(max_length=40)
               class Meta:
                   verbose_name_plural = 'people'
 
               class Meta:
                   verbose_name_plural = 'people'
 
-              first_name = models.CharField(maxlength=20)
-              last_name = models.CharField(maxlength=40)
+              first_name = models.CharField(max_length=20)
+              last_name = models.CharField(max_length=40)
 
     * The order of model inner classes and standard methods should be as
       follows (noting that these are not all required):

File docs/databases.txt

View file
  • Ignore whitespace
 ``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
 `MySQLdb documentation`_ for more details.
 
-.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
+.. _settings documentation: ../settings/#database-engine
 .. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
 .. _MySQLdb documentation: http://mysql-python.sourceforge.net/
 

File docs/db-api.txt

View file
  • Ignore whitespace
 a weblog application::
 
     class Blog(models.Model):
-        name = models.CharField(maxlength=100)
+        name = models.CharField(max_length=100)
         tagline = models.TextField()
 
         def __unicode__(self):
             return self.name
 
     class Author(models.Model):
-        name = models.CharField(maxlength=50)
+        name = models.CharField(max_length=50)
         email = models.EmailField()
 
         def __unicode__(self):
 
     class Entry(models.Model):
         blog = models.ForeignKey(Blog)
-        headline = models.CharField(maxlength=255)
+        headline = models.CharField(max_length=255)
         body_text = models.TextField()
         pub_date = models.DateTimeField()
         authors = models.ManyToManyField(Author)
 
 See the `OR lookups examples page`_ for more examples.
 
-.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
+.. _OR lookups examples page: ../models/or_lookups/
 
 Related objects
 ===============
         ('F', 'Female'),
     )
     class Person(models.Model):
-        name = models.CharField(maxlength=20)
-        gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+        name = models.CharField(max_length=20)
+        gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
 
 ...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
 
 as a fallback check. This guarantees that no records are skipped or duplicated.
 For a full example, see the `lookup API sample model`_.
 
-.. _lookup API sample model: http://www.djangoproject.com/documentation/models/lookup/
+.. _lookup API sample model: ../models/lookup/
 
 get_FOO_filename()
 ------------------

File docs/email.txt

View file
  • Ignore whitespace
 
     subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
     text_content = 'This is an important message.'
-    html_content = '<p>This is an <strong>important</strong> message.'
+    html_content = '<p>This is an <strong>important</strong> message.</p>'
     msg = EmailMultiAlternatives(subject, text_content, from_email, to)
     msg.attach_alternative(html_content, "text/html")
     msg.send()

File docs/faq.txt

View file
  • Ignore whitespace
 
 Django is pronounced **JANG**-oh. Rhymes with FANG-oh. The "D" is silent.
 
+We've also recorded an `audio clip of the pronunciation`_.
+
 .. _Django Reinhardt: http://en.wikipedia.org/wiki/Django_Reinhardt
+.. _audio clip of the pronunciation: http://red-bean.com/~adrian/django_pronunciation.mp3
 
 Is Django stable?
 -----------------

File docs/forms.txt

View file
  • Ignore whitespace
     )
 
     class Place(models.Model):
-        name = models.CharField(maxlength=100)
-        address = models.CharField(maxlength=100, blank=True)
-        city = models.CharField(maxlength=50, blank=True)
+        name = models.CharField(max_length=100)
+        address = models.CharField(max_length=100, blank=True)
+        city = models.CharField(max_length=50, blank=True)
         state = models.USStateField()
-        zip_code = models.CharField(maxlength=5, blank=True)
+        zip_code = models.CharField(max_length=5, blank=True)
         place_type = models.IntegerField(choices=PLACE_TYPES)
 
         class Admin:
         def __init__(self):
             self.fields = (
                 forms.EmailField(field_name="from", is_required=True),
-                forms.TextField(field_name="subject", length=30, maxlength=200, is_required=True),
+                forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
                 forms.SelectField(field_name="urgency", choices=urgency_choices),
                 forms.LargeTextField(field_name="contents", is_required=True),
             )

File docs/model-api.txt

View file
  • Ignore whitespace
 ``tests/modeltests`` directory.)
 
 .. _Database API reference: ../db-api/
-.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
+.. _official repository of model examples: ../models/
 
 Quick example
 =============
     from django.db import models
 
     class Person(models.Model):
-        first_name = models.CharField(maxlength=30)
-        last_name = models.CharField(maxlength=30)
+        first_name = models.CharField(max_length=30)
+        last_name = models.CharField(max_length=30)
 
 ``first_name`` and ``last_name`` are *fields* of the model. Each field is
 specified as a class attribute, and each attribute maps to a database column.
 Example::
 
     class Musician(models.Model):
-        first_name = models.CharField(maxlength=50)
-        last_name = models.CharField(maxlength=50)
-        instrument = models.CharField(maxlength=100)
+        first_name = models.CharField(max_length=50)
+        last_name = models.CharField(max_length=50)
+        instrument = models.CharField(max_length=100)
 
     class Album(models.Model):
         artist = models.ForeignKey(Musician)
-        name = models.CharField(maxlength=100)
+        name = models.CharField(max_length=100)
         release_date = models.DateField()
         num_stars = models.IntegerField()
 
 
 The admin represents this as an ``<input type="text">`` (a single-line input).
 
-``CharField`` has an extra required argument, ``maxlength``, the maximum length
-(in characters) of the field. The maxlength is enforced at the database level
+``CharField`` has an extra required argument, ``max_length``, the maximum length
+(in characters) of the field. The max_length is enforced at the database level
 and in Django's validation.
 
-``CommaSeparatedIntegerField``
+Django veterans: Note that the argument is now called ``max_length`` to
+provide consistency throughout Django. There is full legacy support for
+the old ``maxlength`` argument, but ``max_length`` is prefered.
+	
+ ``CommaSeparatedIntegerField``
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-A field of integers separated by commas. As in ``CharField``, the ``maxlength``
+A field of integers separated by commas. As in ``CharField``, the ``max_length``
 argument is required.
 
 ``DateField``
 ~~~~~~~~~~~~~~
 
 A ``CharField`` that checks that the value is a valid e-mail address.
-This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
+This doesn't accept ``max_length``; its ``max_length`` is automatically set to
 75.
 
 ``FileField``
 containing only letters, numbers, underscores or hyphens. They're generally
 used in URLs.
 
-Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
+Like a CharField, you can specify ``max_length``. If ``max_length`` is
 not specified, Django will use a default length of 50.
 
 Implies ``db_index=True``.
 
 The admin represents this as an ``<input type="text">`` (a single-line input).
 
-``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
-characters) of the field. The maxlength is enforced at the database level and
-in Django's validation. If you don't specify ``maxlength``, a default of 200
+``URLField`` takes an optional argument, ``max_length``, the maximum length (in
+characters) of the field. The maximum length is enforced at the database level and
+in Django's validation. If you don't specify ``max_length``, a default of 200
 is used.
 
 ``USStateField``
             ('M', 'Male'),
             ('F', 'Female'),
         )
-        gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+        gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
 
 or outside your model class altogether::
 
         ('F', 'Female'),
     )
     class Foo(models.Model):
-        gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+        gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
 
 For each model field that has ``choices`` set, Django will add a method to
 retrieve the human-readable name for the field's current value. See
 form. It's useful for documentation even if your object doesn't have an
 admin form.
 
+Note that this value is *not* HTML-escaped when it's displayed in the admin
+interface. This lets you include HTML in ``help_text`` if you so desire. For
+example::
+
+	help_text="Please use the following format: <em>YYYY-MM-DD</em>."
+
 ``primary_key``
 ~~~~~~~~~~~~~~~