From a7d3a2c29add2278e4e9aa3fd8e5ff847a3c9a87 Mon Sep 17 00:00:00 2001 From: Stephen Burrows Date: Fri, 7 Oct 2011 18:03:53 -0700 Subject: [PATCH] Abstracted email resetting during the email change process onto the AccountForm. Addresses bug #173. --- philo/contrib/waldo/forms.py | 24 ++++++++++++++++++++++++ philo/contrib/waldo/models.py | 16 ++++------------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/philo/contrib/waldo/forms.py b/philo/contrib/waldo/forms.py index eb53598..8e14ba5 100644 --- a/philo/contrib/waldo/forms.py +++ b/philo/contrib/waldo/forms.py @@ -74,6 +74,30 @@ class UserAccountForm(forms.ModelForm): kwargs['instance'] = user super(UserAccountForm, self).__init__(*args, **kwargs) + def email_changed(self): + """Returns ``True`` if the email field changed value and ``False`` if it did not, or if there is no email field on the form. This method must be supplied by account forms used with :mod:`~philo.contrib.waldo`.""" + return 'email' in self.changed_data + + def reset_email(self): + """ + ModelForms modify their instances in-place during :meth:`_post_clean`; this method resets the email value to its initial state and returns the altered value. This is a method on the form to allow unusual behavior such as storing email on a :class:`UserProfile`. + + """ + email = self.instance.email + self.instance.email = self.initial['email'] + self.cleaned_data.pop('email') + return email + + @classmethod + def set_email(cls, user, email): + """ + Given a valid instance and an email address, correctly set the email address for that instance and save the changes. This is a class method in order to allow unusual behavior such as storing email on a :class:`UserProfile`. + + """ + user.email = email + user.save() + + class Meta: model = User fields = ('first_name', 'last_name', 'email') diff --git a/philo/contrib/waldo/models.py b/philo/contrib/waldo/models.py index 730b7db..cdadead 100644 --- a/philo/contrib/waldo/models.py +++ b/philo/contrib/waldo/models.py @@ -444,15 +444,8 @@ class AccountMultiView(RegistrationMultiView): if form.is_valid(): message = "Account information saved." redirect = self.get_requirement_redirect(request, default='') - if 'email' in form.changed_data and self.email_change_confirmation_email: - # ModelForms modify their instances in-place during - # validation, so reset the instance's email to its - # previous value here, then remove the new value - # from cleaned_data. We only do this if an email - # change confirmation email is available. - request.user.email = form.initial['email'] - - email = form.cleaned_data.pop('email') + if form.email_changed() and self.email_change_confirmation_email: + email = form.reset_email() current_site = Site.objects.get_current() @@ -464,7 +457,7 @@ class AccountMultiView(RegistrationMultiView): } self.send_confirmation_email('Confirm account email change at %s' % current_site.domain, email, self.email_change_confirmation_email, context) - message = "An email has be sent to %s to confirm the email%s." % (email, bool(request.user.email) and " change" or "") + message = "An email has be sent to %s to confirm the email%s." % (email, " change" if bool(request.user.email) else "") if not request.user.email: message += " You will need to confirm the email before accessing pages that require a valid account." redirect = '' @@ -538,8 +531,7 @@ class AccountMultiView(RegistrationMultiView): raise Http404 if token_generator.check_token(user, email, token): - user.email = email - user.save() + self.account_form.set_email(user, email) messages.add_message(request, messages.SUCCESS, 'Email changed successfully.') if self.manage_account_page: redirect = self.reverse('account', node=request.node) -- 2.20.1