Question

I am using Django in-build password to allow users to reset the password. My password_reset_form.html looks like this:

{% block title %}Reset Password{% endblock %}

{% block content %}
<p>Please specify your email address to receive instructions for resetting it.</p>

<form action="" method="post">
    <div style="display:none">
        <input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
    </div>
     {{ form.email.errors }}
    <p><label for="id_email">E-mail address:</label> {{ form.email }} <input type="submit" value="Reset password" /></p>
</form>
{% endblock %}

For now, user can enter their e-mail address and password reset instruction is send to the user. I want to modify this so that user can enter either their username or e-mail address and receive the password reset instruction in email. Should I directly go to dist-packages and start editing the password reset file or should I do something else? I can find the e-mail address of user using their username if they enters their username:

if not '@' in new_mail:
      email = User.objects.filter(username=new_mail).values_list('email')
      new_mail1 = email[0]

How can I do this? Thank you

Was it helpful?

Solution 2

I'd do something like this

{% block title %}Reset Password{% endblock %}

{% block content %}
<p>Please specify your username or email address to receive instructions for resetting it.</p>

<form action="" method="POST">
  {% csrf_token %}
  {{ form.email.errors }}
  <p>{{ form.email.label }}{{ form.email }} <button type="submit">Reset Password</button></p>
</form>
{% endblock %}

In your POST variable you now have an email or a password. You'd have to make a guess if people would use the email or username more. Based on that the following should work

from django.db.models import Q
email = request.POST.get('email, "")
u = User.objects.filter(Q(username=email)|Q(email=email))
if u.count() == 1:
  email_address = u[0].email
  # now you can send the user an email with instructions
if u.count() < 1:
  # invalid username or email
  return
if u.count() > 1:
  # unlikely but lets account for this anyway. I'll leave this up to you
  return

There might be a more elegant way to check for the user, but this way there's essentially only one query and might be quicker than matching email and username individually in try/except blocks. Personally I prefer a filter/count way of checking rather than try/except, but thats besides the point.

OTHER TIPS

You definitely should not edit dist-packages files. Built-in views and forms don't support the behaviour you want. I think it's ok to copy implementation of the involved views and forms and modify them. Copy django.contrib.auth.views.password_reset view to your views file. Copy django.contrib.auth.forms.PasswordResetForm to your forms file and add username field to it and modify user search code to search on email or username depending on what has been specified. Change used form class in password_reset view to your new PasswordResetForm. This should be enough.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top