Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5786: relaxed the validation for usernames to allow more commo…

…n characters '@', etc.

This is really just a stop-gap until we come up with a improved way of handling
disparate auth data, but it should help us stretch a bit more milage out of the
current system.

Thanks to alextreme, lbruno, and clayg.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12634 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c8015052d935a99a5c8f96434b2d0cd16d8a4e14 1 parent 6476516
Jacob Kaplan-Moss authored March 01, 2010
12  django/contrib/auth/forms.py
@@ -11,9 +11,9 @@ class UserCreationForm(forms.ModelForm):
11 11
     """
12 12
     A form that creates a user, with no privileges, from the given username and password.
13 13
     """
14  
-    username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^\w+$',
15  
-        help_text = _("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."),
16  
-        error_message = _("This value must contain only letters, numbers and underscores."))
  14
+    username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
  15
+        help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
  16
+        error_message = _("This value may contain only letters, numbers and @/./+/-/_ characters."))
17 17
     password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
18 18
     password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput,
19 19
         help_text = _("Enter the same password as above, for verification."))
@@ -45,9 +45,9 @@ def save(self, commit=True):
45 45
         return user
46 46
 
47 47
 class UserChangeForm(forms.ModelForm):
48  
-    username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^\w+$',
49  
-        help_text = _("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."),
50  
-        error_message = _("This value must contain only letters, numbers and underscores."))
  48
+    username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
  49
+        help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
  50
+        error_message = _("This value may contain only letters, numbers and @/./+/-/_ characters."))
51 51
     
52 52
     class Meta:
53 53
         model = User
2  django/contrib/auth/models.py
@@ -177,7 +177,7 @@ class User(models.Model):
177 177
 
178 178
     Username and password are required. Other fields are optional.
179 179
     """
180  
-    username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Alphanumeric characters only (letters, digits and underscores)."))
  180
+    username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
181 181
     first_name = models.CharField(_('first name'), max_length=30, blank=True)
182 182
     last_name = models.CharField(_('last name'), max_length=30, blank=True)
183 183
     email = models.EmailField(_('e-mail address'), blank=True)
10  django/contrib/auth/tests/forms.py
@@ -21,7 +21,7 @@
21 21
 # The username contains invalid data.
22 22
 
23 23
 >>> data = {
24  
-...     'username': 'jsmith@example.com',
  24
+...     'username': 'jsmith!',
25 25
 ...     'password1': 'test123',
26 26
 ...     'password2': 'test123',
27 27
 ... }
@@ -29,7 +29,7 @@
29 29
 >>> form.is_valid()
30 30
 False
31 31
 >>> form["username"].errors
32  
-[u'This value must contain only letters, numbers and underscores.']
  32
+[u'This value may contain only letters, numbers and @/./+/-/_ characters.']
33 33
 
34 34
 # The verification password is incorrect.
35 35
 
@@ -65,7 +65,7 @@
65 65
 # The success case.
66 66
 
67 67
 >>> data = {
68  
-...     'username': 'jsmith2',
  68
+...     'username': 'jsmith2@example.com',
69 69
 ...     'password1': 'test123',
70 70
 ...     'password2': 'test123',
71 71
 ... }
@@ -73,7 +73,7 @@
73 73
 >>> form.is_valid()
74 74
 True
75 75
 >>> form.save()
76  
-<User: jsmith2>
  76
+<User: jsmith2@example.com>
77 77
 
78 78
 # The user submits an invalid username.
79 79
 
@@ -189,7 +189,7 @@
189 189
 >>> form.is_valid()
190 190
 False
191 191
 >>> form['username'].errors
192  
-[u'This value must contain only letters, numbers and underscores.']
  192
+[u'This value may contain only letters, numbers and @/./+/-/_ characters.']
193 193
 
194 194
 
195 195
 ### PasswordResetForm
7  docs/releases/1.2.txt
@@ -742,3 +742,10 @@ views in your :ref:`URLconf <topics-http-urls>`. This means that you can
742 742
 maintain complete control over the URL structure of your feeds. Like any other view, feeds views are passed a ``request`` object, so you can
743 743
 do anything you would normally do with a view, like user based access control,
744 744
 or making a feed a named URL.
  745
+
  746
+Relaxed requirements for usernames
  747
+----------------------------------
  748
+
  749
+The built-in :class:`~django.contrib.auth.models.User` model's
  750
+:attr:`~django.contrib.auth.models.User.username` field now allows a wider range
  751
+of characters, including ``@``, ``+``, ``.`` and ``-`` characters.
3  docs/topics/auth.txt
@@ -71,6 +71,9 @@ Fields
71 71
 
72 72
         Required. 30 characters or fewer. Alphanumeric characters only
73 73
         (letters, digits and underscores).
  74
+        
  75
+        .. versionchanged:: 1.2
  76
+           Usernames may now contain ``@``, ``+``, ``.`` and ``-`` characters.
74 77
 
75 78
     .. attribute:: models.User.first_name
76 79
 

0 notes on commit c801505

Please sign in to comment.
Something went wrong with that request. Please try again.