HenryM HenryM - 6 months ago 38
Python Question

Django-registration resend activation form

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.

Answer

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.

Comments