I've been working on Django Authentication, but I have stumbled on a problem: login works on a page (the "post detail" page of the blog), but not on the homepage.
This is the part of the base.html that handles this header
{% if user.is_authenticated %}
<span class="glyphicon glyphicon-plus"></span>
<span class="glyphicon glyphicon-edit"></span>
<p class="top-menu">Hello, {{ user.first_name }}!<small> (Log out)</small></p>
{% else %}
<form>
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}" />
{% endif %}
{{ login_form.as_p }}
</form>
{% endif %}
The view seems good to me, anyway here it is
def login(request):
if request.method == 'POST':
login_form = CustomLoginForm(request.POST)
email = request.POST.get('email')
password = request.POST.get('password1')
user = authenticate(email=email, password=password)
if user is not None:
if user.is_active:
auth_login(request, user)
return HttpResponseRedirect('/')
else:
return HttpResponse("Your Blog account is disabled.")
else:
print "Invalid login details: {0}, {1}".format(email, password)
return HttpResponse("Invalid login details supplied. Get back to the homepage.")
else:
login_form = CustomLoginForm()
return render(request, 'blog/post_list.html', {})
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('-published_date')
user = CustomUser.objects.all()
user_form = CustomUserCreationForm()
login_form = CustomLoginForm()
return render(request, 'blog/post_list.html', {'posts': posts, 'user_form': user_form, 'login_form': login_form, 'user': user})
I think the core of the problem could be on either the header of the base.html file or on the view.
This is what I see on the homepage (even when I'm logged in)
This is what I see on the post-detail page (and that's what I should see on the homepage too)
Any thoughts?
Your problem is here:
user = CustomUser.objects.all()
and then
return render(request, 'blog/post_list.html',
{'posts': posts, 'user_form': user_form,
'login_form': login_form, 'user': user})
You are passing a queryset result consisting of CustomUser objects as user in your request context. It overwrites the user variable assigned by the django.contrib.auth.context_processors.auth context processor.
To solve the problem, simply change the name of the template variable to something else, such as:
return render(...
'users': user})
Related
I am unable to login and redirect to home page using the custom login view (user_login) and AuthenticationForm. However, if i login using the admin page (http://127.0.0.1:8000/admin) and then reopen login page it automaticaly redirects to home page.
There is some issue related to authentication which is not getting done from my custom login page/view .I am unable to fix this or identify resolution based on answers provided online.
There is another issue regarding the URL it is showing as
http://127.0.0.1:8000/login/?csrfmiddlewaretoken=FhHQjhGGgFDwcikpH9kl3OwQMcZisjWS2zvMHFGBU6KxGNWbamgago7FhtSs8MeN&username=admin&password=admin
However, Password and Username should not be showing in the URL if form method is post.
URL
urlpatterns = [
path("", views.index, name="index"),
path("signup/", views.user_signup, name="signup"),
path("login/", views.user_login, name="login"),
path("home/", views.homepage, name="home"),]
Views
def user_login(request):
if request.user.is_authenticated:
return redirect("/home")
else:
if request.method == "POST":
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect("home")
else:
messages.error(request, "Invalid username or password.")
else:
messages.error(request, "Invalid username or password.")
form = AuthenticationForm()
return render(
request=request,
template_name="socialapp/login.html",
context={"login_form": form},
)
def homepage(request):
return render(request=request, template_name="socialapp/home.html")
Login HTML
<form action="{% url 'login' %}" id="login-form" method="post" class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4">
{% csrf_token %}
{{ login_form|crispy }}
<button type="submit" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800" value="Submit">Login</button>
</form>
Home HTML
{% block main %}
<div class="flex flex-col min-h-screen justify-center items-center ">
<h1>Welcome to Home</h1>
</div>
{% endblock main %}
Settings
LOGIN_URL = "/login"
LOGIN_REDIRECT_URL = "/home"
You need to check login in else part
def SigninView(request):
if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
username = request.POST.get("username")
password = request.POST.get("password")
user = authenticate(username=username,password=password)
if user is None:
messages.error(request,'Please Enter Correct Credinatial')
return redirect('/signin/')
else:
login(request,user)
messages.info(request,'Login Successful')
return redirect('/dashboard/')
else:
if request.user.is_authenticated:
return redirect('/dashboard/')
else:
form = AuthenticationForm()
return render(request,'signin.html',{'form':form})
This has been asked many times before and I have read all of those answers, but none of them worked for me so I'd like to try again.
When I try to submit a Django form with username and password, I get this error message:
'CSRF token missing or incorrect'.
The CSRF token is not missing.
Here is where I included it in my form in my .html template:
In index.html:
<form name="loginform" action="/notes/index/" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit"/>
{% for field, errors in form.errors.items %}
{{ errors }}
{% endfor %}
</form>
In views.py:
class LoginForm(forms.Form):
username = forms.EmailField()
password = forms.CharField(widget=forms.PasswordInput())
def index(request):
if request.method == 'POST':
print("Received POST")
form = LoginForm(request.POST)
if form.is_valid():
print("FORM is Valid")
else:
print("FORM is NOT VALID")
template = loader.get_template('index.html')
context = {
'username': 'Benny',
'form': LoginForm(),
}
return HttpResponse(template.render(context))
I also have csrf middleware in settings. I am trying to avoid using #csrf_exempt as this app will go into production down the line.
I got it to work but not sure why this fixes it. Can anyone clarify?
I changed:
return HttpResponse(template.render(context))
to:
return HttpResponse(template.render(context, request=request))
I thought the request was automatically carried out by render()? So I'm not sure why I had to add request=request.
I have a view to log in and when the user does not exist it throws me an error, I would like this error to be printed in the template, saying that the user does not exist, try this way but it does not work for me. Would there be any other way to make it work?
View
def login_rfid(request):
'''
Login
'''
if request.method == 'POST':
username = ''
if 'username' in request.POST:
print("sasrfwrfsrsf")
rfid = request.POST['username']
user = User.objects.get(rfid=rfid)
if user is not None:
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
return redirect('/')
else:
messages.error(request, 'The user does not exist')
return render(request, "registration/login_rfid.html")
HTML
{% if messages %}
<div class="span12">
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message|safe }}
</div>
{% endfor %}
</div>
{% endif %}
ERROR
Ok i didnt understand why u wrote username=''
in beggining of the function but heres the code which will work for u
def login2(request):
# Check if the user is already logged in or not
if request.user.is_authenticated:
return redirect("/service-page.html")
if request.method == "POST":
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(username=username,password=password)
if user is not None:
login(request, user)
return redirect("/service-page.html")
else:
messages.error(request,"Invaild Credentials, Please try again")
return render(request,"login.html")
else:
return HttpResponse("Only POST Methods are allowed baby")
return HttpResponse("Wrong password")
The view ats.views.index didn't return an HttpResponse object. It returned None instead.
I am trying to implement an authentication system, if I enter the password correctly I don't bump into any problems but when I enter it incorrectly I get this error. Does anyone know how I could solve this?
This is my view
def index(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return render(request, "homepage.html", context_instance=RequestContext(request))
else:
form = AuthenticationForm()
return render(request, "index.html", {'form': form})
This is my html
{% block content %}
<form class="box" method = "post">
{% csrf_token %}
<h1>Ats</h1>
{{ form }}
<input type="submit" name="" value="Login">
</form>
{% endblock %}
The request can be a POST request, but where the form.is_valid() does not hold. In that case, your view, will return None.
You should "unindent" the return render(..) part:
from django.shortcuts import redirect
def index(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return redirect('some-view-name')
else:
form = AuthenticationForm()
return render(request, 'index.html', {'form': form})
Note that here your view does not performs authentication. You should first check if the password (or some other token) matches. See the documentation on authenticate(..) [Django-doc] for more information.
In case of a successful POST request, you should make a redirect to implement the Post/Redirect/Get pattern [wiki].
Rearranging the code should work
def index(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return render(request, "homepage.html", context_instance=RequestContext(request))
return render(request, "index.html", {'form': form})
You are getting this problem because you haven't written a HttpResponse object if the form is not valid.
To overcome this in your view write return an HTTP response if the form is not valid.
def index(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return render(request, "homepage.html", context_instance=RequestContext(request))
else:
return render(request, "index.html", {'form': form, 'errors': form.errors})
else:
form = AuthenticationForm()
return render(request, "index.html", {'form': form})
in index.html
{% block content %}
{% if errors %}
{{ errors }}
{% endif %}
<form class="box" method = "post">
{% csrf_token %}
<h1>Ats</h1>
{{ form }}
<input type="submit" name="" value="Login">
</form>
{% endblock %}
or you can simply handle conditions and return default request if the request is not a post request.
def index(request):
form = AuthenticationForm()
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return render(request, "homepage.html", context_instance=RequestContext(request))
return render(request, "index.html", {'form': form})
You need to define the else condition if form is not valid.
def index(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
user = form.get_user()
login(request, user)
return render(request, "homepage.html", context_instance=RequestContext(request))
else:
return render(request, "index.html", {'form': form, 'errors': form.errors})
else:
form = AuthenticationForm()
return render(request, "index.html", {'form': form})
In your template you can show form errors by accessing this context variable {{ errors }}.
{% block content %}
{% if errors %}
{{ errors }}
{% endif %}
<form class="box" method = "post">
{% csrf_token %}
<h1>Ats</h1>
{{ form }}
<input type="submit" name="" value="Login">
</form>
{% endblock %}
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 ;)