First of all, I've searched this error, tried everything those guys said but it won't work for me.
So, basically, I'm having a login form, and I can't even access the page as it gives me the 400 Bad Request error.
My flask code:
#app.route('/', methods=['POST', 'GET'])
def login():
users = mongo.db.users
login_user = users.find_one({'name' : request.form['username']})
if login_user:
if bcrypt.hashpw(request.form['pass'].encode('utf-8'), login_user['password'].encode('utf-8')) == login_user['password'].encode('utf-8'):
session['username'] = request.form['username']
return redirect(url_for('index'))
return 'Invalid username/password combination'
My HTML form:
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<form method=POST action="{{ url_for('login') }}" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputEmail1">Username</label>
<input type="text" class="form-control" name="username" placeholder="Username">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" name="pass" placeholder="Password">
</div>
<button type="submit" class="btn btn-primary btn-block">Log In</button>
</form>
<br>
</div>
</div>
I have a similar register page but that works fine, it adds the user to the DB.
I have fixed it. I had to include if request.method == 'POST' under the login index. No idea how I didn't come to this earlier, it makes sense that I was requesting something from the form when I didn't even had the chance to type.
Thanks everyone.
Your html form should be render by login view because in your login view you are trying to get form value:
#app.route('/', methods=['POST', 'GET'])
def login():
...
return render_template('your_htmlform.html')
And now in your form action you can add action={{url_for('index')}} if form submitted.
Related
Complete newbie to web dev so I suspect this might be more of an architectural problem rather than a technical one..
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
#app.route('/', methods=("POST", "GET"))
def index():
if request.method == 'GET':
return render_template("templ.html")
if request.method == 'POST':
if 'submit' in request.form:
return str([request.form[val] for val in ['input1', 'input2']])
if 'cancel' in request.form:
return redirect(url_for('index'))
app.run(host='0.0.0.0', port='5000')
html:
<!doctype html>
<form action="." method="POST">
<div>
<input type="text" name="input1" required="required">
<input type="text" name="input2" required="required">
</div>
<div>
<button name="submit">Submit</button>
<button name="cancel">Cancel</button>
</div>
</form>
Question: Can I skip 'required' when cancel button is pressed with this simple design or do I need to employ flask_wtf with wtforms.validators? Could I get a working minimal script with my example code please?
There may be a more efficient way of handling it, but this will work as it places the 'Cancel' button in a separate form.
<form action="." method="POST" id ="CancelForm"></form>
<form action="." method="POST">
<div>
<input type="text" name="input1" required="required">
<input type="text" name="input2" required="required">
</div>
<div>
<button name="submit">Submit</button>
<button type="submit" form="CancelForm">Cancel</submit>
</div>
</form>
You may want to give it a different action so you can handle 'cancel' differently
I have a defined route in my Python Flask app(which worked fine).
#app.route('/insertpage', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
companyname = request.form['companyname']
username = request.form['username']
userpass = request.form['password']
new_company= Grocery(companyname=companyname,
username=username, userpass=userpass)
try:
db.session.add(new_company)
db.session.commit()
return render_template('index.html', data=Todos.query.all())
except:
return "The problem occurred while adding a new company...."
else:
groceries = Grocery.query.order_by(Grocery.created_at).all()
return render_template('index.html', groceries=groceries)
And I am collecting information in my HTML page:
<form action="/" method="POST">
<div class="form-row">
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New company:</label>
<input type="text" class="form-control" name="companyname" id="newStuff" placeholder="Enter name of new company">
</div>
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New username:</label>
<input type="text" class="form-control" name="username" id="newStuff" placeholder="Enter username...">
</div>
<div class="col-sm-3 my-1">
<label for="newStuff" class="sr-only">New password:</label>
<input type="text" class="form-control" name="password" id="newStuff" placeholder="Enter password...">
</div>
<div class="col-sm-3 my-1">
<button type="submit" class="btn btn-primary btn-block">Add</button>
</div>
</div>
</form>
After a couple of successful CRUD operations, I am facing the following error(even if I defined 'POST' and 'GET' in my def).
Method Not Allowed
The method is not allowed for the requested URL.
The action attribute of your HTML form needs to match the name of your Flask route.
Your page is sending a POST to url '/' , so it isn't hitting your route, which is for the path '/insertpage'
You should change it to <form action="/insertpage" method="POST">
I am trying to get user input for a 'username' and 'password' from a form in HTML so I can input them into my python script and have the program run. Where do I need to put the request.form to receive both variables?
app.py
from flask import Flask, render_template, url_for, request
app = Flask(__name__)
#app.route('/', methods=['POST', 'GET'])
def home():
rh = Robinhood()
rh.login(username="EMAIL", password="PASSWORD")
projectpath = request.form['projectFilepath']
return render_template('index.html')
index.html
<form action="{{ url_for('home') }}" method="post">
<input type="text" name="projectFilepath">
<input type="submit">
</form>
Very new to flask and python, thanks for the help!
In your html, follow the input type with a placeholder and name; along with an error message that's optional but advised (put outside of the form div); give each method of 'username' and 'password' their request.form values respectively:
<div class="form">
<form action="" method="post">
<input type="text" placeholder="Username" name="username" value="{{
request.form.username }}">
<input type="password" placeholder="Password" name="password" value="{{
request.form.password }}">
<input class="btn btn-default" type="submit" value="Login">
</form>
{% if error %}
<p class="error">Error: {{ error }}
{% endif %}
</div>
In your python file, put your request.form following an if statement under /login with the methods POST and GET; include your newly made error message:
#app.route('/login', methods=['POST', 'GET'])
def home():
error = None
if request.method == 'POST':
if request.form['username'] != 'admin' or request.form['password'] != 'admin':
error = 'Error Message Text'
else:
return redirect(url_for('home'))
return render_template('index.html', error=error)
I have a very common problem - after login I want to redirect to the page where login was called. I can describe situation exactly like here: Django: Redirect to previous page after login
There are 2 options where you can log in - from the home page (which is defined in base.html) and from bokeh.html (other views inherit from bokeh)
my base.html and bokeh.html have the same block to redirect to login. Difference is, that login called from home page should return to home page and from other page should return to page where was called.
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}">Login</a>
</li>
my login.html
<form method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Username" name="username" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Enter Password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-dark">Login</button>
</div>
</form>
and views.py
def login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect('home')
else:
messages.info(request,'Invalid credentials')
return redirect('login')
else:
return render(request,'login.html')
I was trying to add next to my form in login.html but it didn't work. While accessing to login from page other than home page it was like: localhost:8000/login?next=/bokeh/ and after submiting form I was still on login but URL changed to localhost:8000/login?next=. I know it's pretty hard to explain but I will add another information in need.
First, change the template to include the urlencoded next parameter to the login url:
<li class="nav-item">
<a class="nav-link" href="{% url 'login' %}?next={{ request.path |urlencode }}">Login</a>
</li>
Second, your login template needs to preserve the value of next:
<form method="POST">
<input type="hidden" name="next" value=""{{ next }}">
{% csrf_token %}
<div class="form-group">
<input type="text" class="form-control" placeholder="Enter Username" name="username" required>
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Enter Password" name="password" required>
</div>
<div class="form-group">
<button type="submit" class="btn btn-dark">Login</button>
</div>
</form>
Third, your login view should retrieve the URL parameter and pass it to the template:
from django.conf import settings
def login(request):
if request.method == 'GET':
next = request.GET.get('next', settings.LOGIN_REDIRECT_URL)
return render(request, 'login.html', {'next': next})
if request.method == 'POST':
next = request.POST['next']
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username,password=password)
if user is not None:
auth.login(request,user)
return redirect(next)
else:
messages.info(request,'Invalid credentials')
return redirect('login')
Finally, you should consider using the Django Authentication Views instead of writing your own login views!
I am trying to create a login page for my flask web app code shown below:
# Route for handling the login page logic
#app.route('/logins', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'GET':
# Just render the initial form, to get input
return (render_template('login.html'))
if request.method == 'POST':
if request.form['username'] == 'admin' or request.form['password'] == 'P#55w0rd':
return redirect(url_for('main'))
else:
error = 'Invalid Credentials. Please try again.'
return render_template('login.html', error=error)
# Set up the main route
#app.route('/main', methods=['GET', 'POST'])
def main():
if request.method == 'GET':
# Just render the initial form, to get input
return(render_template('main.html'))
This is my HTML login page code
<form id="login" action="/logins" method="POST" class="login100-form validate-form">
<span class="login100-form-logo">
<i class="zmdi zmdi-landscape"></i>
</span>
<span class="login100-form-title p-b-34 p-t-27">
Log in
</span>
<div class="wrap-input100 validate-input" data-validate = "Enter username">
<input class="input100" type="text" id="username" name="username" placeholder="Username" value={{request.form.username}}>
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="wrap-input100 validate-input" data-validate="Enter password">
<input class="input100" type="password" id="password" name="pass" placeholder="Password" value="{{
request.form.password }}">
<span class="focus-input100" data-placeholder=""></span>
</div>
<div class="container-login100-form-btn">
<button type="submit" class="login100-form-btn">
Login
</button>
</div>
</form>
{% if error %}
<p class="error"><strong>Error:</strong> {{ error }}
{% endif %}
but after clicking on login button
404 Method Not allowed
error is coming. what changes to be done in my code so that it can properly redirect to main.html?
Change 'password' to 'pass' :
if request.form['username'] == 'admin' or request.form['pass'] == 'P#55w0rd':