DJango - NoReverseMatch Error - What is wrong? - django

I am trying to set up a user password change from built on this tutorial. Unfortunately, on success, this tutorial just returns the user to the change password form, which doesn't seem very satisfactory. So, I am attempting to redirect the user user to a success template.
My code is in an app called your_harmony
base.py
INSTALLED_APPS = [
...
'your_harmony',
...
]
urls.py
urlpatterns = [
...
url(r'^your-harmony/', include('your_harmony.urls')),
...
]
your_harmony/urls.py
urlpatterns = [
url(r'password/$', change_password, name='change_password'),
url(r'password_changed/$', password_changed, name='password_changed'),
]
views.py
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important!
messages.success(request, 'Your password was successfully updated!')
return redirect('password_changed')
else:
messages.error(request, 'Please correct the error below.')
else:
form = PasswordChangeForm(request.user)
url = 'registration/change_password.html'
return render(request, url, {'form': form})
def password_changed(request):
url = 'password_changed.html'
return render(request, url, {})
When I use the form to change the password and submit, the password is changed correctly, but I get the error
NoReverseMatch at /your-harmony/password_changed/
However, when I hover over the link to call the change password form, the url displayed in the browser is
127.0.0.1:8000/your-harmony/password
Can someone please point what I am doing wrong?

You can use this
from django.urls import reverse
return redirect(reverse('password_changed'))
after your success
and in your urls.py
from . import views
urlpatterns = [
url(r'password/$', views.change_password, name='change_password'),
url(r'password_changed/$', views.password_changed, name='password_changed'),
]

You should use namespaces
include('your_harmony.urls', namespace='whatever')
...
def f():
return redirect(reverse('whatever:password_changed'))

Related

Url not woking in django

My Question is in two fold, both revolving round NoReverseMatch error. First Question: I keep getting NoReverseMatch error each time i call my url({% url 'dashboard' client.pk %}) in other pages that uses a different view(eg DashboardPilot: kindly check the url) but when i use it in dashboard.html it works fine.
Views.py
class Dashboard(LoginRequiredMixin, UserPassesTestMixin, DetailView):
model = ClientProfile
template_name ='accounts/dashboard.html'
context_object_name= 'client'
login_url= 'login'
fields = '__all__'
def test_func(self):
return self.request.user.role == 'client'
urls.py
urlpatterns =[
path('accounts/dashboard/client/<int:pk>', Dashboard.as_view(), name='dashboard'),
path('accounts/dashboard/pilot/<int:pk>', DashboardPilot.as_view(), name='pilot_dashboard'),
path('jobs', JobPage.as_view(), name='job_page'),
path('job/<int:pk>/details', JobDetails.as_view(), name='job_details'),
path('accounts/edit/job/<int:pk>', EditJob.as_view(), name='job_edit'),
]
**models.py**
class ClientProfile(models.Model):
username = models.ForeignKey(User, on_delete= models.CASCADE)
client_firstname=models.CharField(max_length=200)
client_lastname=models.CharField(max_length =150)
role =models.CharField(max_length =150)
client_phone_no=models.CharField(max_length =150)
client_email=models.EmailField(max_length=150)
Second Questions:
I have a view which redirect to a dashboard(uses pk) after signing but i keep getting a reverse error each time it tries to redirect to dashboard.
views.py
def signin (request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request,user)
messages.success(request, 'You are now logged in')
if user.role == 'client':
return redirect ('dashboard')
else:
return redirect ('pilot_dashboard')
else:
messages.error(request, 'Invalid Credentials')
return redirect ('login')
else:
return render (request, 'accounts/signin.html')
urls.py
urlpatterns =[
path('accounts/dashboard/client/<int:pk>', Dashboard.as_view(), name='dashboard'),
path('accounts/dashboard/pilot/<int:pk>', DashboardPilot.as_view(), name='pilot_dashboard'),
path('jobs', JobPage.as_view(), name='job_page'),
path('job/<int:pk>/details', JobDetails.as_view(), name='job_details'),
path('accounts/edit/job/<int:pk>', EditJob.as_view(), name='job_edit'),
]
I i have tried using return redirect(reverse('dashboard', args=[str(self.id)])) but i keep getting self not defined. I will be immensely grateful for any help rendered.
For the first problem, please make sure that client object is present in the template. Most probably, your template context does not have the object client which is why url is not resolved. You can test this by including {{ client }} in the templates that are giving you the error.
Basically you need to pass the correct object inside the url template tag.
You can add the client object in the context if your view does not have the ClientProfile in your template's context.
For the second problem, call the reverse with the kwargs keyword. Also, you are not passing the correct value to resolve the url.
Use:
return redirect(reverse('dashboard', kwargs={"pk": user.clientprofile.id}))

Problems with Django logout on URLs

I'm beginner with Django and I've resolved my problem yet, but I want to understand...
I've a login page on my app and a logout page, here is it:
urls.py:
url('deconnexion', views.logout, name='deconnexion'),
url('connexion', views.connexion, name='connexion'),
views.py:
def connexion(request):
error = False
if request.method == "POST":
form = ConnexionForm(request.POST)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
user = authenticate(username=username, password=password)
if user:
login(request, user)
else:
error = True
else:
form = ConnexionForm()
return render(request, 'dashboard/connexion.html', locals())
#login_required(login_url='/dashboard/connexion/')
def logout(request):
django_logout(request)
return redirect(reverse(connexion))
If I change place for url: connexion in place of deconnexion, my script doesn't work... I don't logout me and I'm redirected on the connexion page which is being connected...
If somebody have an idea?
P.S.: Sorry for my poor English, I'm French... And French with English.... we all know it's complicated... sorry ;)
As described in django documentations you can do like this:
from django.contrib.auth import logout
def logout_view(request):
logout(request)
return redirect(reverse(connexion))

django redirect after form submission not working

new to django
so this one probably has a very simple answer but i cannot for the life of me find the specific solution to this. I am simply trying to redirect to a new URL after a form submission with a FileField.
I can navigate to the URL separately and it works fine.
The file uploads correctly so I know it is validated correctly.
But the redirect returns the following error:
Reverse for 'success' not found. 'success' is not a valid view function or pattern name.
I have tried a bunch of different naming conventions, but none has worked. It looks to me like I have setup the URL and passed it correctly.
Would really appreciate some help with this. The simplest problems are the most frustrating!
Here are the views.
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .forms import InvestmentReportForm
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('success')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})
def success(request):
return HttpResponse("File successfully uploaded")
And my urls.py:
app_name = 'app'
urlpatterns = [
path('', views.index, name='index'),
path('upload/', views.upload, name='upload'),
path('success/', views.success, name='success'),
path('performance/', views.performance, name='performance'),
]
The answer was simple as I suspected. For others, if you use a namespace for a set of url patterns, you have to refer to that namespace when calling those urls. For this example:
return redirect('app:success')
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('success/')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})

django - KeyError when trying to log in

when i try to login it shows :
KeyError at /admin/
'loggedin'
it shows this error only when i submit with correct username and pwd. so i think it is about my admin view..
here is my log in view :
def log_user_in(request):
if request.method=='POST':
uname = request.POST['username']
password = request.POST['password']
user = authenticate(username=uname, password=password)
form = LoginForm(request.POST)
if form.is_valid():
if user is not None:
request.session['loggedin']="djangoo"
login(request, user)
return HttpResponseRedirect('/admin/')
else:
form = LoginForm()
return render_to_response('login.html',{'form':form,},context_instance=RequestContext(request))
and log out view :
def log_user_out(request):
user = request.user
try:
del request.session['loggedin']
except KeyError:
pass
logout(request)
return HttpResponseRedirect('/blog/%s/'%(user))
and admin view :
def admin_view(request):
if request.session['loggedin'] == "djangoo":
#other codes..
here is my urls.py:
urlpatterns = patterns('blog.views',
url(r'^superadmin/', include(admin.site.urls)),
url(r'^blog/(?P<username>[-\w]+)/$',view='index', name='index'),
url(r'^blog/(?P<username>[-\w]+)/post/(?P<postslug>[-\w]+)',view='single_post', name='view_blog_post'),
url(r'^login/$', view='log_user_in'), # i log in to admin page from this url
url(r'^admin/$', view='admin_view', name='admin'),# to this url
url(r'^admin/logout/$', view='log_user_out', name='logout'),
url(r'^admin/post/add/$', view='add_post',name='addpost'),
url(r'^admin/post/edit/(?P<post_id>\d+)', view='edit_post', name='editpost'),
url(r'^admin/post/delete/(?P<post_id>\d+)', view='delete_post', name='deletePost'),
)
When you logged out, you manually delete request.session['loggedin'] key, and when you browse to admin page, request.session['loggedin'] fails because you already delete that key.
You can control if request.session has loggedin key with:
`loggedin` in request.session
So, writing your admin view like:
def admin_view(request):
if `loggedin` in request.session and request.session['loggedin'] == "djangoo":
#other codes..
Or simply use
if request.session.get('loggedin') == 'djangoo'
as #Alexander Larikov said
EDIT: I need to mention that, it is good to check if a key exists in dictionary or dictionary-like structure, especially if you also may delete that key in somewhere else.

Django retrieve data from db to complete a url pattern

I know this is an easy question, I am just not getting something...so thank you for your patience and advice.
I have a view that asks a user to register to use our app. The data he/she submits is stored in a database and he is sent off to another page to set up the application:
#views.py
def regPage(request, id=None):
form = RegForm(request.POST or None,
instance=id and UserRegistration.objects.get(id=id))
# Save new/edited pick
if request.method == 'POST' and form.is_valid():
form.save()
return HttpResponseRedirect('/dev/leaguepage/')
user_info = UserRegistration.objects.all()
context = {
'form':form,
'user_info' :user_info,
}
return render(request, 'regpage.html', context)
Rather than sending ALL users to the same page '/dev/leaguepage/', I need to send each user to his own page based on the PK in the database like: '/dev/PrimaryKey/' I am not sure how to make this happen either on the views file or in the URLs.py file:
#urls.py
from django.conf.urls.defaults import patterns, include, url
from acme.dc_django import views
urlpatterns = patterns('',
url(r'^leaguepage/$','acme.dc_django.views.leaguePage'),
url(r'^$', 'acme.dc_django.views.regPage'),
)
Thank you for your help!
dp
Updated code:
#url
url(r'^user/(?P<id>\d+)/$','acme.dc_django.views.leaguePage', name="league_page"),
#view
def regPage(request, id):
form = RegForm(request.POST)
# Save new/edited pick
if request.method == 'POST' and form.is_valid():
form.save()
return HttpResponseRedirect(reverse('league_page', kwargs={'id' :id}))
#return HttpResponseRedirect('/dev/leaguepage/')
user_info = UserRegistration.objects.all()
context = {
'form':form,
'user_info' :user_info,
}
return render(request, 'regpage.html', context)
You can do a reverse lookup on your leaguePage to do your redirect, passing in the values you need to resolve the pattern. You'll need to add a name to the URL pattern you want to reverse, but basically the syntax is:
return HttpResponseRedirect(reverse('my_detail', args=(), kwargs={'id' : id}))
Example URL pattern and view:
urlpatterns = patterns('my_app.views',
url(r'^my-pattern/(?P<id>\d+)/$', 'my_action', name='my_detail'),
)
def my_action(request, id):
#do something
Hope that helps you out.