Search code examples
pythondjangopython-2.7django-registration

Django-registration resend activation Email with new code


I'm using django-registration with unique email addresses and I want to be able to send a second activation form to an email if requested by the user and if the account is not already active. I've found this link on Stackoverflow but I'm do not understand where I should put the routine. I've put it in my app's views.py and I'm getting the error

global name 'RegistrationProfile' is not defined

which is because RegistrationProfile is a model in registration but it doesn't create a table/record in my database when an activation form is sent so I don't understand how I can access it.

Any advice would be welcome.


Solution

  • OK, so this is the solution I've come up with. It may not be the prettiest, but it's working for me.

    This is added to views.py

    from .forms import ResendActivationEmailForm
    from django.core import signing
    from django.contrib.sites.shortcuts import get_current_site
    from django.template.loader import render_to_string
    
    
    def resend_activation_email(request):
    
        email_body_template = 'registration/activation_email.txt'
        email_subject_template = 'registration/activation_email_subject.txt'
    
        if not request.user.is_anonymous():
            return HttpResponseRedirect('/')
    
        context = Context()
    
        form = None
        if request.method == 'POST':
            form = ResendActivationEmailForm(request.POST)
            if form.is_valid():
                email = form.cleaned_data["email"]
                users = User.objects.filter(email=email, is_active=0)
    
                if not users.count():
                    form._errors["email"] = ["Account for email address is not registered or already activated."]
    
                REGISTRATION_SALT = getattr(settings, 'REGISTRATION_SALT', 'registration')
                for user in users:
                    activation_key = signing.dumps(
                        obj=getattr(user, user.USERNAME_FIELD),
                        salt=REGISTRATION_SALT,
                        )
                    context = {}
                    context['activation_key'] = activation_key
                    context['expiration_days'] = settings.ACCOUNT_ACTIVATION_DAYS
                    context['site'] = get_current_site(request)
    
                    subject = render_to_string(email_subject_template,
                                       context)
                    # Force subject to a single line to avoid header-injection
                    # issues.
                    subject = ''.join(subject.splitlines())
                    message = render_to_string(email_body_template,
                                               context)
                    user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
                    return render(request, 'registration/resend_activation_email_done.html')
    
        if not form:
            form = ResendActivationEmailForm()
    
        context.update({"form" : form})
        return render(request, 'registration/resend_activation_email_form.html', context)
    

    This is added to forms.py

    class ResendActivationEmailForm(forms.Form):
        email = forms.EmailField(required=True)
    

    I've a new template in registration called resend_activation_email_form.html which is used when the email has been resent but I've used exactly the same template to send the email.

    I've based this on email because I've using unique emails, but it is possibly more sensible to base it on username since that is defined as unique by django-registration.