problem getting data for an html in python with flask [duplicate] - python

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 4 months ago.
Hello i am doing a proyect in pyhton with flask an i pretend to introduce a txt and read it.
This code is part of home.html:
<input type="file" id="gameTXT" name="gameTXT" accept="txt">
<input type="submit" id="submitTXT" value="Submit">
and this one is the part of python:
#app.route("/")
def home():
return render_template('home.html')
How can i get the file? I read that i need to put methods=['GET'] but i don't know where to put it
I try to put methods=['GET'] in the app.route("/") but it doesn't work and it's understandable. I expect to get the file

if you want to get the file, you need to first know what is your form method, as you mentioned GET, I assume GET. (But I insert POST just in case).
You need to create the function, mentioning that the method is GET, and then you need to get the data that was send, which is request.form['name']
Get the data received in a Flask request
Referring above, your code should be
#app.route("/", methods=['GET', 'POST'])
def home():
data = request.form['gameTXT']
### do whatever you want with data
return render_template('home.html')

Try adding method in the route() like this :
#app.route("/", methods=["GET"])
def home():
return render_template('home.html')

Related

Building a user review with python flask [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed last year.
I encountered some problems when trying to open the link provided by the flask. I have updated my code and when I run and open the link only hello world is displayed and not the current code. Can someone explain why pls?
Also the review page asks for the user to input their name and I tried this as code in the python flask although I can't check if this will get the user input due to the problem mentioned above. Does this code make sense?
from flask import Flask,request,render_template
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/")
def name():
name = request("name")
The problem is that you have the same route twice.
You have to use different routes for different endpoints.
Example:
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def index():
return render_template("index.html")
#app.route("/name")
def name():
return "This is the name endpoint."
When you go to /name, you should see 'This is the name endpoint.'.

How is flask able to access login.html? [duplicate]

This question already has answers here:
Sending data from HTML form to a Python script in Flask
(2 answers)
Closed 1 year ago.
I am trying to learn flask.
My login.html file-
<html>
<body>
<form action = "http://localhost:5000/login" method = "post">
<table>
<tr><td>Name</td>
<td><input type ="text" name ="uname"></td></tr>
<tr><td>Password</td>
<td><input type ="password" name ="pass"></td></tr>
<tr><td><input type = "submit"></td></tr>
</table>
</form>
</body>
</html>
And my main.py file has this-
#app.route('/login',methods = ['POST'])
def login():
uname=request.form['uname']
passwrd=request.form['pass']
if uname=="ayush" and passwrd=="google":
return "Welcome %s" %uname
I am not able to understand how is this able to access login.html without specifying. Also also please explain what is the code in main.py means.
You have to specify the 'html' in flask to access it, however, if you open the html file in browser this will still work since its action is aimed directly at your flask server.
the code of your main.py says that if the in the form sent the data 'uname' and 'pass' are respectively 'ayush' and 'google', the code sends back to the browser a text indicating: "Welcome ayush"
If you want to directly implement the html in your flask web server, you have to create the function and put your html code in templates folder.
from flask import render_template
...
#app.route('/', methods=['GET'])
def code():
return render_template('index.html', name='')
So you can access with http://localhost:5000/ now

Flask WTForms - Retrieve form data when submitting to a different route, i.e. a different POST route than the GET route which renders the form

I would like to set up my URLs/endpoints according to REST as closely as possible, while still utilising Flask-WTForms.
I would like my form to render at GET /posts/new, and submit to POST /post.
With Flask-WTForms I can only work out how to get it to GET/POST to the same URL.
My current code looks like this:
#post_bp.route('/posts/new', methods=['GET', 'POST'])
def show_post_form():
create_post_form = CreatePostForm()
if create_post_form.validate_on_submit():
return 'success'
return render_template('create_post_form.html', form=create_post_form)
However I would like to be able to make it look something more like this, but I just can't seem to work it out:
#post_bp.route('/posts/new', methods=['GET'])
def show_post_form():
create_post_form = CreatePostForm()
return render_template('create_post_form.html', form=create_post_form)
this route only shows the form
the form submits a POST request to /post
<form action="{{url_for('shipment.C_shipment')}}" method="POST" novalidate>
the POST /post route handles the submitted form and if there are errors for example, then it redirects back to GET /posts/new:
#post_bp.route('/post', methods=['POST'])
def create_post():
create_post_form = CreatePostForm()
if create_post_form.validate_on_submit():
return "success!"
if len(create_post_form.errors) != 0:
for error in create_shipment_form.errors:
for msg in create_shipment_form.errors[error]:
flash(msg)
return redirect(url_for('shipment.show_create_shipment_form'))
i guess creating a new CreatePostForm() object here doesn't really work..
Any suggestions?
Creating a new CreatePostForm is correct as it parses the submitted form data for you. This allows you to call validate_on_submit() on the form object.
I don't think you're generating the correct URL for the form action in your HTML snippet. The argument to url_for() should be the desired endpoint (see docs) which should be <post_bp>.create_post. This would be similar to your call
return redirect(url_for('shipment.show_create_shipment_form'))
If this does not fix the issue, please provide both frontend and backend error messages you receive when trying to send the data to /post.

dict returning as string through flask url

Using Flask pymongo for a school project, a site on sharing recipes.
I want to return the dict i use on my home page so that the site knows what recipe it should be showing when clicked.However, in the terminal it seems to return (the way i want) as a dict but when its actually returning a string of the dict so i cant use it.
From App.py:
#app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'GET' or request.form.get('search') == '':
recipes = mongo.db.recipe.find()
return render_template('home.html', recipes=recipes)
From home page: loops through the recipes in mongodb so i can take values like recipe.recipe_name etc.
{% for recipe in recipes %}
<a href="{{url_for('view_recipe', recipe=recipe)}}"
Am i returning the variable back wrong? is there another way to do this?
All help very appreciated!
When getting the request to backend, you have to do json.loads(your_json) which can be used in backend. It converts the string of dict you mentioned to valid json.

Why and how http method of current endpoint affects url_for behavior in Flask?

I am using:
Flask 0.12.2
Python 3.6.1
Consider this, isolated, example of the behavior I am pondering on:
from flask import Flask, url_for, render_template_string
app = Flask(__name__)
#app.route('/hi/', methods=['POST'])
#app.route('/hi/<var>')
def hi(var):
return ''
#app.route('/')
def index():
return render_template_string('''
<html>
<head>
<title>GET or POST</title>
</head>
<body>
<form action="{{ url_for('path') }}">
<input type='SUBMIT' value='GET'>
</form>
<form action="{{ url_for('path') }}" method='POST'>
<input type='SUBMIT' value='POST'>
</form>
</body>
</html>''')
#app.route('/path/', methods=['GET', 'POST'])
def path():
return str(url_for('hi', var='Hello', var2='xyz'))
To make my intentions clear, I will briefly describe what is happening and what I am striving to understand:
/hi/ endpoint has an 'optional' parameter (<var>), which is accepted only via GET request. 'Plain' (i.e. without arguments) /hi/ endpoint can only be accessed via POST method.
/path/ endpoint can be accessed via both GET and POST http methods. And it just returns path for hi generated via url_for('hi', var='Hello', var2='xyz')
Now, I would expect /path/ to return the same string, regardless of which method was used to access it (GET or POST). But it is not the case: for GET it returns /hi/Hello?var2=xyz (as I, actually, would expect), but for POST I am getting /hi/?var=Hello&var2=xyz (which strikes me as odd behavior).
Through trials and errors I was able to find out that adding POST to methods allowed for /hi/<var> fixes the issue (/hi/Hello?var2=xyz is returned by /path/ for both GET and POST), i.e.:
#app.route('/hi/', methods=['POST'])
#app.route('/hi/<var>', methods=['GET', 'POST'])
def hi(var):
...
I hope, someone would be able to explain the following, for me:
Why is this (/path/ returns different values for POST and GET) happening?
Is it possible to avoid this behavior, without allowing POST on /hi/<var>?
I have stumbled upon answers thanks to another question =)
Addressing my own questions:
(not 100% sure about that, would be grateful if someone confirmed that I am correct here) url_for has an optional _method parameter, which is defaulted to the method that was used to return current view. So, /path/ is really returning return str(url_for('hi', var='Hello', var2='xyz', _method='GET') when it was accessed via GET request and return str(url_for('hi', var='Hello', var2='xyz', _method='POST') if it was accessed via POST request. That is why allowing POST on both endpoints (/hi/<var> and /hi/) fixes the problem — if POST is allowed only for /hi/, then return str(url_for('hi', var='Hello', var2='xyz', _method='POST') is checking whether var is known only to /hi/ (and it is, obviously, is not known to it). On the other hand, if POST is allowed on both endpoints, then /hi/ and /hi/<var> are checked for the presence of var and /hi/<var> is correctly selected.
Given the previous point, the fix is pretty obvious now: return str(url_for('hi', var='Hello', var2='xyz', _method='GET') should be substituted for return str(url_for('hi', var='Hello', var2='xyz'), in the original snippet.

Categories