From 7fd55c3481a004afb049e15ae3b8c93ce8bf0603 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Mon, 30 Jun 2014 14:34:45 -0400 Subject: [PATCH] Fixed #20631 -- Increased the default EmailField max_length to 254. Thanks pmartin for the report. --- .../0003_alter_user_email_max_length.py | 19 +++++++++++++++++++ django/core/validators.py | 4 +++- django/db/models/fields/__init__.py | 6 ++---- docs/ref/models/fields.txt | 12 ++++-------- docs/releases/1.8.txt | 11 +++++++++++ tests/field_deconstruction/tests.py | 2 +- tests/inspectdb/tests.py | 2 +- tests/introspection/tests.py | 2 +- tests/max_lengths/tests.py | 2 +- tests/validators/tests.py | 3 +++ 10 files changed, 46 insertions(+), 17 deletions(-) create mode 100644 django/contrib/auth/migrations/0003_alter_user_email_max_length.py diff --git a/django/contrib/auth/migrations/0003_alter_user_email_max_length.py b/django/contrib/auth/migrations/0003_alter_user_email_max_length.py new file mode 100644 index 0000000000..a9b8058089 --- /dev/null +++ b/django/contrib/auth/migrations/0003_alter_user_email_max_length.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0002_alter_permission_name_max_length'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='email', + field=models.EmailField(max_length=254, verbose_name='email address', blank=True), + ), + ] diff --git a/django/core/validators.py b/django/core/validators.py index 1e599ec765..315c2c6318 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -124,7 +124,9 @@ class EmailValidator(object): r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)', # quoted-string re.IGNORECASE) domain_regex = re.compile( - r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?": Must be "Author" instance. +Default ``EmailField.max_length`` increased to 254 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The old default 75 character ``max_length`` was not capable of storing all +possible RFC3696/5321-compliant email addresses. In order to store all +possible valid email addresses, the ``max_length`` has been increased to 254 +characters. You will need to generate and apply database migrations for your +affected models (or add ``max_length=75`` if you wish to keep the length on +your current fields). A migration for +:attr:`django.contrib.auth.models.User.email` is included. + Miscellaneous ~~~~~~~~~~~~~ diff --git a/tests/field_deconstruction/tests.py b/tests/field_deconstruction/tests.py index 04d4c6a6ad..2f0732a60e 100644 --- a/tests/field_deconstruction/tests.py +++ b/tests/field_deconstruction/tests.py @@ -128,7 +128,7 @@ class FieldDeconstructionTests(TestCase): name, path, args, kwargs = field.deconstruct() self.assertEqual(path, "django.db.models.EmailField") self.assertEqual(args, []) - self.assertEqual(kwargs, {"max_length": 75}) + self.assertEqual(kwargs, {"max_length": 254}) field = models.EmailField(max_length=255) name, path, args, kwargs = field.deconstruct() self.assertEqual(path, "django.db.models.EmailField") diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index c0babe390e..c0502198d8 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -54,7 +54,7 @@ class InspectDBTestCase(TestCase): assertFieldType('date_time_field', "models.DateTimeField()") if (connection.features.can_introspect_max_length and not connection.features.interprets_empty_strings_as_nulls): - assertFieldType('email_field', "models.CharField(max_length=75)") + assertFieldType('email_field', "models.CharField(max_length=254)") assertFieldType('file_field', "models.CharField(max_length=100)") assertFieldType('file_path_field', "models.CharField(max_length=100)") if connection.features.can_introspect_ip_address_field: diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py index 03962b33bf..d04fa0a6d1 100644 --- a/tests/introspection/tests.py +++ b/tests/introspection/tests.py @@ -70,7 +70,7 @@ class IntrospectionTests(TestCase): desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) self.assertEqual( [r[3] for r in desc if datatype(r[1], r) == 'CharField'], - [30, 30, 75] + [30, 30, 254] ) @skipUnlessDBFeature('can_introspect_null') diff --git a/tests/max_lengths/tests.py b/tests/max_lengths/tests.py index 25101cd535..64edaa6f59 100644 --- a/tests/max_lengths/tests.py +++ b/tests/max_lengths/tests.py @@ -11,7 +11,7 @@ class MaxLengthArgumentsTests(unittest.TestCase): self.assertEqual(model._meta.get_field(field).max_length, length) def test_default_max_lengths(self): - self.verify_max_length(PersonWithDefaultMaxLengths, 'email', 75) + self.verify_max_length(PersonWithDefaultMaxLengths, 'email', 254) self.verify_max_length(PersonWithDefaultMaxLengths, 'vcard', 100) self.verify_max_length(PersonWithDefaultMaxLengths, 'homepage', 200) self.verify_max_length(PersonWithDefaultMaxLengths, 'avatar', 100) diff --git a/tests/validators/tests.py b/tests/validators/tests.py index f586270040..b4b6a57207 100644 --- a/tests/validators/tests.py +++ b/tests/validators/tests.py @@ -66,6 +66,9 @@ TEST_DATA = ( (validate_email, '"\\\011"@here.com', None), (validate_email, '"\\\012"@here.com', ValidationError), (validate_email, 'trailingdot@shouldfail.com.', ValidationError), + # Max length of domain name in email is 251 (see validator for calculation) + (validate_email, 'a@%s.com' % ('a' * 251), None), + (validate_email, 'a@%s.com' % ('a' * 252), ValidationError), (validate_slug, 'slug-ok', None), (validate_slug, 'longer-slug-still-ok', None),