Django reverse for 'password_change_done' not found - html

I have a small application that I'm writing, but I have came into some trouble with the password changing elements used with the Django authentication framework. But I always get the error after changing a password that: Reverse for 'password_change_done' not found. 'password_change_done' is not a valid view function or pattern name. Here is my code below:
#account urls.py
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
app_name = 'account'
urlpatterns = [
#Password Changes URLs
path('password_change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]
This is my directory structure for the login system:
Directory Structure
Here's the password_change.html file:
<h3 style="text-align: center;">Change your password</h3>
<div class="login-form" style="text-align: center; ">
<form method="post">
{{ form.as_p }}
<p><input type="submit" value="Change"></p>
{% csrf_token %}
</form>
</div>
Any help would be greatly appreciated!

Since you use an app_name, you will need to include the namespace in the success_url of the PasswordChangeView:
# account urls.py
from django.urls import path, include
from django.contrib.auth import views as auth_views
from . import views
from django.urls import reverse_lazy
app_name = 'account'
urlpatterns = [
#Password Changes URLs
path('password_change/', auth_views.PasswordChangeView.as_view(
success_url=reverse_lazy('account:password_change_done')
), name='password_change'),
path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]
some other class-based views of the auth package have success_urls, these thus should be updated as well.

Related

NoReverseMatch at 'url' in Django, Reverse for 'my_app' not found. 'my_app' is not a valid view function or pattern name

I'm new to Django, and today when I tried to run a website with a database, I have encountered this error.
I have searched for all solutions on StackOverflow and Django documents, but I can not fix it.
This is the problem that similar to me, but it doesn't work.
I want to create a link that moves user from user.html in user to index.html in citizens
Here is my project structure. I'm sorry because I can't attach an image, so I will try to explain it in easiest way.
[MYPROJECT]
->manage.py
->citizens (folder)
-->templates (inside this folder I have citizen.html, index.html, layout.html)
-->admin.py
-->models.py
-->tests.py
-->urls.py
-->views.py
->myproject (folder)
-->setting.py
-->urls.py
-->etc that I think not important
->user (folder)
-->templates (inside this folder I have login.html, user.html, layout.html)
-->urls.py
-->views.py
-->etc that I think not important
As you can see, I have user.html inside templates folder of user, and index.html inside templates folder of citizens.
Here is my code:
index.html inside citizens
{% extends "citizens/layout.html" %}
{% block body %}
<h1>Hệ thống quản lý XNC</h1>
<table class="table">
<thead>
<tr>
<th scope="col">Số TT</th>
<th scope="col">Họ và tên công dân</th>
<th scope="col">Giới tính</th>
<th scope="col">Số Hộ chiếu</th>
<th scope="col">Chi tiết</th>
</tr>
</thead>
<tbody>
{% for citizen in citizens %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<td>{{ citizen.name }}</td>
<td>{{ citizen.sex }}</td>
<td>{{ citizen.sID }}</td>
<td>Truy cập</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
user.html inside user
{% extends "users/layout.html" %}
{% block body %}
<h1>Chào mừng, {{ request.user.username }}</h1>
<ul>
<li>Username: {{request.user.username }}</li>
</ul>
Truy cập Cơ sở dữ liệu
{% endblock %}
urls.py inside citizens
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("<int:citizen_id>", views.citizen, name="citizen"),
#path("<int:citizen_id>/passports", views.passport, name="passports")
]
views.py inside citizens
from django.shortcuts import render
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.urls import reverse
from .models import Citizen
# Create your views here.
def index(request):
return render(request, "citizens/index.html", {
"citizens": Citizen.objects.all()
})
def citizen(request, citizen_id):
try:
citizen = Citizen.objects.get(sID=citizen_id)
except Citizen.DoesNotExist:
raise Http404("Citizen not found")
return render(request, "citizens/citizen.html", {
"citizen": citizen,
})
urls.py inside myproject
"""htql2 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('citizens/', include('citizens.urls')),
path('accounts/', include('django.contrib.auth.urls')),
path('users/', include('users.urls')),
]
urls.py inside users
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("login", views.login_view, name="login"),
path("logout", views.logout_view, name="logout"),
]
views.py inside users
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth import authenticate, login, logout
from django.shortcuts import render
from django.http import HttpResponseBadRequest, HttpResponseRedirect, Http404
from django.urls import reverse
#csrf_exempt
# Create your views here.
def index(request):
if not request.user.is_authenticated:
return HttpResponseRedirect(reverse("login"))
return render(request, "users/user.html")
def login_view(request):
if request.method == "POST":
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(reverse("index"))
else:
return render(request, "users/login.html", {
"message": "Invalid credentials."
})
else:
return render(request, "users/login.html")
def logout_view(request):
pass
Inside user.html, I have tried to use
Go to Database
but doesn't work.
Thank you. I'm so grateful.
You have tried to use {% url 'citizen:citizens/' %} here the part before : (citizen) is a url namespace and the part after it (citizens) is the url name. But you haven't used any namespace, and neither do you have a url name as citizens.
You can add a namespace in citizens.urls by specifying app_name:
from django.urls import path
from . import views
app_name = 'citizens' # here
urlpatterns = [
path("", views.index, name="index"),
path("<int:citizen_id>", views.citizen, name="citizen"),
#path("<int:citizen_id>/passports", views.passport, name="passports")
]
Next you need to write the url tag as {% url 'citizens:index' %}:
Go to Database

How can I create redirect button with post method in Django template

I'm trying to create a button in the Django template which will redirect to another URL. But getting error 404 since Django can't recognize URL path rescribed in the urls.py.
HTML part
<form method="post" action='sts'>
{% csrf_token %}
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" name="cts_link">cts</button>
</form>
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from rtRegRes.views import units
from rtRegRes.views import spartan
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^units/$', units),
url(r'^units/sts/?$', spartan),
]
views.py
from django.shortcuts import render, redirect, reverse, render_to_response
from .models import rt_reg_res
from django.http import HttpResponse, JsonResponse
def units(request):
"""Return main webpage"""
return render_to_response('runtime.html')
def spartan(request):
"""Link to the other unit webpages"""
table = rt_reg_res.objects.all()
if request.method == 'POST':
qatables = request.POST.get("cts_link")
if qatables:
return render(request, 'cts.html', {'table': table})
Clicking the button following error message appears:
enter image description here
Could somebody point me what is wrong in my code
Thanks
from django.conf.urls import include, url
from django.contrib import admin
from rtRegRes.views import spartan , units
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^units/$', units),
url(r'^units/sts/?$', spartan, name='sts'),
]
and
<form method="post" action='sts'>
{% csrf_token %}
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" name="cts_link">cts</button>
</form>
Swapping the order of urls should help.
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^units/sts/?$', spartan),
url(r'^units/$', units),
]
What a pity, I wasted my time for nothing (( My code was correct, I just forget to rerun server after changes, every time reloaded page instead and did not see real changes. Anyway, thanks for the responses guys!!

Getting Django CSRF error with raw html form

I'm trying to set up a raw html form where a user can make a suggestion and then save it on a database with a POST method, but I keep getting a Forbidden (403) CSRF verification failed. Request aborted. even after following the steps in the Help section.
I have found that I don't get the error if I add csrf_exempt on top of my view like this:
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def suggest_ptags(request):
context = {}
print("Form is submitted.")
return render(request, "partials/search_form.html", context)
But I was made aware that It removes completly the CSRF protection and I don't want that.
So what should I do?
Here's my search_form.html form in a partials folder in templates:
<!-- Suggestion Form in popup -->
<div class="prop-modal">
<div class="prop-content">
<a class="btn-close-prop">×</a>
<img src="{% static 'images/pyramids.svg' %}">
<form action="/suggest_ptags/" class="feedback-form" method="POST" enctype="text/plain">
{% csrf_token %}
<h5 class="title-prop">Suggestion</h5>
<input class="input-prop" name="suggest" rows="3" cols="37" placeholder="suggest something..."></input>
<input class="button-prop" type="submit" value="Envoyez"></input>
</form>
</div>
</div>
My current Views.py:
from django.views.decorators.csrf import ensure_csrf_cookie
#ensure_csrf_cookie
def suggest_ptags(request):
context = {}
print("Form is submitted.")
return render(request, "partials/search_form.html", context)
And in my Urls:
from django.conf.urls import url
from django.contrib import admin
from search.views import HomeView, ProductView, FacetedSearchView, autocomplete, suggest_ptags
from .settings import MEDIA_ROOT, MEDIA_URL
from django.conf.urls.static import static
urlpatterns = [
url(r'^$', HomeView.as_view(), name='home'),
url(r'^admin/', admin.site.urls),
url(r'^suggest_ptags/$', suggest_ptags, name='suggest_ptags'), #Suggestions
url(r'^product/(?P<slug>[\w-]+)/$', ProductView.as_view(), name='product'),
url(r'^search/autocomplete/$', autocomplete),
url(r'^search/', FacetedSearchView.as_view(), name='haystack_search'),
] + static(MEDIA_URL, document_root=MEDIA_ROOT)
Any solutions?
You shouldn't use enctype="text/plain". You can remove it (which is the same as enctype="multipart/form-data"), or use enctype="multipart/form-data" if you are uploading files.

Unable to call Django function for inserting data in postgres db

I am running the below code however when i submit create.html template it goes directly to home.html without inserting any record in postgres db. I believe, the function "create" is not called at all. Kindly assist
I tried directing the function
* views.py *
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .models import Product
def home(request):
return render(request, 'products/home.html')
#login_required
def create(request):
if request.method =='POST':
product = Product()
product.title = request.POST['title']
product.save()
return redirect('home')
else:
return render(request, 'products/create.html')
* urls.py *
from django.urls import path,include
from . import views
urlpatterns = [
path('create',views.create,name='create'),]
* models.py *
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
* apps.py *
from django.apps import AppConfig
class ProductsConfig(AppConfig):
name = 'products'
* Main url.py *
from django.contrib import admin
from django.urls import path,include
from products import views
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('products/', include('products.urls')),]
* urls.py *
from django.urls import path,include
from . import views
urlpatterns = [
path('create',views.create,name='create'),]
* create.html *
{%extends 'base.html'%}
{%block content%}
<form method="POST" action="{% url 'create' %}" enctype = "multipart/form-data">
{% csrf_token %}
Title:
<br/>
<input type="text" name = "title"/>
<br/><br/>
<input type="submit" class = "btn btn-primary" value = "Add Product"/>
</form>
{%endblock%}
I was expecting the record to be inserted in database (postgres) and I should be able to validate it using "django administration" page.
I am able to add the record manually via "django administration" page but not via above html form

Django 1.10 - Issue passing value from Template to View

I am having an issue when it cmoes to passing variables from templates to views. Even though I am able to pass variables from view to template, I canot seem to get it right. I have looked at similar questions here.
Following the Django docs I created a forms.py script as follows:
forms.py
GNU nano 2.7.4 File: forms.py
from django import forms
class TactForm(forms.Form):
tacttime = forms.CharField(label='Tact Time', max_length=100)
Updated View
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from lineoee.models import Lineoee31
from .forms import TactForm
def details(request):
if request.method == 'POST':
form = TactForm(request.POST)
print(form)
else:
form = TactForm()
context = {'form' : form}
return render(request, 'linedetails/index.html',context)
Updated Template
<form method="POST" action="{% url 'details' %}">
{% csrf_token %}
{{ form.as_p }}
<label for="tacttime">Tact Time: </label>
<input id="tacttime" type="text" name="tacttime" value ="60">
<input type="submit" value="OK">
<form>
Updated URLS
from django.conf.urls import url
from django.contrib import admin
from lineoee.views import index
from lineoee.views import details
urlpatterns = [
url(r'lineoee/$', index, name='index'),
url(r'linedetails/', details, name='details'),
]
Still, no errors and no values passed to the view.
EDIT
I am now getting some data on pressing the OK button, however it is not what I was expecting. I want to be able to retrieve the text entered into the input field. How can I do this?
"POST /linedetails/ HTTP/1.1" 200 24580
<tr><th><label for="id_tacttime">Tact Time:</label></th><td><input
type="text" name="tacttime" value="60" required id="id_tacttime"
maxlength="100" /></td></tr>
Template
<div style="text-align:center;">
<form method="POST" action="{% url 'details' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="adsfadsfas">
</form>
</div>
Views (EDITED)
Whatever the name you use in your input on your HTML template, that's the key you're gonna use to get what comes in the request.POST. That's why you'd like to use {{ form.field }} in the template so you know beforehand the name of the fields you're expecting to come in the request.POST
def details(request):
if request.method == 'POST':
print(request.POST)
print(request.POST.get('tacttime')
form = TactForm(request.POST)
print(form)
else:
form = TactForm()
return render(request, 'linedetails/index.html', context)
URLS
from django.conf.urls import url
from django.contrib import admin
from lineoee.views import index
from lineoee.views import details
urlpatterns = [
url(r'lineoee/$', index, name='index'),
url(r'linedetails/', details, name='details'),
]
def details(request):
if request.method == 'POST':
var = request.POST['textfield']
print(var)