From 73ebb647bdfe5ca55614a6d4aa62131eed0d0b8c Mon Sep 17 00:00:00 2001 From: Bryan Brancotte <bryan.brancotte@pasteur.fr> Date: Fri, 30 Aug 2019 14:26:12 +0200 Subject: [PATCH] Ability to have hidden and always equal to email --- README.md | 1 + basetheme_bootstrap/forms.py | 64 ++++++++++++++++++++++++++++++++---- basetheme_bootstrap/tests.py | 42 +++++++++++++++++++++-- basetheme_bootstrap/views.py | 2 +- setup.py | 2 +- tests/settings.py | 1 + 6 files changed, 101 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2758b58..d3f0168 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ BASETHEME_BOOTSTRAP_TEMPLATE_LOCATION_PROJECT = "test_app_1" BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED = True BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_LOCATION_APP = "test_app_1" BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_NAME = "MyUserPreferences" +BASETHEME_BOOTSTRAP_USERNAME_IS_EMAIL = False ################################################################################ ``` diff --git a/basetheme_bootstrap/forms.py b/basetheme_bootstrap/forms.py index e1f9b62..af75713 100644 --- a/basetheme_bootstrap/forms.py +++ b/basetheme_bootstrap/forms.py @@ -1,13 +1,39 @@ -import itertools - +from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.forms import UserCreationForm, UsernameField, UserChangeForm -from django.db.models.query_utils import Q +from django.db.models import Q from django.forms import ModelForm -from django.utils.translation import ugettext as _ +from django.urls import reverse +from django.utils.safestring import mark_safe +from django.utils.translation import ugettext_lazy as _ + + +class CleanUsernameAndSuggestReset: + class Meta: + abstract = True + + @property + def is_username_is_email(self): + try: + return settings.BASETHEME_BOOTSTRAP_USERNAME_IS_EMAIL + except AttributeError: + return False + def clean(self): + f = super().clean() + qs = get_user_model().objects + if hasattr(self, 'instance'): + qs = qs.filter(~Q(id=self.instance.id)) + if qs.filter(email=f["email"]).exists() or \ + not self.is_username_is_email and \ + qs.filter(username=f.get("username", "")).exists(): + self.add_error("email", mark_safe(_( + 'The email already exists, if you have lost your password you can reset it ' + '<a href="%s">here</a>.') % (reverse('basetheme_bootstrap:password_reset')))) + return f -class UserCreationFormWithMore(UserCreationForm): + +class UserCreationFormWithMore(CleanUsernameAndSuggestReset, UserCreationForm): class Meta: model = get_user_model() fields = ("username", "email", "first_name", "last_name") @@ -16,15 +42,39 @@ class UserCreationFormWithMore(UserCreationForm): def __init__(self, *args, **kwargs): super(UserCreationFormWithMore, self).__init__(*args, **kwargs) self.fields['email'].widget.attrs.update({'required': True}) + if self.is_username_is_email: + del self.fields['username'] + + def save(self, commit=True): + user = super().save(commit=False) + if self.is_username_is_email: + user.username = user.email + if commit: + user.save() + return user -class MyUserChangeForm(UserChangeForm): +class MyUserChangeForm(CleanUsernameAndSuggestReset, UserChangeForm): class Meta: model = get_user_model() fields = ("username", "email", "first_name", "last_name", "password") + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + if self.is_username_is_email: + del self.fields['username'] + self.fields['email'].widget.attrs.update({'required': True}) + + def save(self, commit=True): + user = super().save(commit=False) + if self.is_username_is_email: + user.username = user.email + if commit: + user.save() + return user + class UserDeleteForm(ModelForm): class Meta: model = get_user_model() - fields = () \ No newline at end of file + fields = () diff --git a/basetheme_bootstrap/tests.py b/basetheme_bootstrap/tests.py index e0aff44..625dcf3 100644 --- a/basetheme_bootstrap/tests.py +++ b/basetheme_bootstrap/tests.py @@ -38,16 +38,54 @@ class SignUpTests(TestCase): def test_sign_up_form_view(self): user_count = get_user_model().objects.count() - response = self.client.post(reverse('basetheme_bootstrap:signup'), { + data = { 'username': "userAAA", 'email': "userAAA@mp.com", 'password1': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", 'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", 'first_name': "user" - }) + } + response = self.client.post(reverse('basetheme_bootstrap:signup'), data) self.assertEqual(response.status_code, 302) self.assertRedirects(response, expected_url=reverse('home'), ) self.assertEqual(get_user_model().objects.count(), user_count + 1) + user = get_user_model().objects.last() + self.assertEqual(user.username, data["username"]) + self.assertEqual(user.email, data["email"]) + + +@override_settings( + BASETHEME_BOOTSTRAP_USERNAME_IS_EMAIL=True, +) +class SignUpWithoutUsernameTests(TestCase): + + def test_sign_up_form_view(self): + user_count = get_user_model().objects.count() + data = { + 'email': "userAAA@mp.com", + 'password1': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", + 'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", + 'first_name': "user" + } + response = self.client.post(reverse('basetheme_bootstrap:signup'), data) + self.assertEqual(response.status_code, 302) + self.assertRedirects(response, expected_url=reverse('home'), ) + self.assertEqual(get_user_model().objects.count(), user_count + 1) + user = get_user_model().objects.last() + self.assertEqual(user.username, data["email"]) + self.assertEqual(user.email, data["email"]) + + def test_sign_up_detecte_duplicate_email(self): + get_user_model().objects.create(username="toto",email="userAAA@mp.com") + user_count = get_user_model().objects.count() + data = { + 'email': "userAAA@mp.com", + 'password1': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", + 'password2': "user@mp.comuser@mp.comuser@mp.comuser@mp.com", + 'first_name': "user" + } + response = self.client.post(reverse('basetheme_bootstrap:signup'), data) + self.assertEqual(response.status_code, 200) class TestWithTemplatesInPlace(SignUpTests): diff --git a/basetheme_bootstrap/views.py b/basetheme_bootstrap/views.py index c7d1c05..4c6f4e5 100644 --- a/basetheme_bootstrap/views.py +++ b/basetheme_bootstrap/views.py @@ -57,7 +57,7 @@ def signup(request): user.is_superuser = True user.is_staff = True user.save() - username = form.cleaned_data.get('username') + username = user.username raw_password = form.cleaned_data.get('password1') user = authenticate(username=username, password=raw_password) request.user = user diff --git a/setup.py b/setup.py index 2eeea07..b069a61 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ readme = open('README.rst').read() setup( name='django-basetheme-bootstrap', - version='0.2.6', + version='0.2.7', description='Django Basetheme Bootstrap', long_description=readme, author='Bryan Brancotte', diff --git a/tests/settings.py b/tests/settings.py index 374509b..842ee24 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -136,6 +136,7 @@ BASETHEME_BOOTSTRAP_TEMPLATE_LOCATION_PROJECT = "test_app_1" BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_ENABLED = True BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_LOCATION_APP = "test_app_1" BASETHEME_BOOTSTRAP_USER_PREFERENCE_MODEL_NAME = "MyUserPreferences" +# BASETHEME_BOOTSTRAP_USERNAME_IS_EMAIL = True # default is False ################################################################################ # Various debug stuff -- GitLab