9

I have successfully added my own custom HTML templates for the password reset pages in Django and it's all working nicely. The only bit I can't work out it how to include my own email subject.

The default is "Password reset on [my site name]" and I can obviously change the site name in admin but does anyone know how to override the whole subject line?

Thanks.

Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
GivP
  • 2,634
  • 6
  • 32
  • 34

3 Answers3

18

Development Version

Just create new file registration/password_reset_subject.txt in your templates dir. This will override default django subject

See https://github.com/django/django/blob/master/django/contrib/auth/templates/registration/password_reset_subject.txt

and https://github.com/django/django/blob/master/django/contrib/auth/forms.py line 150

In Django 1.3

if you use internalization just add in .po file

#: forms.py:143
#, python-format
msgid "Password reset on %s"
msgstr "YOUR SUBJECT HERE %s"

if not folow next steps

in root urls.py

# change to your custom view
(r'^password_reset/$', 'your_app.views.password_reset'),

in your your_app/views.py

from django.contrib.auth.views import password_reset as django_password_reset
from .forms import CustomPasswordResetForm

# reuse Django view, but change form
def password_reset(*args, **kwargs):
    kwargs['password_reset_form'] = CustomPasswordResetForm
    django_password_reset(*args, **kwargs):

rewrite save method in your your_app/forms.py (I know it not DRY but should work :)

class CustomPasswordResetForm(PasswordResetForm):
    def save(self, domain_override=None, email_template_name='registration/password_reset_email.html',
         use_https=False, token_generator=default_token_generator, request=None):
        from django.core.mail import send_mail
        for user in self.users_cache:
            if not domain_override:
                current_site = get_current_site(request)
                site_name = current_site.name
                domain = current_site.domain
            else:
                 site_name = domain = domain_override
            t = loader.get_template(email_template_name)
            c = {
            'email': user.email,
            'domain': domain,
            'site_name': site_name,
            'uid': int_to_base36(user.id),
            'user': user,
            'token': token_generator.make_token(user),
            'protocol': use_https and 'https' or 'http',
            }
            send_mail(_("YOUR SUBJECT HERE %s") % site_name,
                t.render(Context(c)), None, [user.email])
Alexey Savanovich
  • 1,893
  • 11
  • 19
  • This makes sense, is there anything I need to do to make it override the default? I've put password_reset_subject.txt in the same /registration/ dir as the rest of the password reset templates but it's still using the default subject. – GivP Dec 10 '11 at 18:44
  • Sorry for inconvenience, Giv I was a bit wrong. Path depends on TEMPLATE_DIRS setting. If template will be placed in //auth/registration/ should works – Alexey Savanovich Dec 10 '11 at 19:32
  • Thanks Alexey but I'm still not able to make this work. Does this work with Django 1.3.0? Because I just looked at forms.py in contrib directory and there's no mention of password_reset_subject.txt - the PasswordResetForm class' save() method doesn't specify password_reset_subject.txt - the subject is hard-coded. Any ideas how I can override this? – GivP Dec 10 '11 at 20:37
  • 1
    I've just updated the answer. This code is not tested, but hope you catch the idea – Alexey Savanovich Dec 10 '11 at 21:44
  • I get the following error: Exception Value: 'CustomPasswordResetForm' object has no attribute 'users_cache' – Saqib Ali Feb 15 '14 at 04:10
1

This has been fixed about 8 months ago but the change doesn't seem to have made merged into 1.3.1. See: https://github.com/django/django/commits/master/django/contrib/auth/templates

pseudosudo
  • 6,270
  • 9
  • 40
  • 53
0

The PasswordResetForm sends the email based on your contrib.sites. It gets the domain name to use and passes it to the html template at registration/password_reset_email.html

use admin or django shell to change the site

in shell you can do this by doing:

>>> from django.contrib.sites.models import Site
>>> my_site = Site(domain='your_domain.com', name='Your Domain')
>>> my_site.save()
>>> print my_site.id
2
>>>

in your settings.py:

SITE_ID = 2
Srikar Appalaraju
  • 71,928
  • 54
  • 216
  • 264
  • Thanks for this but it doesn't answer my question. I've mentioned I know how to change the contrib.sites value but the subject will still say "Password reset on..." - I would like to know how to change the entire subject to say "Change your password". – GivP Dec 10 '11 at 13:51