mirror of
https://github.com/django/django.git
synced 2024-11-29 14:46:18 +01:00
Fixed #13147 -- Moved User validation logic from form to model.
This commit is contained in:
parent
d88333661b
commit
849538d03d
@ -74,16 +74,8 @@ class UserCreationForm(forms.ModelForm):
|
|||||||
password.
|
password.
|
||||||
"""
|
"""
|
||||||
error_messages = {
|
error_messages = {
|
||||||
'duplicate_username': _("A user with that username already exists."),
|
|
||||||
'password_mismatch': _("The two password fields didn't match."),
|
'password_mismatch': _("The two password fields didn't match."),
|
||||||
}
|
}
|
||||||
username = forms.RegexField(label=_("Username"), max_length=30,
|
|
||||||
regex=r'^[\w.@+-]+$',
|
|
||||||
help_text=_("Required. 30 characters or fewer. Letters, digits and "
|
|
||||||
"@/./+/-/_ only."),
|
|
||||||
error_messages={
|
|
||||||
'invalid': _("This value may contain only letters, numbers and "
|
|
||||||
"@/./+/-/_ characters.")})
|
|
||||||
password1 = forms.CharField(label=_("Password"),
|
password1 = forms.CharField(label=_("Password"),
|
||||||
widget=forms.PasswordInput)
|
widget=forms.PasswordInput)
|
||||||
password2 = forms.CharField(label=_("Password confirmation"),
|
password2 = forms.CharField(label=_("Password confirmation"),
|
||||||
@ -94,19 +86,6 @@ class UserCreationForm(forms.ModelForm):
|
|||||||
model = User
|
model = User
|
||||||
fields = ("username",)
|
fields = ("username",)
|
||||||
|
|
||||||
def clean_username(self):
|
|
||||||
# Since User.username is unique, this check is redundant,
|
|
||||||
# but it sets a nicer error message than the ORM. See #13147.
|
|
||||||
username = self.cleaned_data["username"]
|
|
||||||
try:
|
|
||||||
User._default_manager.get(username=username)
|
|
||||||
except User.DoesNotExist:
|
|
||||||
return username
|
|
||||||
raise forms.ValidationError(
|
|
||||||
self.error_messages['duplicate_username'],
|
|
||||||
code='duplicate_username',
|
|
||||||
)
|
|
||||||
|
|
||||||
def clean_password2(self):
|
def clean_password2(self):
|
||||||
password1 = self.cleaned_data.get("password1")
|
password1 = self.cleaned_data.get("password1")
|
||||||
password2 = self.cleaned_data.get("password2")
|
password2 = self.cleaned_data.get("password2")
|
||||||
@ -126,13 +105,6 @@ class UserCreationForm(forms.ModelForm):
|
|||||||
|
|
||||||
|
|
||||||
class UserChangeForm(forms.ModelForm):
|
class UserChangeForm(forms.ModelForm):
|
||||||
username = forms.RegexField(
|
|
||||||
label=_("Username"), max_length=30, regex=r"^[\w.@+-]+$",
|
|
||||||
help_text=_("Required. 30 characters or fewer. Letters, digits and "
|
|
||||||
"@/./+/-/_ only."),
|
|
||||||
error_messages={
|
|
||||||
'invalid': _("This value may contain only letters, numbers and "
|
|
||||||
"@/./+/-/_ characters.")})
|
|
||||||
password = ReadOnlyPasswordHashField(label=_("Password"),
|
password = ReadOnlyPasswordHashField(label=_("Password"),
|
||||||
help_text=_("Raw passwords are not stored, so there is no way to see "
|
help_text=_("Raw passwords are not stored, so there is no way to see "
|
||||||
"this user's password, but you can change the password "
|
"this user's password, but you can change the password "
|
||||||
|
@ -383,8 +383,14 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
|||||||
help_text=_('Required. 30 characters or fewer. Letters, digits and '
|
help_text=_('Required. 30 characters or fewer. Letters, digits and '
|
||||||
'@/./+/-/_ only.'),
|
'@/./+/-/_ only.'),
|
||||||
validators=[
|
validators=[
|
||||||
validators.RegexValidator(r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid')
|
validators.RegexValidator(r'^[\w.@+-]+$',
|
||||||
])
|
_('Enter a valid username. '
|
||||||
|
'This value may contain only letters, numbers '
|
||||||
|
'and @/./+/-/_ characters.'), 'invalid'),
|
||||||
|
],
|
||||||
|
error_messages={
|
||||||
|
'unique': _("A user with that username already exists."),
|
||||||
|
})
|
||||||
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
first_name = models.CharField(_('first name'), max_length=30, blank=True)
|
||||||
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
last_name = models.CharField(_('last name'), max_length=30, blank=True)
|
||||||
email = models.EmailField(_('email address'), blank=True)
|
email = models.EmailField(_('email address'), blank=True)
|
||||||
|
@ -4,7 +4,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth import get_user_model
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
|
from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
|
||||||
PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm,
|
PasswordChangeForm, SetPasswordForm, UserChangeForm, PasswordResetForm,
|
||||||
@ -36,7 +35,7 @@ class UserCreationFormTest(TestCase):
|
|||||||
form = UserCreationForm(data)
|
form = UserCreationForm(data)
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
self.assertEqual(form["username"].errors,
|
self.assertEqual(form["username"].errors,
|
||||||
[force_text(form.error_messages['duplicate_username'])])
|
[force_text(User._meta.get_field('username').error_messages['unique'])])
|
||||||
|
|
||||||
def test_invalid_data(self):
|
def test_invalid_data(self):
|
||||||
data = {
|
data = {
|
||||||
@ -46,8 +45,8 @@ class UserCreationFormTest(TestCase):
|
|||||||
}
|
}
|
||||||
form = UserCreationForm(data)
|
form = UserCreationForm(data)
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
self.assertEqual(form["username"].errors,
|
validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid')
|
||||||
[force_text(form.fields['username'].error_messages['invalid'])])
|
self.assertEqual(form["username"].errors, [force_text(validator.message)])
|
||||||
|
|
||||||
def test_password_verification(self):
|
def test_password_verification(self):
|
||||||
# The verification password is incorrect.
|
# The verification password is incorrect.
|
||||||
@ -190,8 +189,7 @@ class AuthenticationFormTest(TestCase):
|
|||||||
username = CharField()
|
username = CharField()
|
||||||
|
|
||||||
form = CustomAuthenticationForm()
|
form = CustomAuthenticationForm()
|
||||||
UserModel = get_user_model()
|
username_field = User._meta.get_field(User.USERNAME_FIELD)
|
||||||
username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
|
|
||||||
self.assertEqual(form.fields['username'].label, capfirst(username_field.verbose_name))
|
self.assertEqual(form.fields['username'].label, capfirst(username_field.verbose_name))
|
||||||
|
|
||||||
def test_username_field_label_empty_string(self):
|
def test_username_field_label_empty_string(self):
|
||||||
@ -291,8 +289,8 @@ class UserChangeFormTest(TestCase):
|
|||||||
data = {'username': 'not valid'}
|
data = {'username': 'not valid'}
|
||||||
form = UserChangeForm(data, instance=user)
|
form = UserChangeForm(data, instance=user)
|
||||||
self.assertFalse(form.is_valid())
|
self.assertFalse(form.is_valid())
|
||||||
self.assertEqual(form['username'].errors,
|
validator = next(v for v in User._meta.get_field('username').validators if v.code == 'invalid')
|
||||||
[force_text(form.fields['username'].error_messages['invalid'])])
|
self.assertEqual(form["username"].errors, [force_text(validator.message)])
|
||||||
|
|
||||||
def test_bug_14242(self):
|
def test_bug_14242(self):
|
||||||
# A regression test, introduce by adding an optimization for the
|
# A regression test, introduce by adding an optimization for the
|
||||||
|
@ -414,6 +414,10 @@ Miscellaneous
|
|||||||
parameters. Internally, Django will continue to provide the
|
parameters. Internally, Django will continue to provide the
|
||||||
``pk`` parameter in ``params`` for backwards compatibility.
|
``pk`` parameter in ``params`` for backwards compatibility.
|
||||||
|
|
||||||
|
* ``UserCreationForm.errors_messages['duplicate_username']`` is no longer used.
|
||||||
|
If you wish to customize that error message, use
|
||||||
|
``User.error_messages['unique']`` instead.
|
||||||
|
|
||||||
.. _deprecated-features-1.8:
|
.. _deprecated-features-1.8:
|
||||||
|
|
||||||
Features deprecated in 1.8
|
Features deprecated in 1.8
|
||||||
|
Loading…
Reference in New Issue
Block a user