Django crazy URL rewrites - python

I'm currently facing an issue that I really don't understand at all, I searched through the whole code and was not able to find any references there, I deleted all caches, databases, venv etc. With no effects at all.
It's all about the 'login' url pattern
urls.py
from Project_Accounts import views as Project_Accounts
....
url(r'^admin/', admin.site.urls),
# Reg and Auth
url(r'^login/$', Project_Accounts.login, name='login'),
url(r'^signup/$', Project_Accounts.signup, name='signup'),
....
urlpatterns += [
path('Project_Accounts/', include('django.contrib.auth.urls')),
]
base.html
{% if user.is_anonymous %}
<a href="{% url 'signup' %}" class="top-menu">
<button type="button" class="btn btn-success">Sign-Up</button>
</a>
<a href="{% url 'login' %}" class="top-menu">
<button type="button" class="btn btn-primary">Login</button>
</a>
{% endif %}
views.py (Project_Accounts)
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST, request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
request.session.flush()
if user.pubpgp:
if user.pubpgp_enabled:
request.session['userID'] = user.pk
return redirect(reverse('login_2fa'))
else:
hybridlogin(request, user)
return redirect(reverse('home'))
else:
hybridlogin(request, user)
# Redirect to a success page.
return redirect(reverse('home'))
else:
return render(request, 'Project_Accounts/login.html', {'form': form})
else:
return render(request, 'Project_Accounts/login.html', {'form': LoginForm()})
If my base.html gets displayed, signup view works fine, and every other also except the login. The URL I get back for login is
127.0.0.1:8000/Project_Accounts/login
but it used to be
127.0.0.1:8000/login
Any idea why that can appear?!
There is really no reference here and the error that gets generated by the WSGI server is:
TemplateDoesNotExist at /Project_Accounts/login/
registration/login.html
Request Method: GET
Request URL: http://127.0.0.1:8000/Project_Accounts/login/
Django Version: 2.1.4
Exception Type: TemplateDoesNotExist
Exception Value:
registration/login.html
Where does registration/login.html comes from!?!?
Makes no sense to me and I also don't find any reference here in my code.
I'm thankful for every hint.
Kind regards.

Related

django 3.1 multilanguage site breaks login

I have set up a django 3.1 site that uses 2 languages, English and German, and I use i18n_patterns in my urls.py. The problem is, in my views.py method, I never get a POST request, even though I specify method="POST" in my form. It always comes in as a GET request, and I cannot login. Somewhere along the way, the system changes my POST request into a GET request.
urlpatterns = []
urlpatterns += i18n_patterns(
path('{}/'.format(settings.DJANGO_ADMIN_URL), admin.site.urls),
path('review/', include('review.urls')),
path('anmelden_success/', views.anmelden_success, name='anmelden_success'),
path('', views.site_login, name='site_login'),
path('site_login/', views.site_login, name='site_login'),
path('site_logout/', views.site_logout, name='site_logout'),
)
I log in with this form, specifying method="POST":
<form action="/site_login/" method="POST" id="login-form">{% csrf_token %}
<label class="required" for="id_username">Benutzer:</label> <input type="text" name="username" autofocus required id="id_username">
<label class="required" for="id_password">Passwort:</label> <input type="password" name="password" required id="id_password">
<input type="hidden" name="next" value="/review/">
<label> </label><input type="submit" value="Anmelden">
</form>
The request comes to my views.py method site_login:
def site_login(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 redirect('/anmelden_success')
else:
return HttpResponse("Sorry, you failed to login.")
else:
if request.user.is_authenticated:
return redirect('/review')
else:
return render(request, 'registration/login.html')
Since it somehow gets changed from a POST request to a GET request, my login fails, and I come straight back to my login page with the /de/ (or /en/) prepended: /de/site_login
If I remove i18n_patterns from my urls.py, I can login using the POST request.
urlpatterns = [
path('{}/'.format(settings.DJANGO_ADMIN_URL), admin.site.urls),
path('review/', include('review.urls')),
path('anmelden_success/', views.anmelden_success, name='anmelden_success'),
path('', views.site_login, name='site_login'),
path('site_login/', views.site_login, name='site_login'),
path('site_logout/', views.site_logout, name='site_logout'),
]
#urlpatterns += i18n_patterns()
With this urls.py config, I can login. But I have lost the multiple language functionality.
How can I have both?
Thanks in advance for any tips.
try to add url like this <form action="{% url 'site_login' %}"> in your form instead of <form action="/site_login/">

No Reverse Match For Some URLs in Django 1.10

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" %}.

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 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.

Django User Logout Fails to Redirect Homepage

After log out user in my django web app, the redirected homepage still displays the "Log Out" button instead of the "Sign in with Facebook". In the following code, I follow the django documentation to logout the user and redirect the page to homepage which is the base.html. It seems that my web app still has user.is_authenticated as True after log out? What am I missing?
I cannot find any useful hint online. Any comment is much appreciated.
Here is part of my template html
<div class="navbar-form navbar-right">
{% if user.is_authenticated %}
<a id="logout" href="/accounts/logout" class="btn btn-success">Logout</a>
{% else %}
<a id="facebook_login" href="/accounts/facebook/login" class="btn btn-success">Sign in with Facebook</a>
{% endif %}
</div>
Here is my urls.py
url(r'^$', 'homepage.views.home', name='home'),
url(r'^accounts/', include('allauth.urls')),
url(r'^accounts/logout/$', 'homepage.views.logout', name='logout'),
Here is my homepage/views.py
# Create your views here.
def home(request):
return render(request, "base.html", {})
# ensure only logged in users can access the view.
#login_required
def logout(request):
logout(request)
# Take the user back to the homepage.
return redirect('home')
There are 2 things here:
You need to reorder the URLs
from:
url(r'^accounts/', include('allauth.urls')),
url(r'^accounts/logout/$', 'homepage.views.logout', name='logout'),
to
url(r'^accounts/logout/$', 'homepage.views.logout', name='logout'),
url(r'^accounts/', include('allauth.urls')),
This way, your logout takes precedence over the allauth's logout URL pattern
You should be aliasing the imported logout, or rename your logout to something different.
Example:
from django.contrib.auth import logout as auth_logout
and then
def logout(request):
auth_logout(request)
....

Categories