Django allauth render login fields manually user or email not displayed - django

I'm trying to display the login fields manually, instead of using:
{{form.as_p}}
I'm setting allauth as follows in order to login with email:
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = False
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_UNIQUE_EMAIL = True
In HTML I have the following:
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
<!-- Email input -->
<div class="form-outline mb-4">
{{form.email}}
<label class="form-label" for="form2Example1">Email address</label>
</div>
<!-- Password input -->
<div class="form-outline mb-4">
{{form.password}}
<label class="form-label" for="form2Example2">Password</label>
</div>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
<button class="btn btn-lg btn-block btn-primary" type="submit">{% trans "Sign In" %}</button>
</form>
The email field is not being displayed, I have also tried with:
{{form.user}}
and the field is not displayed

Related

display multiple django messages in one page?

I have a template in which user can change his details like name, email and password. I am getting wrong messages after updating info ( if I change the password then I got message "Invalid" that is part of edit_profile) though I used extra_tags for message to identify two different messages,
But still having issue. I tried searching a lot, and found some relevant questions but was not helpful.
views.py
def edit_profile(request):
if request.user.is_authenticated:
if request.method == 'POST':
form = EditProfileForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
messages.success(request, "Update successful!", extra_tags='edit_profile')
return redirect("accounts:edit_profile")
else:
messages.error(request, "Invalid", extra_tags='edit_profile')
return redirect("accounts:edit_profile")
else:
form = EditProfileForm(instance=request.user)
return render(request, "accounts/edit_profile.html", {'form': form})
else:
redirect('accounts:signin')
def change_password(request):
if request.method == 'POST':
form = PasswordChangeForm(data=request.POST, user=request.user)
if form.is_valid():
form.save()
messages.success(request, "Update successful!", extra_tags='change_password')
update_session_auth_hash(request, form.user)
return redirect("accounts:change_password")
else:
messages.error(request, "Password Error", extra_tags='change_password')
return redirect("accounts:change_password")
else:
form = PasswordChangeForm(user=request.user)
return render(request, "accounts/edit_profile.html", {'form': form})
template
<h2 class="font-weight-bolder">Account Details</h2>
<!-- edit_profile form -->
<form action="{% url 'accounts:edit_profile' %}" method="post" class="row g-3 needs-validation"
novalidate>
{% csrf_token %}
<!-- 1 Username -->
<div class="offset-md-2 col-md-4 ">
<label for="username" class="form-label">Username</label><br>
<input type="text" name="username" class="form-control" id="username"
value="{{ form.username.value }}" required>
<div class="invalid-feedback">
Please provide name.
</div>
</div>
<!-- 2 Email -->
<div class="offset-md-1 col-md-4">
<label for="email" class="form-label">Email</label>
<input type="email" name="email" class="form-control" id="email"
value="{{ form.email.value }}" required>
<div class="invalid-feedback">
Please provide a valid email.
</div>
</div>
{% for message in messages %}
{% if 'edit_profile' in message.tags %}
<div class="offset-md-2 col-md-6 pt-2">
<h4 class="text-success font-weight-bolder">{{ message }}</h4>
</div>
{% endif %}
{% endfor %}
<div class="offset-md-2 col-md-4 pt-2 pb-2">
<input type="submit" value="Save" class="btn btn-outline-primary btn-lg">
</div>
</form>
<!-- Password section -->
<div class="offset-md-2 pt-3 pb-2">
<h4 class="font-weight-bold">Password</h4>
</div>
<form action="{% url 'accounts:change_password' %}" method="post" class="row g-3 needs-validation"
novalidate>
{% csrf_token %}
<div class="offset-md-2 col-md-3">
<label for="old_password" class="form-label">Current password</label>
<input type="password" name="old_password" value="" class="form-control" id="old_password" required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
<div class="col-md-3">
<label for="new_password1" class="form-label">New password</label>
<input type="password" name="new_password1" value="" class="form-control" id="new_password1"
required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
<div class="col-md-3">
<label for="new_password2" class="form-label">Confirm password</label>
<input type="password" name="new_password2" value="" class="form-control" id="new_password2"
required>
<div class="invalid-feedback">
Please provide a valid password.
</div>
</div>
{% for message in messages %}
{% if "change_password" in message %}
<div class="offset-md-2 col-md-6 pt-2">
<h4 class="text-success font-weight-bolder">{{ message }}</h4>
</div>
{% endif %}
{% endfor %}
<div class="offset-md-2 col-md-4 pt-2">
<input type="submit" value="Change Password" class="btn btn-outline-primary btn-lg">
</div>
</form>

Django: Trouble with logging user using Bootstrap login.html

I'm using Django 3.0.2 + Boostrap. I have created a registration/login.html page. The contents of this page are shown below.
The page renders correctly and most of it works OK. However, I am unable to login to my website through this page. I keep getting Your username and password did not match. Please try again. I can login to the admin website without any issues if I use the same username/password. I am not sure what is wrong with my login.html. Any ideas?
{% extends "base.html" %}
{% block content %}
{% if form.errors %}
<p>Your username and password did not match. Please try again.</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account does nohave access to this page. To proceed,please login with an account that has access.</p>
{% else %}
<p>Please login to see this page.</p>
{% endif %}
{% endif %}
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="p-5">
<div class="text-center">
<h1 class="h4 text-gray-900 mb-4">Welcome Back!</h1>
</div>
<form class="user" method="post" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control form-control-user" id="exampleInputUserName" placeholder="Username">
</div>
<div class="form-group">
<input type="password" class="form-control form-control-user" id="exampleInputPassword" placeholder="Password">
</div>
<input type="submit" class="btn btn-primary btn-user btn-block" value="Login">
<input type="hidden" name="next" value="{{ next }}">
</form>
<hr>
<div class="text-center">
<a class="small" href="forgot-password.html">Forgot Password?</a>
</div>
<div class="text-center">
<a class="small" href="register.html">Create an Account!</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Contents of views.py:
from django.contrib.auth import logout
def logout_view(request):
"""Log out user from the website."""
logout(request)
Your input types are missing the name attribute. As per the Mozilla docs:
A string specifying a name for the input control. This name is
submitted along with the control's value when the form data is
submitted.
So the name is submitted with the form. But what if there is no name attribute?
Same Documentation explains:
Consider the name a required attribute (even though it's not). If an
input has no name specified, or name is empty, the input's value is
not submitted with the form.
So your username and password are not sent to the backend.
You need to provide the name attributes to your input types.
<form class="user" method="post" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control form-control-user" id="exampleInputUserName" placeholder="Username" `name="username"`>
</div>
<div class="form-group">
<input type="password" class="form-control form-control-user" id="exampleInputPassword" placeholder="Password" name="password">
</div>
<input type="submit" class="btn btn-primary btn-user btn-block" value="Login">
<input type="hidden" name="next" value="{{ next }}">
</form>
It is front-end issue, not particularly related to Django.

Django: Redirect Change Password URL

I have the following two URLs:
url(r'^change-password/$',django.contrib.auth.views.password_change,{'template_name': 'meta/changepassword.html', 'post_change_redirect': '/password-changed/'},name='change_password'),
url(r'^change-passwordiOS/$',django.contrib.auth.views.password_change,{'template_name': 'meta/changepassword.html', 'post_change_redirect': '/password-changed/'},name='change_passwordiOS'),
I thought if I used the following within the change password form it would override what URL would be loaded:
{% if 'iOS' in request.path %}
<input type="hidden" name="next" value="/profileiOS/" />
{% endif %}
But when I reach the change password from the url(r'^change-passwordiOS/$' and click the "Change Button" it does not goto the /profileiOS/ as expected but the standard /profile/ URL.
Any help would be appreciated.
/change-password/ view:
#login_required
def password_changed(request):
messages.success(request, 'Your password has been changed.')
return redirect(reverse('profile'))
Full Change Password Form:
<form class="form-horizontal" role="form" method="post" action="">
{% csrf_token %}
<fieldset>
<div class="form-group">
<label class="col-md-6 control-label">{{ form.old_password.label }}:</label>
<div class="col-md-6">
<input name="old_password" type="password" class="form-control"/>
<div class="text-danger">
{% for error in form.old_password.errors %}{{ error }}<br/>{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-6 control-label">{{ form.new_password1.label }}:</label>
<div class="col-md-6">
<input name="new_password1" type="password" class="form-control"/>
<div class="text-danger">
{% for error in form.new_password1.errors %}{{ error }}<br/>{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-6 control-label">{{ form.new_password2.label }}:</label>
<div class="col-md-6">
<input name="new_password2" type="password" class="form-control"/>
<div class="text-danger">
{% for error in form.new_password2.errors %}{{ error }}<br/>{% endfor %}
</div>
</div>
</div>
<div class="form-group">
<div class="text-right col-sm-12">
<button type="submit" class="btn btn-primary">Change Password^</button>
</div>
</div>
</fieldset>
{% if 'iOS' in request.path %}
<input type="hidden" name="next" value="/profileiOS/" />
{% endif %}
</form>
You are manually redirecting to /profile/ in password_changed view. You can change your redirect logic to depend on post param from template:
#login_required
def password_changed(request):
messages.success(request, 'Your password has been changed.')
return redirect(request.POST.get('next', reverse('profile')))

django allauth: redirecting for invalid passwords

I have a custom page which calls allauth signup view (custom_passcheck.html)
<form action="{% url 'account_signup' %}" method="post" class="form">
{% csrf_token %}
<BR>
<BR>
<BR>
<center>
<div class=signuponepage>
<div class=sign-up>
<div class=signup-box>
<div class="form-element email-address">
<label id="email-address-label">
<strong>
Create a password (it must be 6 characters long)
</strong>
<input type="hidden" name="username" value="{{ pemail }}">
<input type="hidden" name="email" value="{{ email }}">
<input type="text" maxlength="19" name="password1" value="" placeholder="Password">
<input type="text" maxlength="19" name="password2" value="" placeholder="Password (again)">
</label>
</div>
<div class="form-element nextstep-button">
{% buttons %}
<button type="submit" class="btn btn-primary btn-sm">
Finish {% bootstrap_icon "chevron-right" %}
</button>
{% endbuttons %}
</div>
</div>
</div>
</div>
</center>
</form>
Now, if a user puts in password less than 6 chars, it will raise an error and redirect the user to allauth signup page (/account/signup)
Question: instead of redirecting to (/account/signup), how can i redirect to the custom page (custom_passcheck.html) while preserving POST data

Django next redirect with default view

I'm trying to enter the page while I'm not logged in and app redirect me to login page and getting the next parameter is working (ex.
localhost:8000/login/?next=/blog/add/
but when I enter login and password and click login button it redirect me to home page, not that one that is in the next parameter
localhost:8000, not localhost:8000/blog/add/
I'm using default django login view so it is possible to do this without changing anything in login view?
Everything is default by django, I added only next parameter while redirecting to login page (with using #login_required(login_url='login')), I heard that Django has built in feature for redirecting after login with next parameter and nothing more is required?
urls.py
url(r'^login/$',
django.contrib.auth.views.login,
{
'template_name': 'user/login.html',
'authentication_form': user.forms.BootstrapAuthenticationForm,
'extra_context':
{
'title': 'Logowanie',
'year': datetime.now().year,
}
},
name='login'),
login.html
<form action="" method="post" class="form-horizontal">
{% csrf_token %}
<h4>Uzyj konta LDAP zeby sie zalogowac</h4>
<hr />
<div class="form-group">
<div class="col-md-10">
{{ form.username }}
</div>
</div>
<div class="form-group">
<div class="col-md-10">
{{ form.password }}
</div>
</div>
<div class="form-group">
<div class="col-md-10">
<input type="hidden" name="next" value="/" />
<input type="submit" value="Zaloguj" class="btn btn-primary btn-block btn-pb" />
</div>
</div>
{% if form.errors %}
<p class="validation-summary-errors">Please enter a correct user name and password.</p>
{% endif %}
</form>
The problem is that you have hardcoded the next variable as / in your template:
<input type="hidden" name="next" value="/" />
You should change it to use {{ next }}:
<input type="hidden" name="next" value="{{ next }}" />