Issues with validation - django

I have some issues with validation.When i am submitting the form, the form.is_valid():
always returns false.
After modifying the form i.e. after removing all validations from the form, it still return the false(my form is not submitted)
the code of html
{% extends "base.html" %}
{% block extrahead %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js" type="text/javascript"></script>
<script>
$(function() {
$( "#id_birthday" ).datepicker();
});
</script>
{% endblock %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<div class="register_div">
<p><label for="username">Username:</label></p>
<p>{{ form.username }}</p>
</div>
<div class="register_div">
<p><label for="email">Email:</label></p>
<p>{{ form.email }}</p>
</div>
<div class="register_div">
<p><label for="password">Password:</label></p>
<p>{{ form.password }}</p>
</div>
<div class="register_div">
<p><label for="password1">Verify Password:</label></p>
<p>{{ form.password1 }}</p>
</div>
<div class="register_div">
<p><label for="birthday">Birthday:</label></p>
<p>{{ form.birthday }}</p>
</div>
<div class="register_div">
<p><label for="name">Name:</label></p>
<p>{{ form.username }}</p>
</div>
<p><input type="submit" value="submit" alt="register"/></p>
</form>
{% endblock %}
the code of forms.py
from django import forms
from django.contrib.auth.models import User
from django.forms import ModelForm
from drinker.models import Drinker
class RegistrationForm(ModelForm):
username = forms.CharField(label=(u'User Name'))
email = forms.EmailField(label=(u'Email Address'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
password1 = forms.CharField(label=(u'Verify Password'), widget=forms.PasswordInput(render_value=False))
class Meta:
model=Drinker
exclude=('user',)
def clean_username(self):
username=self.cleaned_data['username']
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("The Username is already taken, please try another.")
def clean_password(self):
password=self.cleaned_data['password']
password1=self.cleaned_data['password1']
if password1 != password:
raise forms.ValidationError("The Password did not match, please try again.")
return password
class LoginForm(forms.Form):
username = forms.CharField(label=(u'User Name'))
password = forms.CharField(label=(u'Password'), widget=forms.PasswordInput(render_value=False))
and the code of views.py
def DrinkerRegistration(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/profile/')
if request.method == 'POST':
form = RegistrationForm(request.POST)
#return render_to_response('register')
if form.is_valid():
user=User.objects.create_user(username=form.cleaned_data['username'], email=form.cleaned_data['email'], password = form.cleaned_data['password'])
user.save()
# drinker=user.get_profile()
# drinker.name=form.cleaned_data['name']
# drinker.birthday=form.cleaned_data['birthday']
# drinker.save()
drinker=Drinker(user=user,name=form.cleaned_data['name'],birthday=form.cleaned_data['birthday'])
drinker.save()
return HttpResponseRedirect('/profile/')
else:
return render_to_response('register.html',{'form':form} , context_instance=RequestContext(request))
else:
''' user is not submitting the form, show them a blank registration form '''
form = RegistrationForm()
context={'form':form}
return render_to_response('register.html',context , context_instance=RequestContext(request))
the model code
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
class Drinker(models.Model):
user =models.OneToOneField(User)
birthday =models.DateField()
name =models.CharField(max_length=100)
def __unicode__(self):
return self.name
#create our user object to attach to our drinker object
def create_drinker_user_callback(sender, instance, **kwargs):
drinker, new=Drinker.objects.get_or_create(user=instance)
post_save.connect(create_drinker_user_callback, User)

I can see two possible reasons:
Your template contains two usages of username: once at the top and once at the bottom. The form might fail because this does not fit into a single CharField.
It's hard to say without your model class, but maybe it contains fields you haven't explicitly excluded?
If it's not option 1, could you post your Drinker model as well?

Did you checked the errors reporting while validating?
use print form.errors and check your console for error messages

If your code changes aren't reflecting in the run environment, look at removing your *.pyc files. These sometimes can get cached.
For linux OS you can run the following from the root of your project;
find . -iname "*.pyc" -exec rm -f {} \;

Related

authenticate() is not validate data properly django

When I try to click on login button it always execute the invalid credentials instead of redirect to the index page.. What I did is that in database create table name signup and wants to validate all the data from that table.. Here signup_data function is works well but in login_data cannot authenticate the user.
Models.py
from django.db import models
class signup(models.Model):
username = models.CharField(max_length=10)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
email = models.EmailField()
password = models.CharField(max_length=10)
Forms.py
from django.forms import ModelForm
from . models import signup
from django import forms
class signupform(ModelForm):
username= forms.CharField(max_length=10,widget=forms.TextInput(attrs={'class':'form-control'}))
first_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'class': 'form-control'}))
email = forms.EmailField(max_length=20,widget=forms.EmailInput(attrs={'class': 'form-control'}))
password = forms.CharField(max_length=10,widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = signup
fields = '__all__'
Views.py
from django.shortcuts import render,redirect
from . forms import signupform
from . models import signup
from django.contrib import messages
from django.contrib.auth import login,authenticate
def index(response):
return render(response,'login_module/index.html')
def signup_data(response):
if response.method == 'POST':
form = signupform(response.POST)
if form.is_valid():
username = form.cleaned_data['username']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
if signup.objects.filter(username=username).exists():
# messages.add_message(response,messages.WARNING,'Username is already taken')
messages.error(response,'Username is already taken')
return redirect('signup')
elif signup.objects.filter(email=email).exists():
messages.error(response,'Email is already taken')
# messages.add_message(response,messages.WARNING,'Email is already taken')
return redirect('signup')
else:
register_instance = signup(username=username, first_name=first_name, last_name=last_name, email=email, password=password)
register_instance.save()
messages.success(response,'Registered Successfull')
return redirect('signup')
else:
form = signupform()
return render(response,'login_module/signup.html',{'form':form, 'message': messages})
def login_data(request):
form = signupform(request.POST or None)
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('index')
else:
messages.error(request,'Invalid Credentials')
return redirect('login')
else:
return render(request,'login_module/login.html',{'form':form, 'message': messages})
Login.html
{% extends 'login_module/base.html' %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt-50">
<h1>Login Page</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 offset-md-4 ">
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group rounded-top">
{{ form.username.label_tag }} {{ form.username }}
</div>
<div class="form-group rounded-top">
{{ form.password.label_tag }} {{ form.password }}
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
</div>
</div>
<div class="text-center mt-50">
{% if messages %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
{% endfor %}
{% endif %}
</div>
</div>
{% endblock %}
Login Page
As far as I can tell you are creating a signup object when signing up, but when trying to login with authenticate django is looking for the generic User model. You have to create a User in the database rather than a signup object to use authenticate.

How to use form_validate() with CustomForm in Django

I'm creating an app in which I'd like to use my own custom login form with a captcha field. My intention is to do this without using an external library (except for requests) but I couldn't add captcha field to my custom form in forms.py, so I added it directly to login.html but for some reason when I do form.is_valid() it returns an error.
I've already seen the solutions in Django - adding google recaptcha v2 to login form and Adding a Recaptcha form to my Django login page but as I said, I'd like to do this without using an external library.
views.py
...
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(request.POST)
result = is_recaptcha_valid(request)
print(result) # prints True
if form.is_valid():
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
# Redirect to index
messages.success(request, "Logged in.")
return HttpResponseRedirect(reverse('orders:index'))
else:
messages.error(request, "Invalid credentials.")
else:
print("error")
return render(request, 'registration/login.html', {'form': CustomLoginForm()})
else:
form = CustomLoginForm()
return render(request, 'registration/login.html', {'form': form})
forms.py
class CustomLoginForm(AuthenticationForm):
email = forms.EmailField(
error_messages={
'required': 'Please enter your email.',
'invalid': 'Enter a valid email address.'
},
help_text='Email',
)
login.html
<form class="" action="{% url 'orders:login' %}" 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 %}
<!-- ReCAPTCHAV3 -->
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey='key-here'></div>
<button class="btn btn-success" type="submit" name="">Login</button>
<!-- <input type="hidden" name="next" value="{{ next }}"> -->
</form>
is_recaptcha_valid() function already returns True so I didn't share that. I'm a beginner in Django, so if you can please explain in two words what I've done wrong instead of just posting the answer, I'd be grateful. Thank you for your time.
The AuthenticationForm is slightly different than the others..
If your check AuthenticationForm class, AuthenticationForm 's first arguments is not data like others form:
class AuthenticationForm(forms.Form):
...
def __init__(self, request=None, *args, **kwargs):
...
Thats why you need to pass request.POST to data.
So update your code like this:
def login_view(request):
if request.method == 'POST':
form = CustomLoginForm(data=request.POST)
...

Validation errors don't show in Django form

When I try to test my form with an email which has already been entered into the database it doesn't give the error message like it should, it redirects back to the homepage.
My views.py file looks like this:
from django.shortcuts import render
from .forms import LotteryForm
from django.http import HttpResponseRedirect
# Create your views here.
def lottery_list(request):
return render(request, 'lottery/lottery.html', {})
def lottery_new(request):
if request.method == 'POST':
form = LotteryForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('lottery_submitted')
else:
return render(request, 'lottery/lottery.html' {'form': LotteryForm()})
else:
form = LotteryForm()
return render(request, 'lottery/lottery.html', {'form': LotteryForm()})
My form is:
from django import forms
from django.db import models
from django.forms import ModelForm
from .models import Lottery
from .models import Lottery_user
from django.core.exceptions import ValidationError
class LotteryForm(forms.ModelForm):
lottery_type = forms.ModelChoiceField(queryset = Lottery.objects.all(), empty_label=None)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
lottery_numbers = forms.CharField(max_length=12, required=True)
email = forms.EmailField(required=True)
telephone = forms.CharField(max_length=18,
error_messages={'invalid':'Enter a valid mobile number',
'required':'Enter a valid mobile number'})
def clean_email(self):
email = self.cleaned_data['email']
if Lottery_user.objects.filter(email=email).exists():
raise ValidationError("Email already exists")
return email
if Lottery_user.objects.filter(email=self.cleaned_data['email']).exists():
raise ValidationError("You've already entered")
return email
class Meta:
model = Lottery_user
fields = ['lottery_numbers', 'lottery_type', 'first_name', 'last_name', 'email', 'telephone',]
Template form:
<form action="{% url 'lottery_new' %}" method="post">
{% csrf_token %}
<div class="fieldWrapper">
<label for="lotterytype">Choose a lottery:</label>
{{ form.lottery_type }}
<p>See <a href=lottery_instructions>instructions and rules</a></p>
</div>
<div class="fieldWrapper">
<label for="lotterynumbers">Lottery Numbers:</label>
{{ form.lottery_numbers }}
</div>
<div class="fieldWrapper">
<label for="firstname">First name:</label>
{{ form.first_name }}
</div>
<div class="fieldWrapper">
<label for="lastname">Last name:</label>
{{ form.last_name }}
</div>
<div class="fieldWrapper">
{{ form.email.errors }}
{{ form.email.non_field_errors }}
<label for="email">Email:</label>
{{ form.email }}
</div>
<div class="fieldWrapper">
<label for="phonenumber">Telephone Number:</label>
{{ form.telephone }}
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
I want a user to not be able to enter twice with the same email, so it should error when the user clicks submit with a used email address.
Also, does anyone know how to get the error messages to show before the user submits rather than afterwards?
You return a newly instantiated form when the form is invalid, when you should instead return the invalid form (with the errors). Try:
def lottery_new(request):
if request.method == 'POST':
form = LotteryForm(request.POST)
if form.is_valid():
....
else:
return render(request, 'lottery/lottery.html' {'form': form})

django registration auth - how to check valid input?

Could you review my code for improvement? Essentially, it works but it isn't user friendly. For example,(1) If the user puts in an invalid field, it doesn't tell them what field is invalid. (2) If a user tries to register (sign up) with an existing username, there is no way the user can distinguishes that error, specifically. Or if a user mis-type password confirm, the user won't know that mistake either. (3) Also, if the user produces an input error(s), the sign up page blanks out all the field and so the user has to re-enter in all the info. As you can imagine, that could be very frustrating for that user.
I tried to see if form.error_messages might help the user, the error_messages is useless.
How would you improve the code so that (1), (2), (3) is not a nuisance for the user? And one more thing, just curious about how you would change the css? I noticed that most professional website sign-up page highlight the input box that was invalid. I am clueless on how to apply changes to css for {{form|as_bootstrap}}
Many thanks for your help!
form.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True,help_text="Email field is required.")
firstname = forms.CharField(max_length=50, required=False, help_text="Optional. Can fill in later.")
lastname = forms.CharField(max_length=50, required=False, help_text="Optional. Can fill in later.")
class Meta:
model = User
fields = (
'username',
'email',
'password1',
'password2',
'firstname',
'lastname'
)
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
user.firstname = self.cleaned_data["firstname"]
user.lastname = self.cleaned_data["lastname"]
if commit:
user.save()
return user
views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/account/register_success')
else:
form = MyRegistrationForm()
args = {}
args.update(csrf(request))
args['form']= form
print form.errors #this line doesn't print anything
return render_to_response('register.html', args)
else:
return HttpResponseRedirect('/')
def register_success(request):
return render_to_response('register_success.html')
register.html
{% extends 'base.html' %}
{% load bootstrap_toolkit %}
{
{% block title %}
<title>Register</title>
{% endblock %}
<body>
{% block content %}
<div class="col-sm-9 col-sm-offset-3 col-md-6 col-md-offset-2 main">
<h2>Register</h2>
{% if form.error_messages %}
<p class="error"> {{ form.error_messages }}.</p>
{% endif %}
<form class="form-signup" role="form" action="/account/register/" method="post"> {% csrf_token %}
{{ form|as_bootstrap }}
<input type="submit" value="Register" class="btn btn-primary"/>
</form>
</div>
{% endblock %}
</body>

Editing users in Django

I was trying to to edit a user using the form that i used to create the user,
I have no idea why i'm getting an error A user with that username already exists.
Here is my view:
def registration_edit(request):
""" Registration Step2:
The user should be authenticated to reach this step.
Authentication is provided by first step or user login.
"""
if request.user.is_authenticated():
if request.POST:
form = RegistrationForm(request.POST or None, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('reg_step_2'))
else:
form = RegistrationForm(instance=request.user)
page = 'account'
title = 'Editing User Registration'
context = {'title': title, 'form': form, 'page': page}
template = 'customer/registration.djhtml'
return render_to_response(template, context, context_instance=RequestContext(request))
else:
messages.info(request, '<strong>Note</strong>: You must logged in to edit your account.')
return HttpResponseRedirect('/')
forms.py I did this form because I want to include firstname and lastname field be included on the registration.
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
class Meta:
model = User
exclude = ('is_staff', 'is_active', 'is_superuser', 'last_login', 'date_joined', 'groups', 'user_permissions', 'password')
and here is my template
<form class="form-horizontal" action='.' method="POST">
{% csrf_token %}
<fieldset>
<div id="legend">
<legend class="">
{{ title|title }}
</legend>
</div>
{% for f in form %}
<div class="control-group">
<label class="control-label" for="username">{{ f.label }}</label>
<div class="controls">
{{ f }} <i style="color: orange">{{ f.errors|striptags }}</i>
</div>
</div>
{% endfor %}
<div class="controls">
<button class="btn btn-success">
Continue
</button>
</div>
</fieldset>
</form>
Anyone tell me where i was messing around here?
Any help would be much appreciated.
Your from inherits from UserCreationForm which cleans the username field.
In this case see UserChangeForm instead.