'loginForm' object has no attribute 'is_valid' can anyone have solution why i'm getting this
i just trey to get data and the form it shows error on this line is_valid() in django
>login.py
<form action ='' method ='POST' >
{% csrf_token %}
<div class="form-group">
<label for="formGroupExampleInput">User Name</label>
<input type="text" id='username' name = 'username' class="form-control" id="formGroupExampleInput" placeholder="">
</div>
<label for="inputPassword5">Password</label>
<input type="password" name ='password' id="password" class="form-control" aria-describedby="passwordHelpBlock">
<input class="btn btn-primary my-3" type="submit" value="Submit">
</form>
</div>
> views.py
def login(request):
if not request.user.is_authenticated:
if request.method == 'POST':
form = loginForm(request.POST)
if form.is_valid():
username = models.cleaned_data['username']
password = models.cleaned_data['password']
user = authenticate(username=username , password=password)
if user is not None:
login(request , user)
messages.success(request,'logged in Successfully !!')
return HttpResponseRedirect('dashbord')
else:
form = loginForm()
else:
return HttpResponseRedirect('dashbord')
return render(request,'login.html',{'form':form})
def logout(request):
return HttpResponseRedirect('/')
> models.py
class loginForm(models.Model):
username = models.CharField(max_length=50)
password = models.EmailField(max_length=200 )
Your loginForm is not a form. It is a model, and models do not have a .is_valid() method. Models are not used to process, validate and clean data, but to store data. It thus does not make much sense to use a model here.
You should define a form
# app_name/forms.py
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=50)
password = forms.CharField(max_length=200)
In your view, you can then make use of that form:
# app_name/views.py
from app_name.forms import LoginForm
from django.shortcuts import redirect
def login(request):
if not request.user.is_authenticated:
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = models.cleaned_data['username']
password = models.cleaned_data['password']
user = authenticate(username=username , password=password)
if user is not None:
login(request , user)
messages.success(request,'logged in Successfully !!')
return redirect('dashbord')
else:
form = LoginForm()
else:
return HttpResponseRedirect('dashbord')
else:
form = LoginForm()
return render(request,'login.html',{'form':form})
im doing this project which requires me to submit some forms and then return the value. However when i press the submit button the form disappear like as if the page got refreshed. Can any one help me? the code is in HTML
<div id="b2" class="containerTab" style="display:none;background:white">
<span onclick="this.parentElement.style.display='none'" class="closebtn">x</span>
<form method="POST">
<span style="float: left"><b>BTC amt >=: </b></span><center><b> Depth: <input type="range" name="rangeInput" min="0" max="20" onchange="updateTextInput2(this.value);"><input style="font-size:15px;" type="text" id="textInput2" value=""></b></center>
<input style="font-size:15px;" type="text" name=BTC amt><br>
<b>And <= :</b><br>
<input style="font-size:15px;" type="text" name="mdA">
<input style="font-size:20px;" name="BTCamt" type="submit" value="Submit"><br><br><br><br>
</form>
<div>
{{outBTC}}
</div>
</div>
This is the function im trying to run in this HTML
from flask import Flask, render_template, url_for, request
app = Flask(name)
#app.route("/")
def home():
return render_template('home.html')
#app.route("/", methods=['POST'])
def index():
# if form.validate_on_submit():
if 'transactionid' in request.form:
transactionaddr = request.form['transactionid']
newresult = runCypher(transactionaddr)
return render_template('home.html', outputresult=newresult)
elif 'BTCamt' in request.form:
transactionaddr = request.form['BTCamt']
newresult = runCypher(transactionaddr)
return render_template('home.html', outBTC=newresult)
def runCypher(transactionaddr):
from neo4j import GraphDatabase
uri = "bolt://localhost:7687"
user = "neo4j"
password = "123"
graphdb = GraphDatabase.driver(uri, auth=(user, password))
session = graphdb.session()
q1 = 'MATCH g=(n:out {addr: "'+transactionaddr+'"})-[*..3]-(m) RETURN g'
nodes = session.run(q1)
out = ""
for node in nodes:
out += str(node)
return out
if __name__ == '__main__':
app.run(debug=True)
The / route was declared twice. This should point you in the right direction..
#app.route("/", methods=['GET','POST'])
def index():
# if form.validate_on_submit():
if request.method == 'POST':
if 'transactionid' in request.form:
transactionaddr = request.form['transactionid']
newresult = runCypher(transactionaddr)
return render_template('home.html', outputresult=newresult)
elif 'BTCamt' in request.form:
transactionaddr = request.form['BTCamt']
newresult = runCypher(transactionaddr)
return render_template('home.html', outBTC=newresult)
return render_template('home.html')
I'm working on a project using Python(2.7) and Django(1.10) in which I need submit the login form but it returns an error on submission.
Note: I have searched a lot of questions tried various answers but in
most cases the {% csrf_token %} is missing from the <form> HTML
but in my case, I'm using this also, that's why don't mark this
question duplicated, please!
Here's what I have tried:
from form.html:
<form class="fields-signup" action="{% url 'mainlogin' %}" method="post">
{% csrf_token %}
<h1 class="text-center">Sign In</h1>
<div class="form-group">
<input class="user-name form-control" type="text" name="username" placeholder="User name">
</div>
<div class="form-group">
<input class="password form-control" type="password" placeholder="Password" name="password">
</div>
<input type="submit" class="btn siteBtn" value="Sign In">
<!-- <a href="#" class="btn siteBtn" >Sign Up</a>
<p class="text-center">Don’t Have an account? Signup</p> -->
<!--popup-forget-password-->
<div class="col-sm-12">
<button type='button' class="forget-password-btn" data-toggle="modal" data-target="#popUpWindow">Forgot Password</button>
<!--forget-password-end-->
<div class="col-sm-12 register">
<a class="register-driver-btn" data-toggle="modal" data-target="#popUpWindow_register">Register Driver?</a>
</div>
</div>
</form>
from urls.py:
url(r'^$', views.home, name="home"),
from views.py:
if request.method == "GET":
try:
temp = get_template('login.html')
result = temp.render(Context({'context': RequestContext(request)}))
return HttpResponse(result)
more from views.py:
if request.method == "POST":
username = request.POST['username']
# email = request.POST['email']
password = request.POST['password']
try:
#obj = User_table.objects.get(user_name=username, emailid=email)
obj = User_table.objects.get(user_name=username)
if obj:
print('got user obj')
verify_password = ''
try:
verify_password = handler.verify(password, obj.password)
except Exception as e:
print(e)
if verify_password is True:
request.session['user_id'] = obj.id
request.session['user_type'] = obj.user_type
user_name = obj.first_name + ' ' + obj.last_name
request.session['user_name'] = user_name
if not obj.approval_status:
return HttpResponse('Your account is not confirmed by administration.')
obj.is_active = True
obj.login_try = 0
obj.save()
return redirect(home)
else:
try:
# obj = User_table.objects.get(user_name=username, emailid=email)
obj = User_table.objects.get(user_name=username)
if obj:
s = obj.login_try
s = s + 1
obj.login_try = int(s)
if int(obj.login_try) >= 3:
obj.login_try = 3
obj.save()
if int(obj.login_try) == 3:
id = obj.id
key = get_random_string(length=10)
reset_link = 'It seems you forgot password or someone is trying to login you account. This is your password reset link please do not share this with other ' + settings.EMAIL_URL + 'reset_password/' + str(
id) + ' key is : ' + str(key)
send_mail('Reset link', reset_link, settings.EMAIL_HOST_USER, [obj.emailid, ])
obj.password = str(key)
obj.save()
return HttpResponse(
'It seems you forgot password or someone is trying to login you account. Password Reset link has been sent to your email id')
except Exception as e:
print(e)
pass
return redirect(mainlogin)
except Exception as e:
print('error is : ', e)
return HttpResponse('An error has occurred.')
Also, I have included the csrf middleware in my settings.py.
what can be wrong here?
Thanks in advance!
Your problem is here:
if request.method == "GET":
try:
temp = get_template('login.html')
result = temp.render(Context({'context': RequestContext(request)}))
return HttpResponse(result)
Docs about CSRF
In the corresponding view functions, ensure that RequestContext is
used to render the response so that {% csrf_token %} will work
properly. If you’re using the render() function, generic views, or
contrib apps, you are covered already since these all use
RequestContext.
I'm not exactly sure why it's happening, maybe something wrong with context processors configuration, one of them adds csrf_token to context dictionary.
For more debugging see RequestContext section. But using builtin render() function will solve your problem as it'll handle context for you.
from django.shortcuts import render
if request.method == "GET":
...
return render(request, 'login.html')
login.html
`<h2>Login</h2>
<form method="post" action="">
{% csrf_token %}
{{ form.as_p }}
</form>
<input type="submit" value="login" />`
loggedin.html
`<h2>login success</h2>`
views.py
`def signin(request):
if request.method == "POST":
form = LoginForm(request.POST) #form = email, password
email_input = str(request.POST['email'])
password_input = str(request.POST['password'])
user_Qset = Profile.objects.filter(email = email_input)
if user_Qset is not None:
password_saved = str(user_Qset.values('password')[0]['password'])
if password_input == password_saved:
response = render(request, 'registration/login.html',)
request.session.modified = True
request.session['name'] = user_Qset.values('name')[0]['name']
request.session['email'] = user_Qset.values('email')[0]['email']
request.session['password'] = user_Qset.values('password')[0]['password']
return response
def loggedin(request):
if request.session.has_key('name'):
return HttpResponse("transmission success")
else:
return HttpResponse("transmission failed")`
I have a result 'transmission failed'. How can I transmit sessions I added?
When I push the login button, page url and templates should be changed and session be transmitted
When user log in, I want give user session keys(name, email, password)
I want to check session keys I gave is maintained well in another page
I have multiple form on the same page that send post request to same handler
in flask.
I am generating forms using wtforms.
what is the best way to identify which form is submitted ?
I am currently using action="?form=oneform". I think there should be some better method
to achieve the same?
The solution above have a validation bug, when one form cause a validation error, both forms display an error message. I change the order of if to solve this problem.
First, define your multiple SubmitField with different names, like this:
class Form1(Form):
name = StringField('name')
submit1 = SubmitField('submit')
class Form2(Form):
name = StringField('name')
submit2 = SubmitField('submit')
....
Then add a filter in view.py:
....
form1 = Form1()
form2 = Form2()
....
if form1.submit1.data and form1.validate(): # notice the order
....
if form2.submit2.data and form2.validate(): # notice the order
....
Now the problem was solved.
If you want to dive into it, then continue read.
Here is validate_on_submit():
def validate_on_submit(self):
"""
Checks if form has been submitted and if so runs validate. This is
a shortcut, equivalent to ``form.is_submitted() and form.validate()``
"""
return self.is_submitted() and self.validate()
And here is is_submitted():
def is_submitted():
"""Consider the form submitted if there is an active request and
the method is ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
"""
return _is_submitted() # bool(request) and request.method in SUBMIT_METHODS
When you call form.validate_on_submit(), it check if form is submitted by the HTTP method no matter which submit button was clicked. So the little trick above is just add a filter (to check if submit has data, i.e., form1.submit1.data).
Besides, we change the order of if, so when we click one submit, it only call validate() to this form, preventing the validation error for both form.
The story isn't over yet. Here is .data:
#property
def data(self):
return dict((name, f.data) for name, f in iteritems(self._fields))
It return a dict with field name(key) and field data(value), however, our two form submit button has same name submit(key)!
When we click the first submit button(in form1), the call from form1.submit1.data return a dict like this:
temp = {'submit': True}
There is no doubt when we call if form1.submit.data:, it return True.
When we click the second submit button(in form2), the call to .data in if form1.submit.data: add a key-value in dict first, then the call from if form2.submit.data: add another key-value, in the end, the dict will like this:
temp = {'submit': False, 'submit': True}
Now we call if form1.submit.data:, it return True, even if the submit button we clicked was in form2.
That's why we need to define this two SubmitField with different names. By the way, thanks for reading(to here)!
Update
There is another way to handle multiple forms on one page. You can use multiple views to handle forms. For example:
...
#app.route('/')
def index():
register_form = RegisterForm()
login_form = LoginForm()
return render_template('index.html', register_form=register_form, login_form=login_form)
#app.route('/register', methods=['POST'])
def register():
register_form = RegisterForm()
login_form = LoginForm()
if register_form.validate_on_submit():
... # handle the register form
# render the same template to pass the error message
# or pass `form.errors` with `flash()` or `session` then redirect to /
return render_template('index.html', register_form=register_form, login_form=login_form)
#app.route('/login', methods=['POST'])
def login():
register_form = RegisterForm()
login_form = LoginForm()
if login_form.validate_on_submit():
... # handle the login form
# render the same template to pass the error message
# or pass `form.errors` with `flash()` or `session` then redirect to /
return render_template('index.html', register_form=register_form, login_form=login_form)
In the template (index.html), you need to render both forms and set the action attribute to target view:
<h1>Register</h1>
<form action="{{ url_for('register') }}" method="post">
{{ register_form.username }}
{{ register_form.password }}
{{ register_form.email }}
</form>
<h1>Login</h1>
<form action="{{ url_for('login') }}" method="post">
{{ login_form.username }}
{{ login_form.password }}
</form>
I've been using a combination of two flask snippets. The first adds a prefix to a form and then you check for the prefix with validate_on_submit(). I use also Louis Roché's template to determine what buttons are pushed in a form.
To quote Dan Jacob:
Example:
form1 = FormA(prefix="form1")
form2 = FormB(prefix="form2")
form3 = FormC(prefix="form3")
Then, add a hidden field (or just check a submit field):
if form1.validate_on_submit() and form1.submit.data:
To quote Louis Roché's:
I have in my template :
<input type="submit" name="btn" value="Save">
<input type="submit" name="btn" value="Cancel">
And to figure out which button was passed server side I have in my views.py file:
if request.form['btn'] == 'Save':
something0
else:
something1
A simple way is to have different names for different submit fields. For an
example:
forms.py:
class Login(Form):
...
login = SubmitField('Login')
class Register(Form):
...
register = SubmitField('Register')
views.py:
#main.route('/')
def index():
login_form = Login()
register_form = Register()
if login_form.validate_on_submit() and login_form.login.data:
print "Login form is submitted"
elif register_form.validate_on_submit() and register_form.register.data:
print "Register form is submitted"
...
As the other answers, I also assign a unique name for each submit button, for each form on the page.
Then, the flask web action looks like below - note the formdata and obj parameters, which help to init / preserve the form fields accordingly:
#bp.route('/do-stuff', methods=['GET', 'POST'])
def do_stuff():
result = None
form_1 = None
form_2 = None
form_3 = None
if "submit_1" in request.form:
form_1 = Form1()
result = do_1(form_1)
elif "submit_2" in request.form:
form_2 = Form2()
result = do_2(form_2)
elif "submit_3" in request.form:
form_3 = Form3()
result = do_3(form_3)
if result is not None:
return result
# Pre-populate not submitted forms with default data.
# For the submitted form, leave the fields as they were.
if form_1 is None:
form_1 = Form1(formdata=None, obj=...)
if form_2 is None:
form_2 = Form2(formdata=None, obj=...)
if form_3 is None:
form_3 = Form3(formdata=None, obj=...)
return render_template("page.html", f1=form_1, f2=form_2, f3=form_3)
def do_1(form):
if form.validate_on_submit():
flash("Success 1")
return redirect(url_for(".do-stuff"))
def do_2(form):
if form.validate_on_submit():
flash("Success 2")
return redirect(url_for(".do-stuff"))
def do_3(form):
if form.validate_on_submit():
flash("Success 3")
return redirect(url_for(".do-stuff"))
I haven't used WTForms but should work regardless. This is a very quick and simple answer; all you need to do is use different values for the submit button. You can then just do a different def based on each.
In index.html:
<div>
<form action="{{ url_for('do_stuff')}}" method="POST">
<h1>Plus</h1>
<input type = "number" id = "add_num1" name = "add_num1" required><label>Number 1</label><br>
<input type = "number" id = "add_num2" name = "add_num2" required><label>Number 2</label><br>
<input type = "submit" value = "submit_add" name = "submit" ><br>
</form>
<p>Answer: {{ add }}</p>
</div>
<div>
<form action="{{ url_for('do_stuff')}}" method="POST">
<h1>Minus</h1>
<input type = "number" id = "min_num1" name = "min_num1" required><label>Number 1</label><br>
<input type = "number" id = "min_num2" name = "min_num2" required><label>Number 2</label><br>
<input type = "submit" value = "submit_min" name = "submit"><br>
</form>
<p>Answer: {{ minus }}</p>
</div>
in app.py:
#app.route('/',methods=["POST"])
def do_stuff():
if request.method == 'POST':
add = ""
minus = ""
if request.form['submit'] == 'submit_add':
num1 = request.form['add_num1']
num2 = request.form['add_num2']
add = int(num1) + int(num2)
if request.form['submit'] == 'submit_min':
num1 = request.form['min_num1']
num2 = request.form['min_num2']
minus = int(num1) - int(num2)
return render_template('index.html', add = add, minus = minus)
Well here is a simple trick
Assume you Have
Form1, Form2, and index
Form1 <form method="post" action="{{ url_for('index',formid=1) }}">
Form2 <form method="post" action="{{ url_for('index',formid=2) }}">
Now In index
#bp.route('/index', methods=['GET', 'POST'])
def index():
formid = request.args.get('formid', 1, type=int)
if formremote.validate_on_submit() and formid== 1:
return "Form One"
if form.validate_on_submit() and formid== 2:
return "Form Two"
I normally use a hidden tag that works as an identifier.
Here is an example:
class Form1(Form):
identifier = StringField()
name = StringField('name')
submit = SubmitField('submit')
class Form2(Form):
identifier = StringField()
name = StringField('name')
submit = SubmitField('submit')
Then you can add a filter in view.py:
....
form1 = Form1()
form2 = Form2()
....
if form1.identifier.data == 'FORM1' and form1.validate_on_submit():
....
if form2.identifier.data == 'FORM2' and form2.validate_on_submit():
....
and finally in the HTML:
<form method="POST">
{{ form1.indentifier(hidden=True, value='FORM1') }}
</form>
<form method="POST">
{{ form2.indentifier(hidden=True, value='FORM2') }}
</form>
If you do it like this in the if statement it will check what was the identifier and if its equal it will run the form stuff you have in your code.
Example: Multiple WTForm in single html page
app.py
"""
Purpose Create multiple form on single html page.
Here we are having tow forms first is Employee_Info and CompanyDetails
"""
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField, FloatField, validators
from wtforms.validators import InputRequired
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Thisisasecret'
class EmployeeInfo(FlaskForm):
"""
EmployeeInfo class will have Name,Dept
"""
fullName = StringField('Full Name',[validators.InputRequired()])
dept = StringField('Department',[validators.InputRequired()])
class CompanyDetails(FlaskForm):
"""
CompanyDetails will have yearOfExp.
"""
yearsOfExp = IntegerField('Year of Experiece',[validators.InputRequired()])
#app.route('/', methods = ['GET','POST'] )
def index():
"""
View will render index.html page.
If form is validated then showData.html will load the employee or company data.
"""
companydetails = CompanyDetails()
employeeInfo = EmployeeInfo()
if companydetails.validate_on_submit():
return render_template('showData.html', form = companydetails)
if employeeInfo.validate_on_submit():
return render_template('showData.html', form1 = employeeInfo)
return render_template('index.html',form1 = employeeInfo, form = companydetails)
if __name__ == '__main__':
app.run(debug= True, port =8092)
templates/index.html
<html>
<head>
</head>
<body>
<h4> Company Details </h4>
<form method="POST" action="{{url_for('index')}}">
{{ form.csrf_token }}
{{ form.yearsOfExp.label }} {{ form.yearsOfExp }}
<input type="submit" value="Submit">
</form>
<hr>
<h4> Employee Form </h4>
<form method="POST" action="{{url_for('index')}}" >
{{ form1.csrf_token }}
{{ form1.fullName.label }} {{ form1.fullName }}
{{ form1.dept.label }} {{ form1.dept }}
<input type="submit" value="Submit">
</form>
</body>
</html>
showData.html
<html>
<head>
</head>
<body>
{% if form1 %}
<h2> Employee Details </h2>
{{ form1.fullName.data }}
{{ form1.dept.data }}
{% endif %}
{% if form %}
<h2> Company Details </h2>
{{ form.yearsOfExp.data }}
{% endif %}
</body>
</html>