Saturday, March 17, 2012

Resetting password in Django

If a user forgets his password ,he may try to do a reset.To enable this ,you need 6 templates in registration folder.

1.password_reset_form.html
2.password_reset_done.html
3.password_reset_email.html
4.password_reset_subject.txt
5.password_reset_confirm.html
6.password_reset_complete.html

Among these password_reset_form.html and password_reset_confirm.html contain forms which take input from user.The former asks the user to input an email address,while the later asks him to enter a new password.

The password_reset_subject.txt contains

Password reset on {{ site_name }}

which is used to set the subject of email sent to the user.the template password_reset_email.html is used to show the user a clickable link to bring up the password_reset form.However,when you try this,the user may get an email with subject

Password reset on example.com

This is because,the default site in database(with pk=1) has the domain and name 'example.com'.You can see this by querying in your database

select * from django_site where id=1;
id | domain | name
----+-----------------------+-------------
1 | example.com | example.com
(1 row)

To remedy this ,you can create a new site as below.
python manage.py shell
In [1]: from django.contrib.sites.models import Site
In [2]: newsite=Site()
In [3]: newsite.domain='127.0.0.1:8000'
In [4]: newsite.name='localhost'
In [5]: newsite.save()
In [6]:from django.core.serializers import serialize
In [7]:newsite.pk
Out [7]: 2
In [8]: sitedata=serialize("json", Site.objects.filter(pk=2))
In [9]: sitedata
Out[9]: '[{"pk": 2, "model": "sites.site", "fields": {"domain": "127.0.0.1:8000", "name": "localhost"}}]'

This can be added to the initial_data.json in fixtures.When syncdb is run,the record will be added to database.

Now you can set the site_id in settings.py to this new site

SITE_ID=2

When the password reset is requested,the email subject will be

Password reset on localhost

and the mail content will show a link to the reset confirm page correctly.

The mail sending occurs when the save() method in django.contrib.auth.forms.PasswordResetForm class is executed. You can browse the source here.The variables are set to the following values:

current_site = get_current_site(request)
site_name = current_site.name
domain = current_site.domain

get_current_site(request) is a method in django.contrib.sites.models and returns the current site.It defaults to the previously mentioned 'example.com'. You can find these variables used for creating the link in the password_reset_email.html template.

No comments:

Post a Comment