From e7939bb30d26f98c03f895ef0a20986718f865a5 Mon Sep 17 00:00:00 2001 From: AMeng Date: Fri, 15 May 2015 21:42:54 -0600 Subject: [PATCH] Support custom user models with the RegistrationForm. Add tests. --- registration/admin.py | 7 +-- registration/forms.py | 6 +-- registration/tests/forms.py | 6 ++- registration/tests/forms_custom_user.py | 64 +++++++++++++++++++++++++ registration/users.py | 4 ++ test_app/models.py | 14 ++++++ 6 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 registration/tests/forms_custom_user.py diff --git a/registration/admin.py b/registration/admin.py index 03e08574..1b56f9ec 100644 --- a/registration/admin.py +++ b/registration/admin.py @@ -4,19 +4,20 @@ from django.utils.translation import ugettext_lazy as _ from registration.models import RegistrationProfile +from registration.users import UsernameField class RegistrationAdmin(admin.ModelAdmin): actions = ['activate_users', 'resend_activation_email'] list_display = ('user', 'activation_key_expired') raw_id_fields = ['user'] - search_fields = ('user__username', 'user__first_name', 'user__last_name') + search_fields = ('user__{0}'.format(UsernameField()), 'user__first_name', 'user__last_name') def activate_users(self, request, queryset): """ Activates the selected users, if they are not already activated. - + """ for profile in queryset: RegistrationProfile.objects.activate_user(profile.activation_key) @@ -30,7 +31,7 @@ def resend_activation_email(self, request, queryset): who are eligible to activate; emails will not be sent to users whose activation keys have expired or who have already activated. - + """ if Site._meta.installed: site = Site.objects.get_current() diff --git a/registration/forms.py b/registration/forms.py index b7fdc34b..3b46b0db 100644 --- a/registration/forms.py +++ b/registration/forms.py @@ -14,7 +14,7 @@ from django.utils.translation import ugettext_lazy as _ from django.contrib.auth.forms import UserCreationForm -from registration.users import UserModel +from registration.users import UserModel, UsernameField class RegistrationForm(UserCreationForm): @@ -32,10 +32,10 @@ class RegistrationForm(UserCreationForm): """ required_css_class = 'required' email = forms.EmailField(label=_("E-mail")) - + class Meta: model = UserModel() - fields = ("username", "email") + fields = (UsernameField(), "email") class RegistrationFormTermsOfService(RegistrationForm): diff --git a/registration/tests/forms.py b/registration/tests/forms.py index a182ee4b..3d24cbb9 100644 --- a/registration/tests/forms.py +++ b/registration/tests/forms.py @@ -8,11 +8,15 @@ from registration.users import UserModel +DJANGO_VERSION = StrictVersion(get_version()) + + class RegistrationFormTests(TestCase): """ Test the default registration forms. """ + def test_registration_form(self): """ Test that ``RegistrationForm`` enforces username constraints @@ -24,7 +28,7 @@ def test_registration_form(self): UserModel().objects.create_user('alice', 'alice@example.com', 'secret') bad_username_error = 'This value may contain only letters, numbers and @/./+/-/_ characters.' - if StrictVersion(get_version()) >= StrictVersion('1.8'): + if DJANGO_VERSION >= StrictVersion('1.8'): bad_username_error = 'Enter a valid username. ' + bad_username_error invalid_data_dicts = [ diff --git a/registration/tests/forms_custom_user.py b/registration/tests/forms_custom_user.py new file mode 100644 index 00000000..533f3e00 --- /dev/null +++ b/registration/tests/forms_custom_user.py @@ -0,0 +1,64 @@ +from __future__ import unicode_literals +from distutils.version import StrictVersion +try: + from importlib import reload # Python 3.4+ reload() +except: + try: + from imp import reload # Python 3.0+ reload() + except: + pass # Python 2 reload() + +from django import get_version +from django.conf import settings +from django.test import TestCase + +from registration import forms +from registration.users import UsernameField +from test_app.models import CustomUser + + +DJANGO_VERSION = StrictVersion(get_version()) + + +class RegistrationFormTests(TestCase): + """ + Test the default registration forms. + + """ + def setUp(self): + self.old_auth_model = getattr(settings, 'AUTH_USER_MODEL', None) + settings.AUTH_USER_MODEL = 'test_app.CustomUser' + # The form's Meta class is created on import. We have to reload() + # to apply the new AUTH_USER_MODEL to the Meta class. + reload(forms) + + def tearDown(self): + settings.AUTH_USER_MODEL = self.old_auth_model + + def test_registration_form_adds_custom_user_name_field(self): + """ + Test that ``RegistrationForm`` adds custom username + field and does not raise errors + + """ + + form = forms.RegistrationForm() + + self.assertTrue(UsernameField() in form.fields) + + + def test_registration_form_subclass_is_valid_for_django_18(self): + """ + Test that ``RegistrationForm`` subclasses can save in + Django > 1.8 + + """ + if DJANGO_VERSION >= StrictVersion('1.8'): + data = {'new_field': 'custom username', + 'email': 'foo@example.com', + 'password1': 'foo', + 'password2': 'foo'} + + form = forms.RegistrationForm(data=data) + + self.assertTrue(form.is_valid()) diff --git a/registration/users.py b/registration/users.py index a4dcbd09..e3122ba9 100644 --- a/registration/users.py +++ b/registration/users.py @@ -15,3 +15,7 @@ def UserModelString(): return settings.AUTH_USER_MODEL except AttributeError: return 'auth.User' + + +def UsernameField(): + return getattr(UserModel(), 'USERNAME_FIELD', 'username') diff --git a/test_app/models.py b/test_app/models.py index 57d631c3..9af1deea 100644 --- a/test_app/models.py +++ b/test_app/models.py @@ -1 +1,15 @@ # coding: utf-8 + +try: + from django.contrib.auth.models import AbstractBaseUser, BaseUserManager +except ImportError: + from django.contrib.auth.models import User as AbstractBaseUser, UserManager as BaseUserManager + +from django.db import models + + +class CustomUser(AbstractBaseUser): + new_field = models.CharField(max_length=25) + objects = BaseUserManager() + + USERNAME_FIELD = 'new_field'