I'm attempting to setup a login using django and bootstrap found here and here
my views.py
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
else:
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
else:
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
else:
form = LoginForm()
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
my urls.py
from core.views import LoginRequest, LogoutRequest, ContactRequest
urlpatterns = patterns('',
url(r'^login/$', 'LoginRequest'),
url(r'^logout/$', 'LogoutRequest'),
my forms.py
class LoginForm(forms.Form):
email = forms.CharField(label=(u'Email'), max_length=30)
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False), max_length=30)
And the snippet from my index.html -
{% if user.is_authenticated %}
<li><a href={% url 'dashboard' %}>Dashboard</a></li>
{% else %}
<li class="dropdown">
<a class="dropdown-toggle" href="#" data-toggle="dropdown">Login<strong class="caret"></strong></a>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 10px;">
<form action='/login/' method="POST">
{% csrf_token %}
{% if form.errors %}
{{ form.errors}}
{% endif %}
<label for="id_email">Login:</label>
<input type="text" name="email" id="id_email">
<br />
<label for="id_password">Pass:</label>
<input type="password" name="password" id="id_password">
<br />
<input class="btn btn-primary" type="submit" value="Login" />
<input type="hidden" name="next" value="{{ '/dashboard' }}" />
</form>
</div>
</li>
{% endif %}
As soon as I hit "login" I get the following traceback -
Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
Exception Type: TypeError at /login/
Exception Value: 'unicode' object is not callable
In your urls file, you need to remove the string around the view names.
Like this:
urlpatterns = patterns('',
url(r'^login/$', LoginRequest), #Shred the quotes
url(r'^logout/$', LogoutRequest), #Shred the quotes
Note that the new django recommended way is:
from core import views
urlpatterns = patterns('',
url(r'^login/$', views.LoginRequest),
url(r'^logout/$', views.LogoutRequest),
Also, you can simplify your view like this:
def LoginRequest(request):
redirect_to = request.META.get('HTTP_REFERER', '/')
if request.user.is_authenticated():
return HttpResponseRedirect(redirect_to)
form = LoginForm()
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
return HttpResponseRedirect(redirect_to)
return render_to_response('/', {'form': form}, context_instance=RequestContext(request))
Also, / needs to be something like: /index.html - depends on where the template is located.
Related
So my code looked like this at first:
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Information
from django.db.models import Q
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from .forms import MyForm
# rooms = [
# {'id': 1, 'name': 'Lets learn python!'},
# {'id': 2, 'name': 'Design with me'},
# {'id': 3, 'name': 'Frontend developers'},
# ]
def home(request):
q = request.GET.get('q') if request.GET.get('q') !=None else ''
information_search = Information.objects.filter(
Q(host__icontains=q) |
Q(hostname__icontains=q) |
Q(port__icontains=q) |
Q(platform__icontains=q) |
Q(username__icontains=q) |
Q(password__icontains=q) |
Q(groups__icontains=q)
)
sort_info = []
informations = Information.objects.all()
for i in informations:
if i.groups not in sort_info:
device_group = i.groups
sort_info.append(device_group)
information_count=information_search.count()
context = {'informations':informations, 'information_search':information_search, 'information_count':information_count, 'sort_info':sort_info}
return render(request, 'polls/home.html', context)
def view_data(request, pk):
information = Information.objects.get(id=pk)
context = {'information':information}
return render(request, 'polls/view_data.html', context)
def loginPage(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'User does not exist')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, "Username or password does not exist")
context = {}
return render(request, 'polls/login_register.html', context)
def logoutUser(request):
logout(request)
return redirect('home')
def edit_data(request, pk):
information = Information.objects.get(id=pk)
form = MyForm(instance=information)
if request.method == 'POST':
form = MyForm(request.POST, instance=information)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form}
return render(request, 'polls/room_form.html', context)
def delete_data(request, pk):
information = Information.objects.get(id=pk)
if request.method == 'POST':
information.delete()
return redirect('home')
return render(request, 'polls/delete.html', {'obj': information})
def my_form(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = MyForm()
return render(request, 'polls/room_form.html', {'form': form})
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('login/', views.loginPage, name="login"),
path('logout/', views.logoutUser, name="logout"),
path('', views.home, name='home'),
path('view_data/<str:pk>/', views.view_data, name = "view_data"),
path('edit_data/<str:pk>/', views.edit_data, name = "edit_data"),
path('host/', views.my_form, name='my_form'),
path('delete/<str:pk>/', views.delete_data, name='delete_data')
]
login_register.html
{% extends 'main.html' %}
{% block content %}
<div>
<form method="POST" action="">
{% csrf_token %}
<label>Username:</label>
<input type="text" name="username" placeholder="Enter Username" />
<label>Password:</label>
<input type="password" name="password" placeholder="Enter Password">
<input type="submit" value="login">
</form>
</div>
{% endblock content %}
I wanted to change the authentication system so that the home view is only returned if the user is logged in. I was able to show home view after the user logs in by making small changes to urls.py and login_register.html as follows:
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Information
from django.db.models import Q
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from .forms import MyForm
# rooms = [
# {'id': 1, 'name': 'Lets learn python!'},
# {'id': 2, 'name': 'Design with me'},
# {'id': 3, 'name': 'Frontend developers'},
# ]
def home(request):
q = request.GET.get('q') if request.GET.get('q') !=None else ''
information_search = Information.objects.filter(
Q(host__icontains=q) |
Q(hostname__icontains=q) |
Q(port__icontains=q) |
Q(platform__icontains=q) |
Q(username__icontains=q) |
Q(password__icontains=q) |
Q(groups__icontains=q)
)
sort_info = []
informations = Information.objects.all()
for i in informations:
if i.groups not in sort_info:
device_group = i.groups
sort_info.append(device_group)
information_count=information_search.count()
context = {'informations':informations, 'information_search':information_search, 'information_count':information_count, 'sort_info':sort_info}
return render(request, 'polls/home.html', context)
def view_data(request, pk):
information = Information.objects.get(id=pk)
context = {'information':information}
return render(request, 'polls/view_data.html', context)
def loginPage(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
try:
user = User.objects.get(username=username)
except:
messages.error(request, 'User does not exist')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
else:
messages.error(request, "Username or password does not exist")
context = {}
return render(request, 'polls/login_register.html', context)
def logoutUser(request):
logout(request)
return redirect('home')
def edit_data(request, pk):
information = Information.objects.get(id=pk)
form = MyForm(instance=information)
if request.method == 'POST':
form = MyForm(request.POST, instance=information)
if form.is_valid():
form.save()
return redirect('home')
context = {'form': form}
return render(request, 'polls/room_form.html', context)
def delete_data(request, pk):
information = Information.objects.get(id=pk)
if request.method == 'POST':
information.delete()
return redirect('home')
return render(request, 'polls/delete.html', {'obj': information})
def my_form(request):
if request.method == "POST":
form = MyForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = MyForm()
return render(request, 'polls/room_form.html', {'form': form})
login_register.html
{% extends 'main.html' %}
{% block content %}
<div>
<form method="POST" action="home/">
{% csrf_token %}
<label>Username:</label>
<input type="text" name="username" placeholder="Enter Username" />
<label>Password:</label>
<input type="password" name="password" placeholder="Enter Password">
<input type="submit" value="login">
</form>
</div>
{% endblock content %}
However the bar at navbar.html which shows logout option if the user is logged in stops working..
navbar.html
<a href="/polls">
<h1>LOGO</h1>
</a>
<form method="GET" action="{% url 'home' %}">
<input type="text" name="q" placeholder="Search Devices...">
</form>
{% if request.user.is_authenticated %}
Logout
{% else %}
Login
{% endif %}
<hr>
navbar is included in main.html as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>StudyBud</title>
</head>
<body>
{% include 'navbar.html' %}
{% block content %}
{% endblock %}
</body>
</html>
and main.html is extended by other templates. Here main.html and navbar.html are stored in the templates folder of the root directory while other templates are in the 'polls' app folder.
If it helps here are my other files.
models.py
from django.db import models
from django.contrib.auth.models import User
class Information(models.Model):
host = models.CharField(max_length=200, null=True, blank=False)
hostname = models.CharField(max_length=200, null=True, blank=False)
port = models.IntegerField()
platform = models.CharField(max_length=200, null=True, blank=False)
username = models.CharField(max_length=200, null=True, blank=False)
password = models.CharField(max_length=200, null=True, blank=False)
groups = models.CharField(max_length=200, null=True, blank=False)
def __str__(self):
return self.host
Here is home.html which extends main.html and is supposed to show the logout bar.
{% extends 'main.html' %}
{% block content %}
<h2>Inventory Management</h2>
<style>
.home-container{
display: grid;
grid-template-columns: 1fr 3fr;
}
</style>
<div class="home-container">
<div>
<h3>Browse Groups</h3>
<hr>
{% for i in sort_info %}
<div>
{{i}}
<br><br>
</div>
{% endfor %}
</div>
<div>
<h5>{{information_count}} devices registered</h5>
<hr>
Add Device
<hr>
{% for information in information_search %}
<span>#{{information.host}}</span>
<h3> view </h3>
Edit
Delete
<hr>
{% endfor %}
</div>
</div>
{% endblock content %}
</div>
Any insight please? I am a beginner and I was trying to make changes and implement my own features in the code i followed through a tutorial.
Good day,
Using Django 1.11, I have created signin and signup forms.
My signin form is working correctly, but my signup form is using the GET method, not the POST method specified. Using the inspector on the signin form, it just shows . The method="POST" action="...." are missing and I cannot see why.
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'signin/$', views.sign_in, name='signin'),
url(r'signup/$', views.sign_up, name='signup'),
url(r'signout/$', views.sign_out, name='signout'),
]
views.py
def sign_in(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
if form.user_cache is not None:
user = form.user_cache
if user.is_active:
login(request, user)
return HttpResponseRedirect(
reverse('stb:home')
)
else:
messages.error(
request,
"That user account has been disabled."
)
else:
messages.error(
request,
"Username or password is incorrect."
)
return render(request, 'stb/signin.html', {'form': form})
def sign_up(request):
form = UserCreationForm()
if request.method == 'POST':
form = UserCreationForm(data=request.POST)
if form.is_valid():
# Unpack form values
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
# Create the User record
user = User(username=username, email=email)
user.set_password(password)
user.save()
user = authenticate(
username=username,
password=password
)
login(request, user)
messages.success(
request,
"You're now a user! You've been signed in, too."
)
return HttpResponseRedirect(reverse('stb:profile'))
return render(request, 'stb/signup.html', {'form': form})
signup.html:
{% extends "layout.html" %}
{% block title %}{{ block.super }} | Sign Up{% endblock %}
{% block body %}
<div class="grid-30 centered">
<h2>Sign Up</h2><form>
<form method="POST" action="{% url 'stb:signup' %}">
{% csrf_token %}
<input name="username" id="id_username" required="" autofocus=""
placeholder="User Name" maxlength="150" type="text">
<input name="email" id="id_email" required=""
placeholder="Email Address" type="email">
<input name="password1" required="" id="id_password1"
placeholder="Password" type="password">
<input name="password2" required="" id="id_password2"
placeholder="Confirm Password" type="password">
<input type="submit" class="button-primary" value="Sign Up">
<a class="button" href="signin.html">Sign In</a>
<input type="hidden" name="next" value="{{ next }}" />
</form>
</div>
{% endblock %}
Try moving the form assignment in the first line to the else statement of the if ,
Like this,
def sign_up(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password1']
email = form.cleaned_data['email']
user = User(username=username, email=email)
user.set_password(password)
user.save()
user = authenticate( username=username, password=password )
login(request, user)
messages.success( request, "You're now a user! You've been signed in, too." )
return HttpResponseRedirect(reverse('stb:profile'))
else:
return render(request, 'stb/signup.html', {'errors': form.errors}
else:
form = UserCreationForm ()
return render(request, 'stb/signup.html', {'form': form})
I am using a custom user model for my Django project and I can log in via /admin/ perfectly fine. But when I go to /accounts/login and try to log in, it just bounces me back to the login page without logging in. I am using django-registration-redux with the simple backend.
Via logging I discovered that the error happens in this method in django.contrib.auth.__init__.py:
def get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from .models import AnonymousUser
user = None
try:
#
# EXCEPTION THROWN ON BELOW LINE
#
user_id = _get_user_session_key(request)
backend_path = request.session[BACKEND_SESSION_KEY]
except KeyError:
pass
else:
if backend_path in settings.AUTHENTICATION_BACKENDS:
backend = load_backend(backend_path)
user = backend.get_user(user_id)
# Verify the session
if hasattr(user, 'get_session_auth_hash'):
session_hash = request.session.get(HASH_SESSION_KEY)
session_hash_verified = session_hash and constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if not session_hash_verified:
request.session.flush()
user = None
return user or AnonymousUser()
Any ideas? /accounts/register/ performs as expected, although I have overridden RegistrationView. Perhaps I have to do the same thing for logging in?
Login.html
{% extends "base.html" %}
{% load staticfiles %}
{% block body_block %}
<link href="{% static 'css/signin.css' %}" rel="stylesheet">
<div class="container">
<div class="jumbotron">
<h1 class="display-3" align="center">Login</h1>
</div>
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Please sign in</h2>
<label for="inputEmail" class="sr-only">Username</label>
<input type="text" name="email" id="id+username" class="form-control" placeholder="Username" required autofocus>
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" value="Submit">Login</button>
</form>
Not a member?
Register
</div>
<p>
</p>
{% endblock %}
Urls.py
class MyRegistrationView(RegistrationView):
success_url = '/'
form_class = UserProfileRegistrationForm
def get(self, request, *args, **kwargs):
form = self.form_class(initial=self.initial)
return render(request, self.template_name, {'form': form})
def register(self, form):
logging.debug("THIS IS MY REGISTER")
new_user = form.save(commit=False)
new_user.set_password(form.cleaned_data['password1'])
new_user.save()
login(self.request, new_user)
logging.debug("Logged in")
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
logging.debug("After signals")
return new_user
urlpatterns = [
url(r'^', include('base.urls')),
url(r'^admin/', admin.site.urls),
url(r'^accounts/register/$', MyRegistrationView.as_view(), name="registration_register"),
url(r'^accounts/password/change/$', MyRegistrationView.as_view(), name="auth_password_change"),
url(r'^accounts/password/change/done/$', MyRegistrationView.as_view(), name="auth_password_changed"),
url(r'^accounts/', include('registration.backends.simple.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EDIT:
I have a temporary fix of throwing a view into login in urls.py. Something tells me this is extremely dirty but it seems to work... for now. I'm open to better alternatives.
url(r'^accounts/login/$', my_view, name="login"),
def my_view(request):
if request.POST:
username = request.POST['email']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return render(request, 'index.html', {})
# Redirect to a success page.
else:
# Return an 'invalid login' error message.
pass
else:
return render(request, 'registration/login.html', {})
Try using {{ form }} in your login template, instead of rendering the fields manually. This can show whether the problem is in your template or elsewhere.
In this case, I think that the form fields should be username and password, not email and password as you have.
<input type="text" name="username" id="id_username" class="form-control" placeholder="Username" required autofocus>
<input type="password" name="password" id="id_password" class="form-control" placeholder="Password" required>
I try to log a user but I have this error: MultiValueDictKeyError at / "'username'". I followed django documentation: https://docs.djangoproject.com/en/1.7/topics/auth/default/#django.contrib.auth.decorators.login_required
views:
def home(request):
return render_to_response('home.html', {}, context_instance=RequestContext(request))
def login_user(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('start.html')
else:
return HttpResponseRedirect('profile.html')
else:
return HttpResponseRedirect('home.html')
url:
url(r'^$', 'core.views.login_user', name='login_user'),
html:
<form action="/login_user" method="POST" name="auth">
{% csrf_token %}
<label>Email</label>
<input type="text" name="username">
<label>Password</label>
<input type="password" name="password">
<button type="submit">Login</button>
</form>
This question might help you:
Use the MultiValueDict's get method. This is also present on standard dicts and is a way to fetch a value while providing a default if it does not exist.
username = request.POST.get("username", False)
password = request.POST.get("password", False)
I see many errors in your code.
You are pointing your form action to /login_user and in your URL you don't have any /login_user defined so when you enter to root / it will load the login_user function.
I recommend you to do this:
Change your view to something like this:
def login_user(request):
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('home'))
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
usuario = request.POST['username']
clave = request.POST['password']
acceso = auth.authenticate(username=usuario, password=clave)
if acceso is not None:
if acceso.is_active:
login(request, acceso)
return HttpResponseRedirect(reverse('home'))
else:
form = AuthenticationForm()
script = "alert('Usuario no activo');"
return render(request, 'login.html', locals())
else:
form = AuthenticationForm()
script = "alert('Usuario y/o contraseña invalida');"
return render(request, 'login.html', locals())
else:
form = AuthenticationForm()
return render(request, 'login.html', locals())
in your template (login.html)
<form action="{% url "login" %}" method="post" accept-charset="utf-8">
{{ form }}
{% csrf_token %}
<input class="btn btn-default" type="submit" value="Iniciar Sesión" />
</form>
in your urls.py:
url(r'^$', 'core.views.home', name='home'),
url(r'^login/$', 'core.views.login_user', name='login'),
With this a nice form will be shown ;)
I want to redirect a homepage after login in, but the request.user is always anonymous.Where the errors hide?
the code:
urls.py
urlpatterns = patterns('',
url(r'^login/$', login_view),
url(r'^main/$', main_view,name='main'),
)
i have a login form named forms.py
class LoginForm(forms.Form):
username = forms.CharField(required=True,
label='',
max_length=12,
error_messages={'required':'username'},
widget=forms.TextInput(
attrs={'placeholder':'username',
'class':'form-control'}))
password = forms.CharField(required=True,
label='',
max_length=12,
min_length=6,
error_messages={'required':'password'},
widget=forms.PasswordInput(
attrs={'placeholder':'password',
'class':'form-control'}))
def clean(self):
if not self.is_valid():
raise forms.ValidationError('username and password are required')
else:
cleaned_data = super().clean()
the view file:
def login_view(request):
if request.method == 'GET':
form = LoginForm(auto_id=False)
return render_to_response('game/login.html',
RequestContext(request, {'form': form,}))
else:
form = LoginForm(request.POST)
if form.is_valid():
username = request.POST.get('username', '')
password = request.POST.get('password', '')
user = auth.authenticate(username=username,
password=password)
if user is not None and user.is_active:
auth.login(request, user)
return render_to_response('game/main.html',
context_instance=RequestContext(request))
else:
return render_to_response('game/login.html',
RequestContext(request,
{'form': form,'password_is_wrong':True}))
else:
return render_to_response('weapon/login.html',
RequestContext(request, {'form': form,}))
#login_required(login_url='/game/login/')
def main_view(request):
user = request.user
return render_to_response('weapon/main.html',
{'user':user},
context_instance=RequestContext(request))
login.html include:
<form class="form-signin" role="form" action="{% url 'game:main' %}" method="post">
{% csrf_token %}
<h2 class="form-signin-heading">Login in</h2>
{{ form.as_p }}
<label class="checkbox">
<input type="checkbox" value="remember-me"> remember me
</label>
<button class="btn btn-lg btn-primary btn-block" type="submit">Login</button>
</form>
main.html include:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
{% if user.is_authenticated %}
{{ user.username }} Successful
{% else %}
failed
{% endif %}
</body>
</html>
Any suggestions would be much appreciated.
After login you are redirecting the user to game/main.html whereas in my opinion you should redirect user to main_view instead.
The code block in views.py should be:-
EDITED:
if user is not None and user.is_active:
auth.login(request, user)
return HttpResponseRedirect('/game/main')
The form in your login template is pointing to the main view action="{% url 'game:main' %}" not the login view, your form never gets handled.
You should point it to the same login view to handle the authentication, simply use action="." too keep it on the same URL as the login view or point it specifically using the same technique you're using already with main, i.e.
urlpatterns = patterns('',
url(r'^login/$', login_view, name='login'),
url(r'^main/$', main_view, name='main'),
)
And in your template:
action="{% url 'game:login' %}"