so I'm making a login page with forms, the problem is it doesn't work :D
this is my form
forms.py
from django.contrib.auth.models import User
from django import forms
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'password',]
my views.py
def user_login(request):
if request.method == 'POST':
login_form = UserForm(request.POST)
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
raw_password = login_form.cleaned_data.get('password')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('restricted')
else:
login_form = UserForm()
return render(request, 'userlogin.html', {'login_form': login_form})
and my html
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ login_form.username }}
<br>
{{ login_form.password }}
<br>
<button type="submit">Login</button>
</form>
the restricted is a html that checks which user is logged in. and it works fine
i'm not sure why it isn't working cuz it keeps redirecting me to the loginuser.html page instead of redirecting me to restricted page which only appears if a user is logged in.
You need to add more details but here is a step by step guide to login users:
forms.py:
from django.contrib.auth import authenticate, get_user_model
User = get_user_model()
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField()
def clean(self, *args, **kwargs):
username = self.cleaned_data.get("username")
password = self.cleaned_data.get("password")
user_obj = User.objects.filter(username=username).first()
if not user_obj:
raise forms.ValidationError("Invalid credentials")
else:
if not user_obj.check_password(password):
raise forms.ValidationError("Invalid credentials")
return super(LoginForm, self).clean(*args, **kwargs)
and in your views.py:
from django.contrib.auth import login
from .forms import LoginForm # or where you have the LoginForm
User = get_user_model()
def user_login(request):
form = LoginForm(request.POST or None)
if not request.user.is_authenticated:
if form.is_valid():
username_ = form.cleaned_data.get('username')
user_obj = User.objects.get(username__iexact=username_)
login(request, user_obj)
return #something
else:
# show an error or etc
...
else:
# user is authenticated before and he is in.
...
and your template.html:
<form action="" method="post">
{% csrf_token %}
<input type="text" name="username">
<hr>
<input type="password" name="password">
<hr>
<button type="submit">Login</button>
</form>
Note:
you can use django to render the form but you need to make some changes on form fields like password (adding PasswordInput widget)
Add block with form errors to your template
<h2>Login</h2>
<form method="post">
<!-- form errors -->
{% if login_form.errors %}
{% for field in login_form %}
{% for error in field.errors %}
<strong>{{ error|escape }}</strong>
{% endfor %}
{% endfor %}
{% for error in login_form.non_field_errors %}
<strong>{{ error|escape }}</strong>
{% endfor %}
{% endif %}
<!-- form errors -->
{% csrf_token %}
{{ login_form.username }}
<br>
{{ login_form.password }}
<br>
<button type="submit">Login</button>
</form>
Related
This is my login view
def login_request(request):
if request.method == 'POST':
username = request.POST.get['username']
password = request.POST.get['password']
user = authenticate(username = username, password = password)
if user is not None:
form = login(request, user)
messages.success(request, f' welcome {username} !!')
return redirect('index')
else:
messages.info(request, f'Unable to Login now')
form = AuthenticationForm()
context = {'form':form}
return render(request, "BizzyCardApp/log-in.html", context)
and this is the log-in.html file
{% extends "BizzyCardApp/base.html" %}
{% block content %}
{% load crispy_forms_tags %}
<br>
<br>
<br>
<br>
<br>
<div class="container center oswald" id="grad" style="border-radius: 10%; width: 300px;">
<br>
<form>
<table class="table table-borderless table-responsive container">
<tbody>
<tr>
<div class="mb-3 mt-3">
<form method="POST">
{% csrf_token %}
{% for field in form %}
<div>
<p>{{ field.label }}: <br> {{ field }}</p>
{% for error in field.errors %}
<small style="color: red">{{ error }}</small>
{% endfor %}
</div>
{% endfor %}
</form>
</div>
</tr>
<tr>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-light center text-center">Submit</button>
</div>
</tr>
</tbody>
</table>
</form>
<div class="text-center">
<a href="/sign-up/" class="link-dark">
Don't have an account? Sign Up
</a>
</div>
</div>
{% endblock %}
Once I hit the Submit button, it's supposed to redirect me to the index page but all that happens is that the GET request is done but there is no response from the backend to redirect. It just stays on the same page and the URL changes to
http://127.0.0.1:8000/login/?csrfmiddlewaretoken=0rkrC5wOe8LDQc9x0s0Zdag45PXRZixJAYaQns3dod58QhUL6OdmTEvZMYdRNTfq&username=tushar&password=abcd123*
Try this login view:
def login_request(request):
if request.method == 'GET':
if request.user.is_authenticated:
return redirect('/index/')
if request.method=='GET':
form = loginForm(request.POST)
if form.is_valid():
user=authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password'])
if user:
print('user',user)
login(request,user)
return redirect('/index/')
else:
print('Not authenticated')
elif request.method=='GET':
if request.user.is_authenticated:
return redirect('/index/')
form=loginForm()
return render(request,'users/login.html',{'form':form})
In forms.py:
Add this:
class CustomAuthenticationForm(AuthenticationForm):
def confirm_login_allowed(self, user):
if not user.is_active or not user.is_validated:
raise forms.ValidationError('There was a problem with your login.', code='invalid_login')
And in login view, change AuthenticationForm to CustomAuthenticationForm. And import it in login view using below code.
from .form import CustomAuthenticationForm
Finally figured out the answer. The method for the tag wasn't given as POST.
The tag was just and not
The backend kept on getting GET requests instead and that's why the code wasn't working.
This is the Login method code I'm using now
def 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:
form = auth_login(request, user)
messages.success(request, f' welcome {username} !!')
return redirect('/')
else:
messages.info(request, f'account done not exit plz sign in')
form = AuthenticationForm()
return render(request,'BizzyCardApp/log-in.html',{'form':form})
I tried to create a login form. But when I try to login django gives the error that Account with this Email already exists. i don`t now how to fix this.Help me plz
Here is my code, please tell me where I'm going wrong:
forms.py
class AccountAuthenticationForm(forms.ModelForm):
password = forms.CharField(label='Password', widget=forms.PasswordInput)
class Meta:
model= Account
fields = ('email', 'password')
def clen(self):
email = self.cleaned_data['email']
password = self.cleaned_data['password']
if not authenticate(email=email, password=password):
raise forms.ValidationError("Invalid login")
views.py
def login_view(request):
context = {}
user = request.user
if user.is_authenticated:
return redirect("home")
if request.POST:
form = AccountAuthenticationForm(request.POST)
if form.is_valid():
email=request.POST['email']
password = request.POST['password']
user =authenticate(email=email, password=password)
if user:
login(request,user)
return redirect("home")
else:
form = AccountAuthenticationForm()
context['login_form'] = form
return render(request, 'account/login.html', context)
login.html
{% extends 'base.html' %}
{% block content %}
<h2>Login</h2>
<form method="post">{% csrf_token %}
{% for field in login_form %}
<p>
{{field.label_tag}}
{{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 %}
{% if login_form.non_field_errors %}
<div style="color:red";>
<p>{{login_form.non_field_errors}}</p>
</div>
{% endif %}
</p>
{% endfor %}
<button type="submit">Log in</button>
</form>
{% endblock content %}
I'm just getting started with Django. I will be glad if you point out my mistake
solved
i just added email field to the class AccountAuthentcationForm in forms.py
and changed from forms.ModelForm to forms.Form
I went to test the user sign up but it keeps telling me UNIQUE constraint failed: users_customuser.email. That's because the email isn't saving with the rest of the form. I checked the database with an inspector and it shows a blank email field. I put a debug print before form.save and it showed the username email and password so I know the email is in the form data. The view looks fine so it doesn't make sense to me. Tried switching to django 2.2 and it didn't help. The form is valid but the email doesn't save.
views.py
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = SignUpForm()
return render(request, 'user_accounts/signup.html', {'form': form})
forms.py
class SignUpForm(UserCreationForm):
email = forms.EmailField(max_length=254, help_text='Enter a valid email address')
class Meta:
model = CustomUser
fields = ('username', 'password1', 'password2')
signup.html
{% block content %}
<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>
{% endblock %}
I changed the forms.py to the following
forms.py
class SignUpForm(UserCreationForm):
# Deleted extra email field
class Meta:
model = CustomUser
fields = ('email', 'username', 'password1', 'password2') # <-- Added 'email'
Below is code in views.py file.
class login(View):
def get(self, request):
return render(request, 'login.html')
def post(self, request):
form = LoginForm(request.POST)
if form.is_valid():
username = request.POST.get('username')
password = request.POST.get('password')
return HttpResponse("ok")
else:
form = LoginForm()
return HttpResponse(form)
Below code is in template file.
<form method="post" action="{% url 'authapp:login' %}">
{% csrf_token %}
<input type="text" name="username" class="form-control">
<input type="password" name="password" class="form-control">
<button type="submit" class="btn btn-primary">
Login
</button>
</form>
below code is in forms.py file
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length = 50, required = True),
password = forms.CharField(max_length = 50, required = True)
Issue Details
When i submit the form with both username and password empty, it returns just a textfield of password.
I was expecting a list of errors for required username and password. As both are required in forms file.
Can you please suggest something?
change your views.py so it actually return the forms to the template:
class login(View):
if request.method == 'GET':
form = LoginForm()
return render(request, 'login.html', {'form': form})
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
# some validation stuffs
return HttpResponse("ok")
else:
return render(request, 'login.html', {'form': form})
Your forms.py so it actually use to render:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(label="username", max_length=50, required=True, widget=forms.TextInput(attrs={'class' : 'form-control'}))
password = forms.CharField(label="password", max_length=50, required=True, widget=forms.PasswordInput(attrs={'class': 'form-control'}))
And your template:
<form method="post" action="{% url 'authapp:login' %}">
{% csrf_token %}
{{ form.username }}
{% if form.username.errors %}
{% for error in form.username.errors %}
{{ error }}
{% endfor %}
{% endif %}
{{ form.password }}
{% if form.password.errors %}
{% for error in form.password.errors %}
{{ error }}
{% endfor %}
{% endif %}
<button type="submit" class="btn btn-primary">
Login
</button>
</form>
I think you should finish reading the form docs before you doing this since last question you didn't know that you have to add forms.py in your project
You need to enable the debug true in settings.py file
DEBUG = True
I'm trying to add a signup function to my website, this is what I have done so far...
added {% csrf_token %} in home.html
use render instead of rendor_to_response
added the middleware 'django.middleware.csrf.CsrfViewMiddleware'
home.html:
<div class="panel right">
<p>
<form action="/signup" method="post">
{% csrf_token %}
{% for field in user_form %}
{{ field }}
{% endfor %}
<input type="submit" value="Create Account">
</form>
</p>
</div>
Signup method in views.py
def signup(request):
user_form = UserCreateForm(data=request.POST)
if request.method == 'POST':
if user_form.is_valid():
username = user_form.clean_username()
password = user_form.clean_password2()
user_form.save()
user = authenticate(username=username, password=password)
login(request, user)
return render(request,'blog.html')
else:
return render(request,'index.html')
return redirect('/')
What's wrong with my code?