I am follwing the exact steps in this blog.
also made the changes:
1) the url template tag syntax as noted above by "F L"
2) uidb36 in the urls.py and email template both should be uidb64 per https://docs.djangoproject.com/en/1.6/releases/1.6/#django-contrib-auth-password-reset-uses-base-64-encoding-of-user-pk
When I enter the email address, I get the mail and after entering the url: http://localhost:8000/user/password/reset/NDI-47h-e1fbd1df48ce2aa05de4/, I always get the message:
Password reset unsuccessful
The password reset link was invalid,
possibly because it has already been used.
Please request a new password reset.
i.e the validlink always fails. Why?
Sharing relevant Code blocks: urls.py:
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^user/password/reset/$',
'django.contrib.auth.views.password_reset',
{'post_reset_redirect' : '/user/password/reset/done/'}, name="password_reset"),
(r'^user/password/reset/done/$',
'django.contrib.auth.views.password_reset_done'),
(r'^user/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)-(?P<token>.+)/$',
'django.contrib.auth.views.password_reset_confirm',
{'post_reset_redirect' : '/user/password/done/'}),
(r'^user/password/done/$',
'django.contrib.auth.views.password_reset_complete'),
In my template folder, created a folder called registration: The structure of my template folder:
/templates$ find
.
./registration
./registration/password_reset_form.html
./registration/password_reset_confirm.html
./registration/password_reset_email.html
./registration/password_reset_done.html
./registration/password_reset_complete.html
./admin
password_reset_email.html:
{% load i18n %}
{% comment %}
{% load url from future %}
{% endcomment %}
{% 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 %}
{{ 'http' }}://{{ 'localhost:8000' }}{% url 'django.contrib.auth.views.password_reset_confirm' uidb64=uid token=token %}
{% endblock %}
Your username, in case you've forgotten: {{ user.username }}
Thanks for using our site!
The {{ site_name }} team.
All other templates as in the blog
I'm guessing the - in your URL is a problem because your first regular expression group matches -'s greedily.
Notice that - is matched by that first regular expression but you're also using it as a delimiter.
Instead of this URL pattern:
r'^user/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)-(?P<token>.+)/$'
Try this one:
r'^user/password/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$'
The difference is that we changed the - in between the matching groups to a /, which is a character not matched within the first group.
Related
I am creating a feature to let the banned user (user without any group) go to a specific page banned_alert when they click the "post", because they are not allowed to do so. But then when I test this feature, the Chrome shows This page isn’t working | the IP redirected you too many times. Can somebody tell me how to do it correctly? Did I miss any configuration? Below is my code snippets. Thank you for your time!
base.html: (has_group function already works correctly somewhere else)
{% load get_group %}
{% if request.user|has_group:"mod" or request.user|has_group:"default" or user.is_staff %}
<a class="nav-link" href="/create-post">Post</a>
{% else %}
<a class="nav-link" href="/banned_alert">Post</a>
{% endif %}
banned_alert.html:
{% extends 'main/base.html' %}
{% block title %}Your account has been banned by Admin{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<h2>Please contact the Admin!</h2>
{% endblock %}
view.py
def banned_alert(request):
return redirect('/banned_alert')
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('home', views.home, name='home'),
path('sign-up', views.sign_up, name='sign_up'),
path('create-post', views.create_post, name='create_post'),
path('banned_alert', views.banned_alert, name='banned_alert'),
]
You have a recursion:
this is your path
path('banned_alert', views.banned_alert, name='banned_alert'),
User visit this banned_alert path,
it redirects user to view banned_alert
Which redirects user back to url banned_alert
and it redirects back to view banned_alert
reapeat N times (it has no ending)
best way to ban user is to create a flag in his model:
models.py
class User(AbstractUser):
is_banned = models.BooleanField(default=False)
if you want to ban user, change user's field is_banned to true, and then in your template or view, check if user is banned or not, and do your logic according to it
By the way, in your ulrs.py you need to close paths with backslash like this path('home/', views.home, name='home'),
I'm having trouble passing a value from my Template index.html to
my View (duplicates(request, title).
Restricted to version 1.4.3.
I believe it to be a regex problem on my part in the urls.py file.
Current Error is Page not found (404).
urls.py
from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r'^missions/$', 'app.views.index'),
url(r'^missions/(?P<mission_id>\d+)/$', 'app.views.mission_overview'),
url(r'^missions/duplicates/(?P<title>[A-Za-z0-9-\s\>]+)/$',
'app.views.duplicates'),
)
I've tried using the title as a query string such as
url(r'^missions/duplicates/title(?P<title>[\s.\>])/$', ...)
index.html
{% if mt %}
<!-- Title (string), Num (int), mission_id (list) -->
{% for title, num, mission_id in mt%}
{% if num > 1 %}
<li><a href="missions/duplicates/{{ title|urlencode }}/">
{{ title }}
</a></li>
{% else %}
{% for mid in mission_id %}
<li>{{title}}</li>
{% endfor %}
{% endif %}
{% endfor %}
{% else %}
<p>No Titles</p>
{% endif%}
I have also tried
{{ request.GET.urlencode }}
and
{{% url app.views.duplicates title %}}
views.py Only showing the required inputs
def duplicates(request, title):
I either gotten Page not found errors or duplicates() takes exactly 2 arguments (1 given).
Main goal is getting title from the template to the view duplicates.
I have some funky titles like...
01 Wall_01-_Store>
AB.Chicken.1 StoreY
TO.Test.0 StoreZ'
Thanks ahead of time!
EDIT
The trailing slash was the problem here - the Page not found error shows url pattern 3 ending with a slash, but the current URL, does NOT end with a slash. I suspect some code changes between various bits copied and pasted here since the a href= line in the template DOES have a trailing slash.
The TypeError is caused by the fact that the named group is not matching anything - it requires AT LEAST ONE character, as the regex ends in + and not *. Why two trailing slashes are not needed here may also come down to code changes between bits that you've pasted up...
I have set the following entry in the urls.py
(r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
but once I go to http://127.0.0.1:8000/password_reset/ I get the error message:
NoReverseMatch at /password_reset/
Reverse for 'django.contrib.auth.views.password_reset_done' with arguments '()' and keyword arguments '{}' not found.
I was expecting password_reset_done view also to be coming out of the box. So what am I supposed to do at this stage?
UPDATE
After trying Blair's solution, I got a step closer.
(r'^password_reset_done/$', 'django.contrib.auth.views.password_reset_done'),
According to the book 'Django 1.0 Website Development', these built-in views should be used out of the box without further hassle. But maybe it has changed since Django 1.0...
Would be great if someone could shed light on this. Thanks
I have finally found the solution. I think there is always the slight misunderstanding between MVC and MTV pattern. In MTV (Django) the View stands for the controller and the Template stands for the View.
Hence while its true that the change password "Views" are coming built-in out-of-the-box, the actual templates (look & feel) still needs to be generated by the user while the underlying form (widget) is generated by Django automatically. It gets more clear when looking at the code.
Therefore add these two lines to url.py
(r'^change-password/$', 'django.contrib.auth.views.password_change'),
(r'^password-changed/$', 'django.contrib.auth.views.password_change_done'),
Then Under myproject/templates/registration add these two files
password_change_done.html
{% extends "base.html" %}
{% block title %}Password Change Successful{% endblock %}
{% block head %}Password Change Completed Successfully{% endblock %}
{% block content %}
Your password has been changed successfully. Please re-login with your new credentials
login or go back to the
main page.
{% endblock %}
password_change_form.html
{% extends "base.html" %}
{% block title %}Change Registration{% endblock %}
{% block head %}Change Registration{% endblock %}
{% block content %}
<form method="post" action=".">
{{form.as_p}}
<input type="submit" value="Change" />
{% csrf_token %}
</form>
{% endblock %}
Django needs to know which URL to redirect the user to once they have completed the form on the password_reset page. So add another line to your URL configuration:
(r'^password_reset_done/$', 'django.contrib.auth.views.password_reset_done'),
As of django 1.11 password_change view is deprecated.
Deprecated since version 1.11: The password_change function-based view should be replaced by the class-based PasswordChangeView.
What worked for me was:
In urls.py
from django.contrib.auth import views as auth_views
...
url('^account/change-password/$',
auth_views.PasswordChangeView.as_view(
template_name='registration/passwd_change_form.html'),
name='password_change'),
url(r'^account/password-change-done/$',
auth_views.PasswordChangeDoneView.as_view(
template_name='registration/passwd_change_done.html'),
name='password_change_done'),
And then add the couple of templates passwd_change_form.html and passwd_change_done.html under registration.
Note that I'm not using the default name, for some reason when I did that it defaulted to the django admin views.
I want to simply render a built-in comment form in a template, using Django's builtin commenting module, but this returns a TemplateSyntaxError Exception.
I need help debugging this error, please, because after googling and using the Django API reference, I'm still not getting any farther.
Info:
This is the template '_post.html'[shortened]:
<div id="post_{{ object.id }}">
<h2>
{{ object.title }}
<small>{{ object.pub_date|timesince }} ago</small>
</h2>
{{ object.body }}
{% load comments %}
{% get_comment_count for object as comment_count %}
<p>{{ comment_count }}</p>
<!-- Returns 0, because no comments available -->
{% render_comment_form for object %}
<!-- Returns TemplateSyntaxError -->
This is the Exception output, when rendering:
Caught an exception while rendering: Reverse for 'django.contrib.comments.views.comments.post_comment'
with arguments '()' and keyword arguments '{}' not found.1
{% load comments i18n %}
<form action="{% comment_form_target %}" method="post">
{% if next %}<input type="hidden" name="next" value="{{ next }}" />{% endif %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
{% if field.errors %}{{ field.errors }}{% endif %}
<p
{% if field.errors %} class="error"{% endif %}
{% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
{{ field.label_tag }} {{ field }}
/posts/urls.py[shortened]:
queryset = {'queryset': Post.objects.all(),
'extra_context' : {"tags" : get_tags}
}
urlpatterns = patterns('django.views.generic.list_detail',
url('^$', 'object_list', queryset,
name='posts'),
url('^blog/(?P<object_id>\d+)/$', 'object_detail', queryset,
name='post'),
)
/urls.py[shortened]:
urlpatterns = patterns('',
(r'', include('posts.urls')),
(r'^comments/$', include('django.contrib.comments.urls')),
)
I had the same exact problem, render_comment_form template tag was triggering it.
The issue is certainly with your URL config, you had it set the same way i did:
(r'^comments/$', include('django.contrib.comments.urls'))
The correct way is to remove the '$' after 'comments/':
(r'^comments/', include('django.contrib.comments.urls'))
Otherwise django can't properly include all necessary urls under the path comments/...
Hope this helps.
The error message is indicated that it can't find a reverse url for:
django.contrib.comments.views.comments.post_comment
So basically something isn't configured right in your urls. Without being able to see more of how things are setup it's difficult to know exactly what.
Maybe try re-ordering the urls pattern includes in your urls.py, to force the django comments urls to the top?
I had this same problem today. I was referencing a view in urls.py that I hadn't created yet.
From http://docs.djangoproject.com/en/dev/topics/http/urls/#reverse
As part of working out which URL names
map to which patterns, the reverse()
function has to import all of your
URLconf files and examine the name of
each view. This involves importing
each view function. If there are any
errors whilst importing any of your
view functions, it will cause
reverse() to raise an error, even if
that view function is not the one you
are trying to reverse.
Make sure that any views you reference
in your URLconf files exist and can be
imported correctly. Do not include
lines that reference views you haven't
written yet, because those views will
not be importable.
This error is saying that it found the view django.contrib.comments.views.comments.post_comment
but no args () or kwargs{} were passed.
Its not passing a value for object.id into the url.
Take out the url tag and see if the id of the <div id="post_{{object.id}}"> reflects a proper object.id
I'm trying to use the password reset setup that comes with Django, but the documentation is not very good for it. I'm using Django 1.0 and I keep getting this error:
Caught an exception while rendering: Reverse for 'mysite.django.contrib.auth.views.password_reset_confirm' with arguments '()' and keyword arguments ...
in my urlconf I have something like this:
#django.contrib.auth.views
urlpatterns = patterns('django.contrib.auth.views',
(r'^password_reset/$', 'password_reset', {'template_name': 'accounts/registration/password_reset_form.html', 'email_template_name':'accounts/registration/password_reset_email.html', 'post_reset_redirect':'accounts/login/'}),
(r'^password_reset/done/$', 'password_reset_done', {'template_name': 'accounts/registration/password_reset_done.html'}),
(r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'password_reset_confirm', {'template_name': 'accounts/registration/password_reset_confirm.html', 'post_reset_redirect':'accounts/login/', 'post_reset_redirect':'accounts/reset/done/'}),
(r'^reset/done/$', 'password_reset_complete', {'template_name': 'accounts/registration/password_reset_complete.html'}),
)
The problem seems to be in this file:
password_reset_email.html
on line 7
{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
I'm at loss as to what's going on, so any help would be appreciated.
Thanks
Edit: I used your example, and had to change to not use keyword parameters.
{% url django.contrib.auth.views.password_reset_confirm uid, token %}
Named parameters do work, as long as both uid and token are defined. If either are not defined or blank I get the same error you do:
{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
Just wanted to post the solution I came up with. The problem was in this line:
{% url django.contrib.auth.views.password_reset_confirm uidb36=uid, token=token %}
I'm not really a 100% why either, so I just hard coded the url like this:
http://mysite.com/accounts/reset/{{uid}}-{{token}}/
I've struggled with this for over an hour trying everything on this page and every other page on the internet. Finally to solve the problem in my case i had to delete
{% load url from future %}
from the top of my password_reset_email.html template.
Also note, "uidb36=uid" in the url script. Here's my full password_reset_email.html template, I hope it saves someone some time:
{% 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 %}
This is a problem I figured out myself not 10 minutes ago. The solution is to add the post_change_redirect value to the dictionary of arguments you are passing to the password_reset view.
So this is what mine now look like:
(r'^/password/$', password_change, {'template_name': 'testing/password.html', 'post_change_redirect': '/account/'})
I hope that does it for you! I agree that the documentation for this particular feature is lacking somewhat, but this solved the exact same issue for my project.
Edit: I really should have scrolled across - you've included that already. Apologies for that, but I hope you get it sorted :)