Commits

James Turnbull committed 86308da

Applied patch from issue 26

Comments (0)

Files changed (4)

registration/forms.py

 Forms and validation code for user registration.
 
 """
+from django.db.models import get_model
+from django.conf import settings
 
+try:
+    user_model = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
+except AttributeError:
+    from django.contrib.auth.models import User as user_model
 
-from django.contrib.auth.models import User
 from django import forms
 from django.utils.translation import ugettext_lazy as _
 
     
     Subclasses should feel free to add any additional validation they
     need, but should either preserve the base ``save()`` or implement
-    a ``save()`` method which returns a ``User``.
+    a ``save()`` method which returns a ``user_model``.
     
     """
     username = forms.RegexField(regex=r'^\w+$',
         
         """
         try:
-            user = User.objects.get(username__iexact=self.cleaned_data['username'])
-        except User.DoesNotExist:
+            user = user_model.objects.get(username__iexact=self.cleaned_data['username'])
+        except user_model.DoesNotExist:
             return self.cleaned_data['username']
         raise forms.ValidationError(_(u'This username is already taken. Please choose another.'))
 
     
     def save(self):
         """
-        Create the new ``User`` and ``RegistrationProfile``, and
-        returns the ``User`` (by calling
+        Create the new ``user_model`` and ``RegistrationProfile``, and
+        returns the ``user_model`` (by calling
         ``RegistrationProfile.objects.create_inactive_user()``).
         
         """
-        new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],
-                                                                    password=self.cleaned_data['password1'],
-                                                                    email=self.cleaned_data['email'])
+        attributes = {
+            'username': self.cleaned_data['username'],
+            'password': self.cleaned_data['password1'],
+            'email': self.cleaned_data['email'],
+        }
+        new_user = RegistrationProfile.objects.create_inactive_user(**attributes)
         return new_user
 
 
         site.
         
         """
-        if User.objects.filter(email__iexact=self.cleaned_data['email']):
+        if user_model.objects.filter(email__iexact=self.cleaned_data['email']):
             raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.'))
         return self.cleaned_data['email']
 

registration/models.py

 import re
 
 from django.conf import settings
-from django.contrib.auth.models import User
 from django.contrib.sites.models import Site
 from django.db import models
 from django.db import transaction
 from django.template.loader import render_to_string
 from django.utils.hashcompat import sha_constructor
 from django.utils.translation import ugettext_lazy as _
+from django.db.models import get_model
 
 
 SHA1_RE = re.compile('^[a-f0-9]{40}$')
 
+try:
+    user_model = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
+except AttributeError:
+    from django.contrib.auth.models import User as user_model
+
 
 class RegistrationManager(models.Manager):
     """
     def activate_user(self, activation_key):
         """
         Validate an activation key and activate the corresponding
-        ``User`` if valid.
+        ``user_model`` if valid.
         
-        If the key is valid and has not expired, return the ``User``
+        If the key is valid and has not expired, return the ``user_model``
         after activating.
         
         If the key is not valid or has expired, return ``False``.
         
-        If the key is valid but the ``User`` is already active,
+        If the key is valid but the ``user_model`` is already active,
         return ``False``.
         
         To prevent reactivation of an account which has been
         reset to the string constant ``RegistrationProfile.ACTIVATED``
         after successful activation.
 
-        To execute customized logic when a ``User`` is activated,
+        To execute customized logic when a ``user_model`` is activated,
         connect a function to the signal
         ``registration.signals.user_activated``; this signal will be
-        sent (with the ``User`` as the value of the keyword argument
+        sent (with the ``user_model`` as the value of the keyword argument
         ``user``) after a successful activation.
         
         """
         return False
     
     def create_inactive_user(self, username, password, email,
+                             extra_attributes=None,
                              send_email=True):
         """
-        Create a new, inactive ``User``, generate a
+        Create a new, inactive ``user_model``, generate a
         ``RegistrationProfile`` and email its activation key to the
-        ``User``, returning the new ``User``.
+        ``user_model``, returning the new ``user_model``.
         
         To disable the email, call with ``send_email=False``.
 
             ``site`` will be the currently-active
             ``django.contrib.sites.models.Site`` instance.
 
-        To execute customized logic once the new ``User`` has been
+        To execute customized logic once the new ``user_model`` has been
         created, connect a function to the signal
         ``registration.signals.user_registered``; this signal will be
-        sent (with the new ``User`` as the value of the keyword
-        argument ``user``) after the ``User`` and
+        sent (with the new ``user_model`` as the value of the keyword
+        argument ``user``) after the ``user_model`` and
         ``RegistrationProfile`` have been created, and the email (if
-        any) has been sent..
+        any) has been sent.
         
         """
         from registration.signals import user_registered
 
-        new_user = User.objects.create_user(username, email, password)
+
+        new_user = user_model.objects.create_user(username, email, password)
         new_user.is_active = False
+        if extra_attributes:
+            for attr, val in extra_attributes.items():
+                setattr(new_user, attr, val)
         new_user.save()
         
         registration_profile = self.create_profile(new_user)
     def create_profile(self, user):
         """
         Create a ``RegistrationProfile`` for a given
-        ``User``, and return the ``RegistrationProfile``.
+        ``user_model``, and return the ``RegistrationProfile``.
         
         The activation key for the ``RegistrationProfile`` will be a
-        SHA1 hash, generated from a combination of the ``User``'s
+        SHA1 hash, generated from a combination of the ``user_model``'s
         username and a random salt.
         
         """
     def delete_expired_users(self):
         """
         Remove expired instances of ``RegistrationProfile`` and their
-        associated ``User``s.
+        associated ``user_model``s.
         
         Accounts to be deleted are identified by searching for
         instances of ``RegistrationProfile`` with expired activation
-        keys, and then checking to see if their associated ``User``
+        keys, and then checking to see if their associated ``user_model``
         instances have the field ``is_active`` set to ``False``; any
-        ``User`` who is both inactive and has an expired activation
+        ``user_model`` who is both inactive and has an expired activation
         key will be deleted.
         
         It is recommended that this method be executed regularly as
            those accounts will be deleted, the usernames will become
            available for use again.
         
-        If you have a troublesome ``User`` and wish to disable their
+        If you have a troublesome ``user_model`` and wish to disable their
         account while keeping it in the database, simply delete the
-        associated ``RegistrationProfile``; an inactive ``User`` which
+        associated ``RegistrationProfile``; an inactive ``user_model`` which
         does not have an associated ``RegistrationProfile`` will not
         be deleted.
         
     """
     ACTIVATED = u"ALREADY_ACTIVATED"
     
-    user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
+    user = models.ForeignKey(user_model, unique=True, verbose_name=_('user'))
     activation_key = models.CharField(_('activation key'), max_length=40)
     
     objects = RegistrationManager()

registration/tests.py

 import sha
 
 from django.conf import settings
-from django.contrib.auth.models import User
+
+try:
+    user_model = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
+except AttributeError:
+    from django.contrib.auth.models import User as user_model
+
 from django.core import mail
 from django.core import management
 from django.core.urlresolvers import reverse
 from django.test import TestCase
+from django.db.models import get_model
 
 from registration import forms
 from registration.models import RegistrationProfile
                              self.sample_user.pk)
         
         # The activated user must now be active.
-        self.failUnless(User.objects.get(pk=self.sample_user.pk).is_active)
+        self.failUnless(user_model.objects.get(pk=self.sample_user.pk).is_active)
         
         # The activation key must now be reset to the "already activated" constant.
         self.failUnlessEqual(RegistrationProfile.objects.get(user=self.sample_user).activation_key,
     def test_signals(self):
         """
         Test that the ``user_registered`` and ``user_activated``
-        signals are sent, and that they send the ``User`` as an
+        signals are sent, and that they send the ``user_model`` as an
         argument.
         
         """

registration/views.py

 from django.http import HttpResponseRedirect
 from django.shortcuts import render_to_response
 from django.template import RequestContext
+from django.db.models import get_model
 
 from registration.forms import RegistrationForm
 from registration.models import RegistrationProfile
 
+try:
+    RFC = settings.REGISTRATION_FORM_CLASS.split('.')
+    _temp = __import__(".".join(RFC[:-1]), globals(), locals(), [RFC[-1]], -1)
+    registration_form_class = getattr(_temp, RFC[-1])
+    del RFC, _temp
+except AttributeError:
+    from registration.forms import RegistrationForm as registration_form_class
+
 
 def activate(request, activation_key,
              template_name='registration/activate.html',
              extra_context=None):
     """
-    Activate a ``User``'s account from an activation key, if their key
+    Activate a ``user_model``'s account from an activation key, if their key
     is valid and hasn't expired.
     
     By default, use the template ``registration/activate.html``; to
     
     ``activation_key``
        The activation key to validate and use for activating the
-       ``User``.
+       ``user_model``.
     
     **Optional arguments**
        
 
 
 def register(request, success_url=None,
-             form_class=RegistrationForm,
+             form_class=registration_form_class,
              template_name='registration/registration_form.html',
              extra_context=None):
     """
     change this, point that named pattern at another URL, or pass your
     preferred URL as the keyword argument ``success_url``.
     
-    By default, ``registration.forms.RegistrationForm`` will be used
+    By default, the form given by the ``REGISTRATION_FORM_CLASS``
+    setting will be used as the registration form, with
+    ``registration.forms.RegistrationForm` used if this is not defined.
     as the registration form; to change this, pass a different form
     class as the ``form_class`` keyword argument. The form class you
     specify must have a method ``save`` which will create and return
-    the new ``User``.
+    the new ``user_model``.
     
     By default, use the template
     ``registration/registration_form.html``; to change this, pass the