def get_supplement_class(self): """Return the current registration supplement class""" # cache mechanisms will break the test thus disable it in test if not hasattr(self, '_supplement_class_cache') or 'test' in sys.argv: cls = get_supplement_class() setattr(self, '_supplement_class_cache', cls) return getattr(self, '_supplement_class_cache')
def test_get_supplement_class(self): from registration.supplements.default.models import DefaultRegistrationSupplement supplement_class = get_supplement_class( 'registration.supplements.default.models.DefaultRegistrationSupplement') self.failUnless(supplement_class is DefaultRegistrationSupplement)
class RegistrationProfile(models.Model): """Registration profile model class A simple profile which stores an activation key and inspection status for use during user account registration/inspection. Generally, you will not want to interact directly with instances of this model; the provided manager includes method for creating, accepting, rejecting and activating, as well as for cleaning out accounts which have never been activated or its registration has been rejected. While it is possible to use this model as the value of the ``AUTH_PROFILE_MODEL`` setting, it's not recommended that you do so. This model's sole purpose is to store data temporarily during account registration, inspection and activation. """ STATUS_LIST = ( ('untreated', _('Untreated yet')), ('accepted', _('Registration has accepted')), ('rejected', _('Registration has rejected')), ) user = models.OneToOneField(User, verbose_name=_('user'), related_name='registration_profile', editable=False) _status = models.CharField(_('status'), max_length=10, db_column='status', choices=STATUS_LIST, default='untreated', editable=False) activation_key = models.CharField(_('activation key'), max_length=40, null=True, default=None, editable=False) objects = RegistrationManager() supplement_class = get_supplement_class() class Meta: verbose_name = _('registration profile') verbose_name_plural = _('registration profiles') permissions = ( ('accept_registration', 'Can accept registration'), ('reject_registration', 'Can reject registration'), ('activate_user', 'Can activate user in admin site'), ) def _get_supplement(self): """get supplement information of this registration""" return getattr(self, '_supplement', None) supplement = property(_get_supplement) def _get_status(self): """get inspection status of this profile this will return 'expired' for profile which is accepted but activation key has expired """ if self.activation_key_expired(): return 'expired' return self._status def _set_status(self, value): """set inspection status of this profile Setting status to ``'accepted'`` will generate activation key and update ``date_joined`` attribute to now of associated ``User`` Setting status not to ``'accepted'`` will remove activation key of this profile. """ self._status = value # Automatically generate activation key for accepted profile if value == 'accepted' and not self.activation_key: username = self.user.username self.activation_key = generate_activation_key(username) # update user's date_joined self.user.date_joined = datetime_now() self.user.save() elif value != 'accepted' and self.activation_key: self.activation_key = None status = property(_get_status, _set_status) def get_status_display(self): """get human readable status""" sl = list(self.STATUS_LIST) sl.append(('expired', _('Activation key has expired'))) sl = dict(sl) return sl.get(self.status) get_status_display.short_description = _("status") def __unicode__(self): return u"Registration information for %s" % self.user def __str__(self): return "Registration information for %s" % self.user def activation_key_expired(self): """get whether the activation key of this profile has expired Determine whether this ``RegistrationProfiel``'s activation key has expired, returning a boolean -- ``True`` if the key has expired. Key expiration is determined by a two-step process: 1. If the inspection status is not ``'accepted'``, the key is set to ``None``. In this case, this method returns ``False`` because these profiles are not treated yet or rejected by inspector. 2. Otherwise, the date the user signed up (which automatically updated in registration acceptance) is incremented by the number of days specified in the setting ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of days after acceptance during which a user is allowed to activate their account); if the result is less than or equal to the current date, the key has expired and this method return ``True``. """ if self._status != 'accepted': return False expiration_date = datetime.timedelta( days=settings.ACCOUNT_ACTIVATION_DAYS) expired = self.user.date_joined + expiration_date <= datetime_now() return expired activation_key_expired.boolean = True def _send_email(self, site, action, extra_context=None): context = { 'user': self.user, 'site': site, } if action != 'activation': # the profile was deleted in 'activation' action context['profile'] = self if extra_context: context.update(extra_context) subject = render_to_string( 'registration/%s_email_subject.txt' % action, context) subject = ''.join(subject.splitlines()) message = render_to_string('registration/%s_email.txt' % action, context) send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [self.user.email]) def send_registration_email(self, site): """send registration email to the user associated with this profile Send a registration email to the ``User`` associated with this ``RegistrationProfile``. The registration email will make use of two templates: ``registration/registration_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/registration_email.txt`` This template will be used for the body of the email These templates will each receive the following context variables: ``site`` An object representing the site on which the user registered;this is an instance of ``django.contrib.sites.models.Site`` or ``django.contrib.sites.models.RequestSite`` ``user`` A ``User`` instance of the registration. ``profile`` A ``RegistrationProfile`` instance of the registration """ self._send_email(site, 'registration') def send_acceptance_email(self, site, message=None): """send acceptance email to the user associated with this profile Send an acceptance email to the ``User`` associated with this ``RegistrationProfile``. The acceptance email will make use of two templates: ``registration/acceptance_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/acceptance_email.txt`` This template will be used for the body of the email These templates will each receive the following context variables: ``site`` An object representing the site on which the user registered;this is an instance of ``django.contrib.sites.models.Site`` or ``django.contrib.sites.models.RequestSite`` ``user`` A ``User`` instance of the registration. ``profile`` A ``RegistrationProfile`` instance of the registration ``activation_key`` The activation key for tne new account. Use following code to get activation url in the email body:: {% load url from future %} http://{{ site.domain }} {% url 'registration_activate' activation_key=activation_key %} ``expiration_days`` The number of days remaining during which the account may be activated. ``message`` A message from inspector. In default template, it is not shown. """ extra_context = { 'activation_key': self.activation_key, 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'message': message, } self._send_email(site, 'acceptance', extra_context) def send_rejection_email(self, site, message=None): """send rejection email to the user associated with this profile Send a rejection email to the ``User`` associated with this ``RegistrationProfile``. The rejection email will make use of two templates: ``registration/rejection_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/rejection_email.txt`` This template will be used for the body of the email These templates will each receive the following context variables: ``site`` An object representing the site on which the user registered;this is an instance of ``django.contrib.sites.models.Site`` or ``django.contrib.sites.models.RequestSite`` ``user`` A ``User`` instance of the registration. ``profile`` A ``RegistrationProfile`` instance of the registration ``message`` A message from inspector. In default template, it is used for explain why the account registration has been rejected. """ extra_context = { 'message': message, } self._send_email(site, 'rejection', extra_context) def send_activation_email(self, site, password=None, is_generated=False, message=None): """send activation email to the user associated with this profile Send a activation email to the ``User`` associated with this ``RegistrationProfile``. The activation email will make use of two templates: ``registration/activation_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/activation_email.txt`` This template will be used for the body of the email These templates will each receive the following context variables: ``site`` An object representing the site on which the user registered;this is an instance of ``django.contrib.sites.models.Site`` or ``django.contrib.sites.models.RequestSite`` ``user`` A ``User`` instance of the registration. ``password`` A raw password of ``User``. Use this to tell user to them password when the password is generated ``is_generated`` A boolean -- ``True`` if the password is generated. Don't forget to tell user to them password when the password is generated ``message`` A message from inspector. In default template, it is not shown. """ extra_context = { 'password': password, 'is_generated': is_generated, 'message': message, } self._send_email(site, 'activation', extra_context)
def _get_supplement_class(self): """get supplement class of this registration""" return get_supplement_class()