Kaydet (Commit) f0425c72 authored tarafından Berker Peksag's avatar Berker Peksag Kaydeden (comit) Tim Graham

Refs #19353 -- Added tests for using custom user models with built-in auth forms.

Also updated topics/auth/customizing.txt to reflect that subclasses of
UserCreationForm and UserChangeForm can be used with custom user models.

Thanks Baptiste Mispelon for the initial documentation.
üst d4dc7756
...@@ -733,47 +733,45 @@ the "Model design considerations" note of :ref:`specifying-custom-user-model`. ...@@ -733,47 +733,45 @@ the "Model design considerations" note of :ref:`specifying-custom-user-model`.
Custom users and the built-in auth forms Custom users and the built-in auth forms
---------------------------------------- ----------------------------------------
As you may expect, built-in Django's :ref:`forms <built-in-auth-forms>` and Django's built-in :ref:`forms <built-in-auth-forms>` and :ref:`views
:ref:`views <built-in-auth-views>` make certain assumptions about the user <built-in-auth-views>` make certain assumptions about the user model that they
model that they are working with. are working with.
If your user model doesn't follow the same assumptions, it may be necessary to define The following forms are compatible with any subclass of
a replacement form, and pass that form in as part of the configuration of the :class:`~django.contrib.auth.models.AbstractBaseUser`:
auth views.
* :class:`~django.contrib.auth.forms.UserCreationForm`
Depends on the :class:`~django.contrib.auth.models.User` model.
Must be re-written for any custom user model.
* :class:`~django.contrib.auth.forms.UserChangeForm`
Depends on the :class:`~django.contrib.auth.models.User` model.
Must be re-written for any custom user model.
* :class:`~django.contrib.auth.forms.AuthenticationForm`
Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser`,
and will adapt to use the field defined in ``USERNAME_FIELD``.
* :class:`~django.contrib.auth.forms.PasswordResetForm` * :class:`~django.contrib.auth.forms.AuthenticationForm`: Uses the username
field specified by :attr:`~models.CustomUser.USERNAME_FIELD`.
* :class:`~django.contrib.auth.forms.SetPasswordForm`
* :class:`~django.contrib.auth.forms.PasswordChangeForm`
* :class:`~django.contrib.auth.forms.AdminPasswordChangeForm`
Assumes that the user model has a field named ``email`` that can be used to The following forms make assumptions about the user model and can be used as-is
identify the user and a boolean field named ``is_active`` to prevent if those assumptions are met:
password resets for inactive users.
* :class:`~django.contrib.auth.forms.SetPasswordForm` * :class:`~django.contrib.auth.forms.PasswordResetForm`: Assumes that the user
model has a field named ``email`` that can be used to identify the user and a
boolean field named ``is_active`` to prevent password resets for inactive
users.
Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser` Finally, the following forms are tied to
:class:`~django.contrib.auth.models.User` and need to be rewritten or extended
to work with a custom user model:
* :class:`~django.contrib.auth.forms.PasswordChangeForm` * :class:`~django.contrib.auth.forms.UserCreationForm`
* :class:`~django.contrib.auth.forms.UserChangeForm`
Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser` If your custom user model is a simple subclass of ``AbstractUser``, then you
can extend these forms in this manner::
* :class:`~django.contrib.auth.forms.AdminPasswordChangeForm` from django.contrib.auth.forms import UserCreationForm
from myapp.models import CustomUser
Works with any subclass of :class:`~django.contrib.auth.models.AbstractBaseUser` class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = UserCreationForm.Meta.fields + ('custom_field',)
Custom users and :mod:`django.contrib.admin` Custom users and :mod:`django.contrib.admin`
-------------------------------------------- --------------------------------------------
......
from __future__ import unicode_literals from __future__ import unicode_literals
import datetime
import re import re
from django import forms from django import forms
...@@ -19,6 +20,7 @@ from django.utils.encoding import force_text ...@@ -19,6 +20,7 @@ from django.utils.encoding import force_text
from django.utils.text import capfirst from django.utils.text import capfirst
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from .models.custom_user import ExtensionUser
from .settings import AUTH_TEMPLATES from .settings import AUTH_TEMPLATES
...@@ -122,6 +124,21 @@ class UserCreationFormTest(TestDataMixin, TestCase): ...@@ -122,6 +124,21 @@ class UserCreationFormTest(TestDataMixin, TestCase):
form['password2'].errors form['password2'].errors
) )
def test_custom_form(self):
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = ExtensionUser
fields = UserCreationForm.Meta.fields + ('date_of_birth',)
data = {
'username': 'testclient',
'password1': 'testclient',
'password2': 'testclient',
'date_of_birth': '1988-02-24',
}
form = CustomUserCreationForm(data)
self.assertTrue(form.is_valid())
class AuthenticationFormTest(TestDataMixin, TestCase): class AuthenticationFormTest(TestDataMixin, TestCase):
...@@ -407,6 +424,24 @@ class UserChangeFormTest(TestDataMixin, TestCase): ...@@ -407,6 +424,24 @@ class UserChangeFormTest(TestDataMixin, TestCase):
# value to render correctly # value to render correctly
self.assertEqual(form.initial['password'], form['password'].value()) self.assertEqual(form.initial['password'], form['password'].value())
def test_custom_form(self):
class CustomUserChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = ExtensionUser
fields = ('username', 'password', 'date_of_birth',)
user = User.objects.get(username='testclient')
data = {
'username': 'testclient',
'password': 'testclient',
'date_of_birth': '1998-02-24',
}
form = CustomUserChangeForm(data, instance=user)
self.assertTrue(form.is_valid())
form.save()
self.assertEqual(form.cleaned_data['username'], 'testclient')
self.assertEqual(form.cleaned_data['date_of_birth'], datetime.date(1998, 2, 24))
@override_settings(TEMPLATES=AUTH_TEMPLATES) @override_settings(TEMPLATES=AUTH_TEMPLATES)
class PasswordResetFormTest(TestDataMixin, TestCase): class PasswordResetFormTest(TestDataMixin, TestCase):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment