NoReverseMatch at /user_details/reset-password - django

I know it's well asked, but somehow none of the other answers seemed to solve my problem.
I get an error with the ReverseMatch, here is the relevant urls.py section:
# for password reset
url(r'^reset-password$','django.contrib.auth.views.password_reset', {'post_reset_redirect' : 'user_details/reset_password.html', 'template_name': 'user_details/reset_password.html'}, name="password_reset"),
url(r'^reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', {'post_reset_redirect' : 'user_details/reset_password.html'}, name="password_reset_confirm"),
I think the name is adequately defined?
The problem is in the template /usr/lib/python2.7/dist-packages/django/contrib/admin/templates/registration/password_reset_email.html, error at line 6:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
where the {% url ...} is highlighted in red.
Why?
I assume that Django would then use the default template for that view?
Thanks!
Chris

Right, I had to resolve to overwriting the Django default email, because the reverse URL lookup doesn't want to behave properly.
So I created a copy of the original Django email file (/usr/lib/python2.7/dist-packages/django/contrib/admin/templates/registration/password_reset_email.html):
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
and replaced line 6 with the following:
{{ protocol }}://{{ domain }}/user_details/reset/{{uid}}/{{token}}
which matches my urls.py.
This does indeed work now...

You have defined a URL which accepts a "uidb36" parameter, but the reverse call is passing "uidb64".

Related

Django 3: Badly formed URL in password_reset_email.html

I have a Django 3.0.7 app using the default template for sending password reset emails.
For some of our users, the link to reset is badly formed, e.g.:
https://foo.bar/accounts/reset/McU4Mw/5no-9cd52590f0943503=
fa3a/
/>
While it should be:
https://foo.bar/accounts/reset/McU4Mw/5no-9cd52590f0943503fa3a/
This second one is whats actually being sent. But, as I said, some users are receiving the first one.
I assume some of my users' email clients are wrecking the text, but what could I do?
I've considered adding a plaintext url to the email, but it's already plaintext.
EDIT: This is a solution I came up with, and it works. Can anyone think of a reason not to do this?
urls.py
...
path('accounts/reset/<uidb64>/<token>/<str:extra_chars>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
path('accounts/reset/<uidb64>/<token>/', PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
...
EDIT:
Here's the default template:
/site-packages/django/contrib/admin/templates/registration/password_reset_email.html
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans 'Your username, in case you’ve forgotten:' %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}

using django authentication password_reset_confirm error

I have an error with password reset. If I attempt to reset using an invalid email I get the password reset sent notice. If I use a valid email I get NoReverseMatch error message
from django.conf.urls import url
from django.contrib import admin
from . import views
from django.contrib.auth import views as auth_views
from django.urls import reverse, reverse_lazy, resolve
# Password URL's ###################################################################################################
url(r'^change-password/$', views.change_password, name='change_password'),
url(
r'^password_reset/$',
auth_views.PasswordResetView.as_view(
template_name="registration/password_reset.html",
email_template_name="registration/password_reset_email.html",
success_url=reverse_lazy("partners:password_reset_done"), # might be required
),
name='password_reset'
),
url(r'^password_reset_done/',
auth_views.PasswordResetDoneView.as_view(
),
name='password_reset_done'
),
url(r'^password_reset_confirm/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$',
auth_views.PasswordResetConfirmView.as_view(
template_name="registration/password_reset_confirm.html",
success_url=reverse_lazy("partners:password_reset_complete"), # might be required
),
name='password_reset_confirm'
),
url(r'^password_reset_complete/$',auth_views.PasswordResetCompleteView.as_view(), name="password_reset_complete"),
]
Please see my screen grabs for my project structure and the error message
project structure
error message received
{% block head %}
<meta charset="UTF-8">
<title>Welcome ! You can login here !</title>
{% endblock head %}
{% block body %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-3">
<h3>Password Reset Email</h3>
<p>Provide your registered email address </p>
{% autoescape off %}
To initiate the password reset process for your {{ user.get_username }} TestSite Account,
click the link below:
{{ protocol }}://{{ domain }}{% url 'partners:password_reset_confirm' uidb64=uid token=token %}
If clicking the link above doesn't work, please copy and paste the URL in a new browser
window instead.
Sincerely,
The AV's BlogTeam
{% endautoescape %}
</div>
</div>
</div>
{% endblock content %}
{% endblock body %}
I am building this in a "partners app" where I have templates/registration with the above password_reset_confirm.html
Password reset email is as below
{% load i18n %}{% autoescape off %}
{% blocktrans %}You're receiving this email because you requested a password reset for your user account at {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page and choose a new password:" %}
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url 'partners:password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
{% trans "Your username, in case you've forgotten:" %} {{ user.get_username }}
{% trans "Thanks for using our site!" %}
{% blocktrans %}The {{ site_name }} team{% endblocktrans %}
{% endautoescape %}
PLEASE HELP
If you want Django to use the template from your partners app, you need to move partners above django.contrib.admin in your INSTALLED_APPS setting.
I would suggest that you move the password reset urls into a urls.py that does not use the partners namespace. Using {% url 'partners:password_reset_confirm' ... %} will fix this specific error, but there are several other places that you will have to make changes to use the namespace, and I don't think it's worth the effort.

Why isn't the Django out-of-the-box password-reset feature working?

I am using Django 1.6.
I have the following file in myApp/templates/registration/password_reset_email.html.
However, when I enter my email address in the form to send a reset password email, I get the following error:
TemplateSyntaxError at /auth/password_reset/
Could not parse the remainder: ',' from 'uid,'
What is wrong with the template below that causes the {% url %} tag to fail?
{% autoescape off %}
You're receiving this e-mail because you requested a password reset for your user account at {{ site_name }}.
Please go to the following page and choose a new password:
{% block reset_link %}
{{ protocol }}://{{ domain }}{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
{% endblock %}
Your username, in case you've forgotten: {{ user.username }}
Thanks for using our site!
The {{ site_name }} team.
{% endautoescape %}
When you are using templatetags with several parameters, separate them by space.
Like {{ protocol }}://{{ domain }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb36=uid token=token %} (notice that there is no , after "uid".
I think that is the solution.
See https://docs.djangoproject.com/en/dev/howto/custom-template-tags/ for more info about custom templatetags and how they work.

Customize Installed Apps on Django

in my server I have a lot of apps installed like, facebook_connect, userena, guardian and so on...
For example, I realized that if I customize the:
django-userena / userena / templates / userena / emails / activation_email_message.txt
{% load i18n %}{% autoescape off %}{% load url from future %}
{% if not without_usernames %}{% blocktrans with user.username as username %}Dear {{ username }},{% endblocktrans %}
{% endif %}
{% blocktrans with site.name as site %}Thank you for signing up at {{ site }}.{% endblocktrans %}
{% trans "To activate your account you should click on the link below:" %}
{{ protocol }}://{{ site.domain }}{% url 'userena_activate' activation_key %}
{% trans "Thanks for using our site!" %}
{% trans "Sincerely" %},
{{ site.name }}
{% endautoescape %}
For specified website, and I have more than 4 in the same server, I will make a complete mess in my django_site.
My question is:
How to customize the templates or models in some installed apps without completely change the original django_site?
Thanks in advance,
You cannot change the models, but you can override templates.
In the same directory as manage.py, you would have a directory called templates, there, you can create the following folder hierarchy, and put your custom template.
templates/userena/emails/activation_email_message.txt

Django trans and url tags

I want to translate a paragraph containing a URL in a Django 1.3 application.
<p>
First edit your profile, please.
</p>
Depending on the language, the text surrounded by <a> tags will surely change. How can I allow translators to decide on the link placement? Wrapping the entire thing in a {% trans %} causes an error:
<p>{% trans "First <a href='{% url edit-profile username=user.username %}'>edit your profile</a>, please." %}</p>
The error thrown is TemplateSyntaxError: Searching for value. Unexpected end of string in column 64: trans "First <a href='{% url edit-profile username=user.username.
How should I go about doing this? Do I have to determine the URL in the view, then pass that URL as a string to the template? That seems like a really convoluted solution for what I would think is a very common problem.
Use {% blocktrans %}. The Django translation docs include this example:
{% url path.to.view arg arg2 as the_url %}
{% blocktrans %}
This is a URL: {{ the_url }}
{% endblocktrans %}
This works for me:
{% url "app-name:name-of-view" as the_url %}
{% blocktrans %}
This is a URL: {{ the_url }}
{% endblocktrans %}