Commits

Anonymous committed fa915e4

Add configurable form_class kwarg to registration view, and example subclasses

Comments (0)

Files changed (2)

registration/forms.py

 """
-Form and validation code for user registration.
+Forms and validation code for user registration.
 
 """
 
 from django import newforms as forms
 from django.contrib.auth.models import User
 
+from registration.models import RegistrationProfile
+
 
 # I put this on all required fields, because it's easier to pick up
 # on them with CSS or JavaScript if they have a class of "required"
         if self.cleaned_data.get('tos', False):
             return self.cleaned_data['tos']
         raise forms.ValidationError(u'You must agree to the terms to register')
+
+    def save(self):
+        """
+        Creates the new ``User`` and ``RegistrationProfile``, and
+        returns the ``User``.
+
+        """
+        new_user = RegistrationProfile.objects.create_inactive_user(username=form.cleaned_data['username'],
+                                                                    password=form.cleaned_data['password1'],
+                                                                    email=form.cleaned_data['email'],
+                                                                    profile_callback=profile_callback)
+        return new_user
+
+
+class RegistrationFormUniqueEmail(RegistrationForm):
+    """
+    Subclass of ``RegistrationForm`` which enforces uniqueness of
+    email addresses.
+    
+    """
+    def clean_email(self):
+        """
+        Validates that the supplied email address is unique for the
+        site.
+        
+        """
+        if 'email' in self.cleaned_data:
+            try:
+                user = User.objects.get(email__exact=self.cleaned_data['email'])
+            except User.DoesNotExist:
+                return self.cleaned_data['email']
+            raise forms.ValidationError(u'This email address is already in use. Please supply a different email address.')
+
+
+class RegistrationFormNoFreeEmail(RegistrationForm):
+    """
+    Subclass of ``RegistrationForm`` which disallows registration with
+    email addresses from popular free webmail services; moderately
+    useful for preventing automated spam registrations.
+    
+    """
+    bad_domains = ['aim.com', 'aol.com', 'email.com', 'gmail.com',
+                   'googlemail.com', 'hotmail.com', 'hushmail.com',
+                   'live.com', 'msn.com', 'mail.ru']
+    
+    def clean_email(self):
+        """
+        Checks the supplied email address against a list of known free
+        webmail domains.
+        
+        """
+        if 'email' in self.cleaned_data:
+            email_domain = self.cleaned_data['email'].split('@')[1]
+            if email_domain in self.bad_domains:
+                raise forms.ValidationError(u'Registration using free email addresses is prohibited. Please supply a different email address.')
+            return self.cleaned_data['email']

registration/views.py

                               context_instance=RequestContext(request))
 
 
-def register(request, success_url='/accounts/register/complete/', profile_callback=None):
+def register(request, success_url='/accounts/register/complete/', form_class=RegistrationForm, profile_callback=None):
     """
     Allows a new user to register an account.
     
     for that URL and routes it to the ``direct_to_template`` generic
     view to display a short message telling the user to check their
     email for the account activation link.
+
+    By default, uses ``registration.forms.RegistrationForm`` as the
+    form; to change this, pass a different form class as the
+    ``form_class`` keyword argument.
     
     To enable creation of a site-specific user profile object for the
     new user, pass a function which will create the profile object as
     
     """
     if request.method == 'POST':
-        form = RegistrationForm(request.POST)
+        form = form_class(request.POST)
         if form.is_valid():
-            new_user = RegistrationProfile.objects.create_inactive_user(username=form.cleaned_data['username'],
-                                                                        password=form.cleaned_data['password1'],
-                                                                        email=form.cleaned_data['email'],
-                                                                        profile_callback=profile_callback)
+            new_user = form.save()
             return HttpResponseRedirect(success_url)
     else:
-        form = RegistrationForm()
+        form = form_class()
     return render_to_response('registration/registration_form.html',
                               { 'form': form },
                               context_instance=RequestContext(request))