5

How can I force resending activation e-mail to user? E.g. when he accidentaly deletes the mail, he clicks in link in my website, and django will send him new activation e-mail.

DJpython
  • 71
  • 1
  • 3
  • Can you give some more details? What link? – kzh Dec 28 '09 at 16:13
  • User accidentaly deleted the e-mail. Then, he log in into website and clicks link, wich resends him activation link. My question is: how can I make that link? Wtah should be in view file. – DJpython Dec 28 '09 at 17:15
  • Unfortunately, django-registration sets is_active to False until the user clicks the link. The default django login function checks to ensure is_active is True. I too am looking for a way to allow users to login and choose resend email. I think it will require big changes to django-registration and adding a user profile with another boolean field indicating whether they confirmed their email or not. Your site has to then check this flag when authorizing users to view restricted portions of your site. – mhost May 18 '10 at 22:02

4 Answers4

8

There's an admin action for doing that. From the django-registration docs:

How do I re-send an activation email?

Assuming you’re using the default backend, a custom admin action is provided for this; in the admin for the RegistrationProfile model, simply click the checkbox for the user(s) you’d like to re-send the email for, then select the “Re-send activation emails” action.

There's no built-in automatic way of doing this (how should django-registration figure out that a random visitor is that guy who filled out the registration form 3 days ago and deleted his activation mail?).

Community
  • 1
  • 1
Benjamin Wohlwend
  • 30,958
  • 11
  • 90
  • 100
  • 8
    He can log in, and click "resend activation e-mail" in his profile... it's frequently used on many websites. – DJpython Dec 28 '09 at 16:33
5

The following view function will render a form with single email field, then check if there are any users with this email not activated yet, recreate activation code if expired (hashing stuff was copypasted from RegistrationProfile) and finally send activation email.

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

def resend_activation_email(request):
    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."),)

            for user in users:
                for profile in RegistrationProfile.objects.filter(user=user):
                    if profile.activation_key_expired():
                        salt = sha_constructor(str(random())).hexdigest()[:5]
                        profile.activation_key = sha_constructor(salt+user.username).hexdigest()
                        user.date_joined = datetime.now()
                        user.save()
                        profile.save()

                    if Site._meta.installed:
                        site = Site.objects.get_current()
                    else:
                        site = RequestSite(request)

                    profile.send_activation_email(site)

                    context.update({"form" : form})
                    return render_to_response("registration/resend_activation_email_done.html", context)

    if not form:
        form = ResendActivationEmailForm()

    context.update({"form" : form})
    return render_to_response("registration/resend_activation_email_form.html", context)
ilya b.
  • 443
  • 5
  • 9
  • Where do I put this function? I don't want to change my downloaded version of django-registration so I've put in views.py of my app (having put the form in forms.py) and I'm getting this error: global name 'RegistrationProfile' is not defined – HenryM May 18 '16 at 12:20
0

I updated the ilya b. method resend_activation_email. The old method show error of sha deprecation in python >= 2.5

def resend_activation_email(request):

    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.")

            for user in users:
                for profile in RegistrationProfile.objects.filter(user=user):
                    if profile.activation_key_expired():
                        salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
                        profile.activation_key = hashlib.sha1(salt+user.email).hexdigest()
                        user.date_joined = datetime.datetime.now()
                        user.save()
                        profile.save()

                    if Site._meta.installed:
                        site = Site.objects.get_current()
                    else:
                        site = RequestSite(request)

                    profile.send_activation_email(site)

                    context.update({"form" : form})
                    return render(request, 'registration/resend_activation_email_done.html', context)

    if not form:
        form = ResendActivationEmailForm()

    context.update({"form" : form})
    return render(request, 'registration/resend_activation_email_form.html', context)
  • Where do I put this function? I don't want to change my downloaded version of django-registration so I've put in views.py of my app (having put the form in forms.py) and I'm getting this error: global name 'RegistrationProfile' is not defined – HenryM May 18 '16 at 12:23
0

My (ugly) solution was to create my own login view:

from django.contrib.auth.views import login as django_login

def login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          redirect_authenticated=None,
          authentication_form=AuthenticationForm):
    """
        Redirect to redirect_authenticated if user is authenticated or
        delegate to contrib login otherwise.
    """

    form = authentication_form(data=request.POST)

    if request.method == "POST":
        if not form.is_valid():

            non_field_errors = form.non_field_errors()

            if non_field_errors:
                # test if the account is not active
                user_inactive = non_field_errors[0].find(_("This account is inactive.")) != -1

                if user_inactive:
                    return render_to_response(template_name, {
                        'form': form,
                        'user_inactive' : user_inactive,
                    }, context_instance=RequestContext(request))

    return django_login(request, template_name=template_name,
              redirect_field_name=redirect_field_name,
              authentication_form=authentication_form)

And then use the context variable in template:

{% if user_inactive %}  
  <a href="/activation/resend/">Resend activation link</a>
{% else %}   
  <a href="{% url django.contrib.auth.views.password_reset %}">Forgot your password?</a> 
{% endif %}

When the user clicks on the resend activation link, a form asking for the registered email appears. Submiting the form triggers a new account activation email.

Hope this helps.

Marcio Fonseca
  • 489
  • 4
  • 5