I have a django project with a structure like this:
my_project
|_ UserSignUp
|_ urls.py
|_ views.py
|_ Mainpage
|_ urls.py
|_ views.py
|_ my_project
|_ urls.py
|_ settings.py
My problem is as follows:
I can access mysite.com/index and mysite.com/login just fine. But if I try to open mysite.com/signup I encounter a 500 Internal Server Error, more precisely an Error is thrown:
NoReverseMatch at /signup/
Reverse for 'login' not found. 'login' is not a valid view function or pattern name.
Of course I already googled the error but did not encounter anything particularly helpful. The descriptions I found explained errors, in which an url of an app had been tried to access, then failing because the namespace of the app was not provided in the url tag. In my case I am inside an app and want to access an url of the project root. As far as I know it should be automatically resolved and even if not, I don't know how to tell django to please look into the root urls. Is django not checking the root urls really cause of the problem or is there another thing I set up wrong? How can I fix this?
My root urls.py:
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', include('Mainpage.urls')),
path('index/', include('Mainpage.urls')),
path('mainpage/', include('Mainpage.urls')),
path('home/', include('Mainpage.urls')),
path('login/', auth_views.LoginView.as_view(template_name='login/login.html', redirect_field_name='index')),
path('signup/', include('UserSignUp.urls')),
path('logout', auth_views.LogoutView.as_view(template_name='logout/logout.html', next_page='index')),
path('admin/', admin.site.urls),
]
My UserSignUp urls.py:
from django.urls import path
from django.conf.urls import include
from UserSignUp import views
urlpatterns = [
path(r'', views.signup, name='signup'),
path(r'account_activation_sent/', views.account_activation_sent, name='account_activation_sent'),
path(r'activate/', views.activate, name='activate')
]
My UserSignUp views.py:
from django.contrib.auth import login
from django.contrib.auth.models import User
from django.contrib.sites.shortcuts import get_current_site
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.template.loader import render_to_string
from UserSignUp.forms import SignUpForm
from UserSignUp.tokens import account_activation_token
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
subject = 'Activate Your MySite Account'
message = render_to_string('account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
return redirect('signup/account_activation_sent')
else:
form = SignUpForm()
return render(request, 'UserSignUp/signup.html', {'form': form})
def account_activation_sent(request):
return render(request, 'UserSignUp/account_activation_sent.html')
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.profile.email_confirmed = True
user.save()
login(request, user)
return redirect('index')
else:
return render(request, 'UserSignUp/account_activation_invalid.html')
The signup.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Signup</title>
</head>
<body>
<header>
<h1>My Site</h1>
{% if user.is_authenticated %}
logout
{% else %}
login / signup #<----- here it encounters error
{% endif %}
<hr>
</header>
<main>
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{% for field in form %}
<p>
{{ field.label_tag }}<br>
{{ field }}
{% if field.help_text %}
<small style="color: grey">{{ field.help_text }}</small>
{% endif %}
{% for error in field.errors %}
<p style="color: red">{{ error }}</p>
{% endfor %}
</p>
{% endfor %}
<button type="submit">Sign up</button>
</form>
</main>
</body>
</html>
You need to specify the name of login and logout views in urls.py
urlpatterns = [
# rest of your URL configs
path('login/', auth_views.LoginView.as_view(template_name='login/login.html', redirect_field_name='index'),
name='login'),
path('logout', auth_views.LogoutView.as_view(template_name='logout/logout.html', next_page='index'),
name='logout'),
]
Related
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 %}
So, I have a code below:
newEra/urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("",include('mentor.urls')),]
mentor/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('',views.home_page),
]
my views.py
from django.shortcuts import render,redirect
from .models import *
from .forms import *
def home_page(request):
todo = ToDo.objects.all()
form = ToDoForms()
if request.method == 'POST':
form = ToDoForms(request.POST)
if form.is_valid():
form.save()
return redirect('')
context = {'todo' : todo, 'form':form}
return render(request, 'home.html',context)
home.html
<h1>To-Do list</h1>
<form action="POST" method="/">
{% csrf_token %}
{{form.name}}
<input type="submit" value="Create task" >
</form>
<ul>
{% for to in todo %}
<li>{{ to }}</li>
{% endfor %}
</ul>
But I am getting this error below
**Using the URLconf defined in NewEra.urls, Django tried these URL patterns, in this order:
admin/
The current path, POST, didn't match any of these.**
'mentor' file added to the SETTINGS
URLs are regexes.
Try:
urlpatterns = [
path('^/$',views.home_page),
]
Login cannot be done in my app.I wrote in views.py
from django.shortcuts import render,redirect
from django.urls import reverse
from app.forms import RegisterForm,LoginForm
from app.models import Data
from app.forms import DataForm
from django.db.models import Q
def index(request):
data = Data.objects.order_by('-created_at')
form = RegisterForm()
loginform = LoginForm()
dataform = DataForm()
return render(request, 'index.html',{'data':data,'form':form,'loginform':loginform,'dataform':dataform,'user': request.user})
in index.html
<section id="top">
{% if user and not user.is_anonymous %}
<p>Hello</p>
<h3>{{ user.username }}</h3>
{% else %}
<form action="{% url 'app:index' %}" method="POST">
{{ loginform.non_field_errors }}
{% for field in loginform %}
{{ field }}
{{ field.errors }}
{% endfor %}
<button type="submit">LOGIN</button>
{% csrf_token %}
</form>
{% endif %}
</section>
in forms.py
from django import forms
from django.contrib.auth.forms import (
AuthenticationForm
)
class LoginForm(AuthenticationForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
field.widget.attrs['placeholder'] = field.label
in child's app's urls.py
from django.urls import include, path
from . import views
from django.contrib.auth.views import login
app_name = 'app'
urlpatterns = [
path('index', views.index,name='index'),
]
in parent's app's urls.py
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('app/',include('app.urls') ),
]
When I login from loginform,if statement of {% if user and not user.is_anonymous %} did not become true.But when I login in admin site, the statement become true.When I put LOGIN button, no error happens.I really cannot understand what is wrong.How should I fix this?
Your index view doesn't do anything when a POST request is submitted. It just initialises empty forms and returns them. You need to actually process the data that is submitted, authenticate the user and call the login method:
def index(request):
if request.method == 'POST':
loginform = LoginForm(request, data=request.POST)
if loginform.is_valid(): # this authenticates the user
user = loginform.get_user()
# redirect to success view or just render index.html
return render(request, 'index.html', {'user': user})
# else not needed, we go to the end and return the form with errors
else: # request method is 'GET'
loginform = LoginForm()
dataform = ...
...
return render(request, 'index.html',{'data':data,'form':form,'loginform':loginform,'dataform':dataform,'user': request.user})
I'm relatively new to django and trying to create a home page that has a login form on it, consisting of username and pw bars. I was trying to recreate what I saw here in my own project:
homepage login form Django
but I keep getting back
NameError: name 'url' is not defined. I am pretty lost on what is causing this. I was initially writing into the project level urls.py but then moved to the app level (accounts) urls.py because that makes sense to me...but I'm not confident about this.
Here are my files:
project
├── manage.py
├── db.sqlite3
├── templates
├── accounts
| ├──migrations
| ├──_pycache_
| ├──admin.py
| ├──apps.py
| ├──models.py
| ├──_init__.py
| ├──urls.py
| ├──tests.py
| └──views.py
└── project
├── settings.py
├── urls.py
└── wsgi.py
project/settings.py
from django.urls import reverse_lazy
import os
...
SITE_ID = 1
LOGIN_URL = reverse_lazy('login')
LOGIN_REDIRECT__URL = reverse_lazy('home')
LOGOUT_REDIRECT__URL = '/'
enter code here
project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('accounts/', include('accounts.urls')),
path('accounts/', include('allauth.urls')),
path('', include('posts.urls')),
]
accounts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.SignUpView.as_view(), name='signup'),
url(r'^accounts/', HomeView.as_view(template_name='../templates/home.html', name='home')),
url(r'^accounts/login/$', 'django.contrib.auth.views.login', name='login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', name='logout'),
]
accounts/views.py
from django.shortcuts import render
from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views import generic
from django.views.generic.base import TemplateView
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
class SignUpView(generic.CreateView):
form_class = UserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
class HomeView(TemplateView):
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super(HomeView, self).dispatch(*args, **kwargs)
templates/home.html
<!--user checks-->
{% if user.is_authenticated %}
<div class = "greeting">
Hi {{ user.username }}!
logout
</div>
{% else %}
<div class = "register">
sign up!
</div>
login
<form method = "post" action = "{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<!--username bar-->
<div class="container-2">
{{ form.username.label_tag }}
{{ form.username }}
</div>
<!--pw bar-->
<div class="container-3">
{{ form.password.label_tag }}
{{ form.password }}
</div>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endif %}
You need to import url in accounts/urls.py:
from django.conf.urls import url
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.