Flask - Pass argument to URL - 405 Error - python

I am learning Flask and I am having some trouble passing arguments to a URL for use on another page. For example, I have a form on /index and I would like it to redirect to a /results page where I could print the form data. My attempt is this:
from flask import render_template
from flask import redirect
from flask import url_for
from app import app
from .forms import LoginForm
#app.route('/')
#app.route('/index', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
name = form.artistName.data
return redirect(url_for('result', name=name))
else:
return redirect('/index')
return render_template('index.html',
title='Sign In',
form=form)
#app.route('/result/<name>')
def result(name):
return render_template('results.html')
I receive a 405 error Method not allowed for the requested URL when redirecting to the /results page. I would like to construct a URL on /results using the result of the form as an argument.
How can I do this? Many thanks

you defined
#app.route('/result/<name>')
which means its default http method is GET;
when this runs:
if form.validate_on_submit():
# POST method
name = form.artistName.data
# redirect Will use 'POST'
return redirect(url_for('result', name=name))
so , you got Method not allowed for the requested URL.
i think you can add a POST method to #app.route('/result/<name>')

Related

Flask redirect(url_for) with arguments

I'm new to building web apps using Flask and having trouble using redirect(url_for)
from flask import Flask, render_template, request, redirect, url_for
app = Flask(__name__)
def getSomeList(paramsFromHTML):
return someList
#app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
myData = getSomeList(paramsFromHTML)
return redirect(url_for("show_data", this_data=myData))
else:
# Show the default page for GET requests
return render_template("welcome.html")
#app.route("/show_data", methods=["GET", "POST"])
def show_data(this_data):
return render_template("show_data.html", data=this_data)
Once I get some details from HTML in my main index page, I need to route it to the show_data view function.
The function has a parameter (this_data). However, there is no parameter in the route itself - like "/show_data/<string:something>" It is just "/show_data"
I get the below error when trying this.
TypeError: show_data() missing 1 required positional argument: 'this_data'
Is it mandatory to have some kind of a parameter in the url route as well?
Is there any work around I can try for my use case?
I was able to get this working after removing the args part (this_data) from my show_data function and use the below to get the value -
this_data = request.args.get('data')

How to give arguments to view with flask, redirect url_for

I have an application build with flask and I want to pass one input tag from my current html view ('/setpickup') to another view, in order to reuse the variable values of that input and print them again in the new view ('/payments.html'). But I dont know if it is possible, thanks you. Here is a brief of the code that is not working at this moment.
#app.route('/')
#app.route('/setpickup', methods=['GET', 'POST'])
#login_required
def setpickup():
form = RideForm()
device = Utils.getDevice()
if request.method == 'POST':
data_input_data = form.data_input.data
return redirect(url_for('payment', data_input_data=data_input_data))
#app.route('/payment')
#login_required
def payment(data_input_data):
device = Utils.getDevice()
return render_template("/"+device+"/payment.html",
device=device,
data_input_data=data_input_data)

Redirect to one Flask view from another

I have a view that is accessed by clicking a link on the index page. The view will perform an action and should then show the index page again. My view does that, but the url is still the url of the action view, not the index view. How can I redirect back to the index view?
#app.route('/')
def index():
return render_template('index.html')
#app.route('/u1/')
def u1():
# do something
return render_template('index.html')
Use url_for to build a url to another endpoint in the app. Use redirect to create a redirect response with that url.
from flask import url_for, redirect
#app.route('/u1/')
def u1():
# do something
return redirect(url_for('index'))

How to print output using only a POST Method?

How can I print something like this:
{
username = admin
email = admin#localhost
id=42
}
With only using a method = ['POST'] and without using render_template?
PS: I already made it run with ['GET']
Here's my code:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
if request.method == 'POST':
return jsonify(username="admin",
email="admin#localhost",
id="42")
else:
if request.method == 'POST':
return jsonify(username="admin",
email="admin#localhost",
id="42")
if __name__ == "__main__":
app.run()
And what I get is a 405 Method error.
Hey make sure your trailing stashes in your html are correct.
you may refer to : Flask - POST Error 405 Method Not Allowed and flask documentation : http://flask.pocoo.org/docs/0.10/quickstart/
this
<form action="/" method="post">
and this is same same but different
<form action="" method="post">
Accessing it without a trailing slash will cause Flask to redirect to the canonical URL with the trailing slash.
Given your error 405, I am suspecting that this is your problem. GET is fine, because you will just be redirected.
Try returning the form (as biobirdman said) on a GET request. Not sure why you need the request.method == 'POST' conditional statement. The parameter methods=['POST'] in the route should suffice.
Try this:
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/', methods=['POST'])
def index():
return jsonify(username="admin", email="admin#localhost", id="42")
#app.route('/', methods=['GET'])
def form():
return "<form action='/' method='POST'>" \
"<input type='submit'>" \
"</form>"
if __name__ == "__main__":
app.run()

how do I redirect to the flask blueprint parent?

Suppose i have the following structure:
/root/user/login
I do the login in a blueprint:
app.register_blueprint(login_blueprint,url_prefix=prefix('/user'))
I can redirect to ".index":
#login_blueprint.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
#### this redirects me to '/root/user/'
redirect_to_index= redirect(url_for('.index'))
response = current_app.make_response(redirect_to_index)
# do the log in
return response
redirect_to_index=redirect(url_for('.index'))
response = current_app.make_response(redirect_to_index)
The redirect brings me to /root/user:
redirect(url_for('.index'))
But how to get to /root (which is up relative to the current url (..)?
You can pass url_for the name of the endpoint function for /root/.
For example, if you have:
#app.route('/root/')
def rootindex():
return "this is the index for the whole site."
elsewhere in your app, you can do:
redirect(url_for('rootindex'))
To cause a redirect here. When you put a . in front of the string you pass to url_for, that tells it to look for an endpoint in the current blueprint. By leaving the . off, you tell it to look for a endpoint in the app

Categories