make url semantic (dynamic) in Flask - python

I build a simple flusk service, this is a part of home page:
<form action="/results" method="POST">
<div>
<label class="required">Name: </label>
<input type="text" id="name" name="name" required="required"/>
</div>
<div>
<label class="required">ID: </label>
<input type="text" id="ID" name="ID" required="required"/>
</div>
<button type="submit" class="submit" id="submit" onclick="loading()"> Submit </button>
</form>
Here is a part of python:
#app.route('/', methods=['GET'])
def main_page():
return render_template('ui/home_page.html')
#app.route('/results', methods=['POST'])
def show_results():
# do something...
return render_template('ui/result_page.html')
It works when I click button and shows results in http://localhost:8080/results.
I now want to make the result url to be semantic base on users' input in the home page such as http://localhost:8080/results/user=balabala&ID=balabala. I tried modify the python
#app.route('/results/<url_postfix>', methods=['POST'])
def process_diff_by_platform(url_postfix):
# do something...
return render_template('ui/result_page.html')
but it shows 404 Not Found. I guess this is because that I hard coded the url in html template. But I have no idea how to fix that...
How do I solve this problem?
~ thanks

Related

How to fix "Method not allowed" error in Python Flask app

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">

HTML and Python - Radio Button Choice then Redirect

I want my app when I click the radio button of choice, it will redirect me to the page that I want it to, here's my code:
#app.route('/', methods=['GET', 'POST'])
def main():
if request.method == 'GET': #html radio form
return render_template('home.html', selected = "home")
then my HTML file:
<h2>What do you want to do?</h2>
<form method = "GET">
<form class="p2c-form">
<fieldset>
<div class="p2c-form-group">
<label for="show">Show all SKU</label>
<input id="show" type="radio">
</div>
<div class="p2c-form-group">
<label for="add">Add an SKU</label>
<input id="add" type="radio">
</div>
<div class="p2c-form-group">
<label for="remove">Remove an SKU</label>
<input id="remove" type="radio">
</div>
<div class="p2c-form-group">
<label for="insert">Insert an SKU</label>
<input id="insert" type="radio">
</div>
<div class="p2c-form-group">
<label for="forecast">Use forecaster</label>
<input id="forecast" type="radio" >
</div>
<button type="submit" class="p2c-button" value = "p2cbtn">Submit</button>
</div>
</fieldset>
</form>
How do I if-else the value of these buttons so that when the user chooses the radio button then clicks "submit", he would be redirected to the assigned page. Do I if-else within the HTML(using <%%>? or in Python(using request.form['']? How do I approach this problem?
You can use request.form in python, without even creating an if-else block
def x():
var = request.form["Radio"]
return render_template("%s.html" % var, selected="home")
Make sure to set the name of radio buttons. If you only want the user to select one of the radio buttons, set them to the same name
<input type="radio" name="Radio" val="select">
<input type="radio" name="Radio" val="show">
This will ensure that only one of those buttons can be selected

400 Bad Request Flask

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.

Bad Request with Flask

really struggling with this bad request from flask. I know normally it caused by flask not finding the [key] in the form.. However, I've checked my form and python code 40 times and cannot see any reason that would be the case.. I have commented out each line of the python code that references request.form. I have done it 1 by 1 and I still get a bad request. However when I comment out all the lines the bad request goes away.. Any thought would be wonderful..
Python code;
if request.method == 'POST':
form = 'Add Package Form'
clientId = request.form['id']
date = request.form['date2']
strPrice = request.form['price']
price = float(strPrice)
adultlessons = request.form['adult']
juniorlessons = request.form['junior']
shortlessons = request.form['short']
playinglessons = request.form['playing']
notes = request.form['notes']
form..
<form action="/addpackage" method="post" class="sky-form">
<fieldset>
<section>
<label class="label">Select Package Date</label>
<label class="input">
<i class="icon-append fa fa-calendar"></i>
<input type="text" name="date2" id="date">
</label>
</section>
<div style="margin: -25px"></div>
<fieldset>
<section>
<label class="label">Price</label>
<label class="input">
<input type="text" name="price">
</label>
</section>
<section>
<label class="label">Adult Lessons</label>
<label class="input">
<input type="text" name="adult">
</label>
</section>
<section>
<label class="label">Junior Lessons</label>
<label class="input">
<input type="text" name="junior">
</label>
</section>
<section>
<label class="label">Short Game Lessons</label>
<label class="input">
<input type="text" name="short">
</label>
</section>
<section>
<label class="label">Playing Lessons</label>
<label class="input">
<input type="text" name="playing">
</label>
</section>
<section>
<label class="label">Notes</label>
<label class="textarea textarea-expandable">
<textarea rows="3" name="notes"></textarea>
</label>
<div class="note"><strong>Note:</strong> expands on focus.</div>
</section>
</fieldset>
</fieldset>
<!-- hidden client id -->
<input type="hidden" name="id" value="{{ client.id }}">
<!-- /hidden client id -->
<footer>
<button type="submit" name="addpackage" value="package" class="button">Add Package</button>
</footer>
</form>
This is something of a half-answer, but it was too long for a comment.
If you enable debugging in your Flask app you should get a detailed traceback indicating exactly where the problem is occurring (both in the browser and on your console).
If your application currently has something like:
app.run()
Just set the debug parameter to true:
app.run(debug=True)
If after enabling debugging you're still not sure what's causing the problem, update your question to include the traceback.
For what it's worth, if I dump your form and your code into a simple Flask app, it all seems to work just fine as long as I provide a numeric value for the price field.
Usually you'll get a 400 Bad Request in Flask while submitting a form when you try and access a form key in the request object that doesn't exist.
This is because the request.form object inherits its __getitem__ method the Multidict class in the werkzeug.datastructures module which raises a BadRequestKeyError when a key doesn't exist.
You should give the form data a default value to avoid HTTP 400 error, like this:
default_value = True
is_public = request.form.get('public', default_value)
However, I recommend you to use Flask-WTF.
With Flask-WTF, your code can be simplify to this (an example):
import ...
app = Flask(__name__)
class EditProfileForm(Form):
name = StringField('name', validators=[Length(0, 64)])
location = StringField('city', validators=[Length(0,64)])
website = StringField('website', validators=[Length(0,64), render_kw={"placeholder": "http://..."})
about_me = TextAreaField('Bio', validators=[Length(0,2000)], render_kw={"placeholder": "I'm......"})
submit = SubmitField(u'submit')
#app.route('/edit-profile', methods=['GET', 'POST'])
def edit_profile():
form = EditProfileForm()
if form.validate_on_submit():
current_user.name = form.name.data
current_user.location = form.location.data
current_user.website = form.website.data
current_user.about_me = form.about_me.data
db.session.add(current_user)
flash('Update success!', 'success')
return redirect(url_for('.user', username=current_user.username))
return render_template('edit_profile.html', form=form)
In your html file:
<form method="POST" action="/">
{{ form.hidden_tag() }}
{{ form.name.label }} {{ form.name() }}
{{ form.location.label }} {{ form.location() }}
...
</form>
By the way, if you use Flask-Bootstrap, you can just use one line to render the whole form:
{% import "bootstrap/wtf.html" as wtf %}
{{ wtf.quick_form(form) }}
I hope it will help.

Html form not sending data

I have a form action but it's not sending data and I don't know why, so I was hoping you could tell me why.
Here's my form:
<form method="post" action="http://myapp.herokuapp.com/test/url">
<input placeholder="Name" type="text" name="user" maxlength="30">
<input placeholder="Password" type="password" name="password">
<input placeholder="email" type="text" name="mail">
<input class="btn btn-register" type="submit" value="¡Register now!" />
</form>
And here's my back-end code (Python):
def test_1(request):
return HttpResponse(simplejson.dumps({'post': request.POST, 'get': request.GET}))
What I get:
{"get": {}, "post": {}}
I have already an app working fine, and now I'm doing a Phonegap version of it.
Any ideas?
Edit:
When I change the url for http://myapp.herokuapp.com/test/url/ I get this:
CSRF verification failed. Request aborted.

Categories

Resources