No Reverse Match For Some URLs in Django 1.10 - python

I am making an web app in Django 1.10 and am getting an annoying error which I cannot seem to resolve. In this project there are several Django app whose URLs function without problems and seem to have similar setup as the new Account app. However, this authentication app is giving me trouble.
What's more, the account/register URL works successfully and inserts a user into the database. I am not sure why some URLs work and other do not.
Here is the error:
NoReverseMatch at /account/login/
Reverse for 'dashboard' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Request Method: POST
Request URL: http://localhost:8000/account/login/
Django Version: 1.10.6
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'dashboard' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
I have the following directory structure:
Project's url.py:
from django.conf.urls import url, include
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^account/', include('account.urls', namespace='account')),
url(r'^orders/', include('orders.urls', namespace='orders')),
url(r'^shop/', include('shop.urls', namespace='shop')),
url(r'^cart/', include('cart.urls', namespace='cart')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Account app urls.py:
urlpatterns = [
# url(r'^login/$', views.user_login, name='login'),
url(r'^$', views.dashboard, name='dashboard'),
url(r'^register/$', views.register, name='register'),
url(r'^edit/$', views.edit, name='edit'),
# login / logout urls
url(r'^login/$', django_views.login, name='login'),
url(r'^logout/$', django_views.logout, name='logout'),
url(r'^logout-then-login/$', django_views.logout_then_login, name='logout_then_login'),
# change password urls
url(r'^password-change/$', django_views.password_change, name='password_change'),
url(r'^password-change/done/$', django_views.password_change_done, name='password_change_done'),
# restore password urls
url(r'^password-reset/$', django_views.password_reset, name='password_reset'),
url(r'^password-reset/done/$', django_views.password_reset_done, name='password_reset_done'),
url(r'^password-reset/confirm/(?P<uidb64>[-\w]+)/(?P<token>[-\w]+)/$', django_views.password_reset_confirm, name='password_reset_confirm'),
url(r'^password-reset/complete/$', django_views.password_reset_complete, name='password_reset_complete'),
]
Login template:
{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
<h1>Log-in</h1>
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% else %}
<p>Please, use the following form to log-in. If you don't have an account register here</p>
{% endif %}
<div class="login-form">
<form action="{% url "account:login" %}" method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<p><input type="submit" value="Log-in"></p>
</form>
<p>Forgotten your password?</p>
</div>
<div class="social">
</div>
{% endblock %}
Edit (views.py):
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from .forms import LoginForm, UserRegistrationForm, UserEditForm, ProfileEditForm
from .models import Profile
def user_login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(username=cd['username'], password=cd['password'])
if user is not None:
if user.is_active:
login(request, user)
return HttpResponse('Authenticated successfully')
else:
return HttpResponse('Disabled account')
else:
return HttpResponse('Invalid login')
else:
form = LoginForm()
return render(request, 'account/login.html', {'form': form})
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(user_form.cleaned_data['password'])
# Save the User object
new_user.save()
# Create the user profile
profile = Profile.objects.create(user=new_user)
return render(request,
'account/register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})
#login_required
def edit(request):
if request.method == 'POST':
user_form = UserEditForm(instance=request.user,
data=request.POST)
profile_form = ProfileEditForm(instance=request.user.profile,
data=request.POST,
files=request.FILES)
if user_form.is_valid() and profile_form.is_valid():
user_form.save()
profile_form.save()
messages.success(request, 'Profile updated successfully')
else:
messages.error(request, 'Error updating your profile')
else:
user_form = UserEditForm(instance=request.user)
profile_form = ProfileEditForm(instance=request.user.profile)
return render(request, 'account/edit.html', {'user_form': user_form,
'profile_form': profile_form})
#login_required
def dashboard(request):
return render(request, 'account/dashboard.html', {'section': 'dashboard'})

Somewhere, in a template you haven't shown, you have done {% url "dashboard" %}, but that URL is under the account namespace. So you need to do {% url "account:dashboard" %}.

Related

Newly registered users are not being reflected in the database in 'Django Administration' page after I login as an admin

I am trying to build a user login/signup page using Django. Everything works fine except when I try to register new users by clicking on the register button, the newly registered users are not being reflected in the database in 'Django Administration' page after I login as an admin. Please help.
Here's my code:
urls.py-login
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls'))
]
urls.py-accounts
from django.urls import path
from . import views
urlpatterns = [
path('', views.indexView, name = "home"),
path('dashboard/', views.dashboardView, name = "dashboard"),
# path('login/',),
path('register/',views.registerView, name = "register_url"),
# path('logout,'),
]
views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
# Create your views here.
def indexView(request):
return render(request, 'index.html')
def dashboardView(request):
return render(request, 'dashboard.html')
def registerView(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login_url')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form':form})
index.html
<!DOCTYPE html>
<html>
<head>
<title>Petrol Pump Management System</title>
</head>
<body>
{% block content %}
<h1>User Authentication</h1>
{% endblock %}
</body>
</html>
register.html
{% extends 'index.html'%}
{% block content %}
<h1>Create new account</h1>
<form method = "POST">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Register</button>
</form>
{% endblock %}

Cannot find url

I got an error that,
Page not found (404)
Request Method: GET
Request URL: `http://localhost:8000/accounts/registration/accounts/registration/accounts/registration/accounts/profile.html` .
I think routes are wrong But I cannot understand how to fix the routes.
In accounts app,I wrote
in urls.py
from django.conf.urls import url
from . import views
from django.contrib.auth.views import login, logout
urlpatterns = [
url(r'^login/$', login,
{'template_name': 'registration/accounts/login.html'},
name='login'),
url(r'^logout/$', logout, name='logout'),
url(r'^regist/$', views.regist,name='regist' ),
url(r'^regist_save/$', views.regist_save, name='regist_save'),
url(r'^registration/accounts/registration/accounts/profile.html$', views.regist_save, name='regist_save'),
]
in views.py
#require_POST
def regist_save(request):
form = RegisterForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
context = {
'user': request.user,
}
return redirect('registration/accounts/profile.html', context)
context = {
'form': form,
}
return render(request, 'registration/accounts/regist.html', context)
in accounts(child app)/templates/registration/accounts/profile.html directory,
{% extends "registration/accounts/base.html" %}
{% block content %}
user.username: {{ user.username }}<hr>
user.is_staff: {{ user.is_staff }}<hr>
user.is_active: {{ user.is_active }}<hr>
user.last_login: {{ user.last_login }}<hr>
user.date_joined: {{ user.date_joined }}
{% endblock %}
You have some serious misunderstandings here.
You can't have a template without a view. You have written a template for the profile, but you haven't written a view. You need the view that loads the profile data and then renders the profile.html template.
Secondly, your URL has nothing to do with the template location; as you have done in regist_save, you should define a sensible URL pointing to that view - for the profile, you probably want something like r'^profile/$'.
So, the fifth entry in your urls.py should be:
url(r'^profile/$', views.profile, name='profile'),
and you need a corresponding function named profile in views.py.
Finally, when you redirect you need to use an actual URL entry - again, it has nothing to do with templates. So in your regist_save view, you should do:
return redirect('profile')

Django User-Login and authentication is not working

I am creating a simple user-login page using Django and after get login redirecting to home page.But its always redirecting to unauthorized option given in app's views.py (i.e Invalid Details). Please check and help me.
Project name:login and App name: index
views.py
from django.shortcuts import render_to_response
from django.contrib import auth
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout
from django.core.context_processors import csrf
# Create your views here.
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def auth(request):
username = request.GET.get('username', '')
password = request.GET.get('password', '')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect("/home/")
else:
return HttpResponse("Bad request")
else:
return HttpResponse("Invalid details")
#login_required
def home(request):
return render_to_response('home.html')
App urls.py
from django.conf.urls import url
from django.contrib import admin
from django.contrib.auth.views import login, logout
from . import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', views.login, name='login'),
url(r'^auth/$', views.auth, name='auth'),
url(r'^home/$', views.home, name='home'),
]
Project's: urls.py:
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('index.urls')),
]
Templates:
login.html
{% block content %}
{% if form.errors %}
<p class="error">Sorry, that's not a valid username or password</p>
{% endif %}
<form action="/auth/" method="post">{% csrf_token %}
<label for="username">User name:</label>
<input type="text" name="username" value="" id="username">
<label for="password">Password:</label>
<input type="password" name="password" value="" id="password">
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next|escape }}" />
</form>
{% endblock %}
home.html
{% block content %}
<h1>Hello Vivek</h1>
{% endblock %}
Im going to share another approach to manage authentication in django assuming you already have a login html template (with username and password inputs inside a form with post action) , a user form and a home template , this would be the authentication views .py :
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect
from django.views.generic import View
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.contrib.auth import login, authenticate, logout
from ..form import UsersForm
class LoginView(View):
template_name = ['yourtemplatedirectory/login.html', 'yourtemplatedirectory/home.html']
def get(self, request, *args, **kwargs):
form = UsersForm()
if request.user.is_authenticated():
return render(request, self.template_name[1])
return render(request, self.template_name[0])
def post(self, request, *args, **kwargs):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username, password = password)
if user is not None:
login(request, user)
if user.is_active:
return render(request, self.template_name[ 1 ])
else:
messages.add_message(
request, messages.ERROR, "Invalid username or password"
)
return HttpResponseRedirect(reverse( 'yourapp:login' ))
def LogoutView(request):
logout(request)
return HttpResponseRedirect(reverse( 'yourapp:home' ))
Just call the respective url from login and logout buttons and that's it. Hope it helps !!
Change from
username = request.GET.get('username', '')
password = request.GET.get('password', '')
to
username = request.POST.get('username', '')
password = request.POST.get('password', '')

Django application deployed at suburl, redirect to home page after login

I have my page deployed at http://example.com. I also have my django application deployed at http://example.com/djangoapp.
I'm using Apache 2.2 with this configuration (/etc/apache2/apache2.conf): WSGIPythonPath /home/brian/djangoprojects/djangoapp.
I also added the line WSGIScriptAlias /djangoapp /home/brian/djangoprojects/djangoapp/djangoapp/wsgi.py to the default Apache Virtual Host file and it works really nice.
However, after logging in, my application redirects me to http://example.com/ instead of http://example.com/djangoapp/homeit.
Here's my urls.py file:
from django.conf.urls import include, url
from django.contrib import admin
from djangoapp import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'django.contrib.auth.views.login', name="login"),
url(r'^logout/$', views.logout_page, name="logout"),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name="login"),
url(r'^register/$', views.register, name="register"),
url(r'^register/success/$', views.register_success, name="register_success"),
url(r'^homeit/$', views.homeit, name="homeit"),
]
Here's my views.py file:
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.contrib.auth.models import User
from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from djangoapp.forms import RegistrationForm
#csrf_protect
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = User.objects.create_user(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
email=form.cleaned_data['email']
)
return HttpResponseRedirect(reverse('register_success'))
else:
form = RegistrationForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response(
'registration/register.html',
variables,
)
def register_success(request):
return render_to_response('registration/success.html')
def logout_page(request):
logout(request)
return HttpResponseRedirect(reverse('login'))
#login_required
def homeit(request):
return render_to_response(('home.html', {'user': request.user}))
My settings file, settings.py:
LOGIN_URL = '/djangoapp/accounts/login/'
USE_X_FORWARDED_HOST = True
SUB_SITE = "/djangoapp"
And finally, the login page which I'm using to log in:
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block head %}Login{% endblock %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form method="post" action=".">{% csrf_token %}
<table border="0">
<tr><th><label for="id_username">Username:</label></th><td>{{ form.username }}</td></tr>
<tr><th><label for="id_password">Password:</label></th><td>{{ form.password }}</td></tr>
</table>
<input type="submit" value="Login" />
<input type="hidden" name="next" value="{% url "homeit" %}" />
</form>
Register
{% endblock %}
Quick read
Method to solve this:
Add LOGIN_REDIRECT_URL = '/djangoapp/homeit' in settings.py
Change your urls.py line 9 to url(r'^accounts/login/$', 'django.contrib.auth.views.login', {'extra_context': {'next':'/djangoapp/homeit'}}),
Explanation
Check for the documentation of django.contrib.auth.views.login present here
The code for def login is as follows:
def login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
"""
Displays the login form and handles the login action.
"""
redirect_to = request.POST.get(redirect_field_name,
request.GET.get(redirect_field_name, ''))
if request.method == "POST":
form = authentication_form(request, data=request.POST)
if form.is_valid():
# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=redirect_to, host=request.get_host()):
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
# Okay, security check complete. Log the user in.
auth_login(request, form.get_user())
return HttpResponseRedirect(redirect_to)
else:
form = authentication_form(request)
current_site = get_current_site(request)
context = {
'form': form,
redirect_field_name: redirect_to,
'site': current_site,
'site_name': current_site.name,
}
if extra_context is not None:
context.update(extra_context)
if current_app is not None:
request.current_app = current_app
return TemplateResponse(request, template_name, context)
What is happening:
django.contrib.auth.views.login takes redirect_field_name and redirect accordingly
Default value of redirect_field_name is next.
Currently as you aren't passing anything as next parameter, it is making redirect_to = '' automatically.
HttpResponseRedirect is being called as HttpResponseRedirect('')
Thus it end up redirecting to your homepage, and not /djangoapp.

Cross Site Request Forgery Issue in Django

I am getting this error when trying to implement csrf in django.
Forbidden (403)
CSRF verification failed. Request aborted.
Help
Reason given for failure:
CSRF token missing or incorrect. (and bla bla bla)
My Views.py shows following:
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from django.contrib.auth.forms import UserCreationForm
def login(request):
c = {}
c.update(csrf(request))
return render_to_response('login.html', c)
def auth_view(request):
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username, password=password)
if user is not None:
auth.login(request, user)
return HttpResponseRedirect('/accounts/loggedin')
else:
return HttpResponseRedirect('/accounts/invalid')
def loggedin(request):
return render_to_response('loggedin.html',{'full_name':request.user.username})
def invalid_login(request):
return render_to_response('invalid_login.html')
def logout(request):
auth.logout(request)
return render_to_response('logout.html')
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args ={}
args.update(csrf(request))
args['form'] = UserCreationForm()
return render_to_response('register.html')
def register_success(request):
return render_to_response('register_success.html')
My register.html reflects following:
{% extends 'base.html' %}
{% block content %}
<h2>Register</h2>
<form action="/accounts/register/" method="post">{% csrf_token %}
{{ form }}
<input type="submit" value="Register"/>
</form>
{% endblock %}
In urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^articles/', include('article.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/login/$', 'django_test.views.login'),
url(r'^accounts/auth/$', 'django_test.views.auth_view'),
url(r'^accounts/logout/$', 'django_test.views.logout'),
url(r'^accounts/loggedin/$', 'django_test.views.loggedin'),
url(r'^accounts/invalid/$', 'django_test.views.invalid_login'),
url(r'^accounts/register/$', 'django_test.views.register_user'),
url(r'^accounts/register_success/$', 'django_test.views.register_success'),
)
Please advise. I got cookies enabled in browser.
In register.html you need to add csrf token within <form> </form> like this: {% csrf_token %}, hopefully it will resolve the problem.
This might not be the best practice but you can add:
#csrf_exempt
Just above the functions in the view.py file.
See example in django-rest-framework tutorial:
Writing regular Django views

Categories