问题
I want to be able to get the data sent to my Flask app. I\'ve tried accessing request.data
but it is an empty string. How do you access request data?
@app.route(\'/\', methods=[\'GET\', \'POST\'])
def parse_request():
data = request.data # data is empty
# need posted data here
The answer to this question led me to ask Get raw POST body in Python Flask regardless of Content-Type header next, which is about getting the raw data rather than the parsed data.
回答1:
The docs describe the attributes available on the request. In most common cases request.data
will be empty because it's used as a fallback:
request.data
Contains the incoming request data as string in case it came with a mimetype Flask does not handle.
- request.args: the key/value pairs in the URL query string
- request.form: the key/value pairs in the body, from a HTML post form, or JavaScript request that isn't JSON encoded
- request.files: the files in the body, which Flask keeps separate from
form
. HTML forms must useenctype=multipart/form-data
or files will not be uploaded. - request.values: combined
args
andform
, preferringargs
if keys overlap - request.json: parsed JSON data. The request must have the
application/json
content type, or use request.get_json(force=True) to ignore the content type.
All of these are MultiDict instances (except for json
). You can access values using:
request.form['name']
: use indexing if you know the key existsrequest.form.get('name')
: useget
if the key might not existrequest.form.getlist('name')
: usegetlist
if the key is sent multiple times and you want a list of values.get
only returns the first value.
回答2:
To get the raw data, use request.data. This only works if it couldn't be parsed as form data, otherwise it will be empty and request.form
will have the parsed data.
from flask import request
request.data
回答3:
For URL query parameters, use request.args
.
search = request.args.get("search")
page = request.args.get("page")
For posted form input, use request.form
.
email = request.form.get('email')
password = request.form.get('password')
For JSON posted with content type application/json
, use request.get_json().
data = request.get_json()
回答4:
Here's an example of parsing posted JSON data and echoing it back.
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/foo', methods=['POST'])
def foo():
data = request.json
return jsonify(data)
To post JSON with curl:
curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo
Or to use Postman:
回答5:
If you post JSON with content type application/json
, use request.get_json()
to get it in Flask. If the content type is not correct, None
is returned. If the data is not JSON, an error is raised.
@app.route("/something", methods=["POST"])
def do_something():
data = request.get_json()
回答6:
To get the raw post body regardless of the content type, use request.get_data()
. If you use request.data
, it calls request.get_data(parse_form_data=True)
, which will populate the request.form
MultiDict
and leave data
empty.
回答7:
To get request.form
as a normal dict with all the values for each key, use request.form.to_dict(flat=False)
. This might be useful to store the data with something that doesn't understand MultiDict
.
To return JSON data for an API, pass it to jsonify
.
This example returns form data as JSON data.
@app.route('/form_to_json', methods=['POST'])
def form_to_json():
data = request.form.to_dict(flat=False)
return jsonify(data)
Here's an example of POST form data with curl, returning as JSON:
$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
"name": "ivanleoncz",
"role": "Software Developer"
}
回答8:
To get JSON posted without the application/json
content type, use request.get_json(force=True)
.
@app.route('/process_data', methods=['POST'])
def process_data():
req_data = request.get_json(force=True)
language = req_data['language']
return 'The language value is: {}'.format(language)
回答9:
To parse JSON, use request.get_json()
.
@app.route("/something", methods=["POST"])
def do_something():
result = handle(request.get_json())
return jsonify(data=result)
回答10:
The raw data is passed in to the Flask application from the WSGI server as request.stream
. The length of the stream is in the Content-Length
header.
length = request.headers["Content-Length"]
data = request.stream.read(length)
It is usually safer to use request.get_data()
instead.
回答11:
Use request.get_json()
to get posted JSON data.
data = request.get_json()
name = data.get('name', '')
Use request.form
to get data when submitting a form with the POST method.
name = request.form.get('name', '')
Use request.args
to get data passed in the query string of the URL, like when submitting a form with the GET method.
request.args.get("name", "")
request.form
etc. are dict-like, use the get
method to get a value with a default if it wasn't passed.
回答12:
If the content type is recognized as form data, request.data
will parse that into request.form
and return an empty string.
To get the raw data regardless of content type, call request.get_data(). request.data
calls get_data(parse_form_data=True)
, while the default is False
if you call it directly.
回答13:
If the body is recognized as form data, it will be in request.form
. If it's JSON, it will be in request.get_json()
. Otherwise the raw data will be in request.data
. If you're not sure how data will be submitted, you can use an or
chain to get the first one with data.
def get_request_data():
return (
request.args
or request.form
or request.get_json(force=True, silent=True)
or request.data
)
request.args
contains args parsed from the query string, regardless of what was in the body, so you would remove that from get_request_data()
if both it and a body should data at the same time.
回答14:
To post JSON with jQuery in JavaScript, use JSON.stringify
to dump the data, and set the content type to application/json
.
var value_data = [1, 2, 3, 4];
$.ajax({
type: 'POST',
url: '/process',
data: JSON.stringify(value_data),
contentType: 'application/json',
success: function (response_data) {
alert("success");
}
});
Parse it in Flask with request.get_json()
.
data = request.get_json()
Or if you send the data as a simple dictionary without jsonifying it, then
data = request.data
回答15:
When posting form data with an HTML form, be sure the input
tags have name
attributes, otherwise they won't be present in request.form
.
@app.route('/', methods=['GET', 'POST'])
def index():
print(request.form)
return """
<form method="post">
<input type="text">
<input type="text" id="txt2">
<input type="text" name="txt3" id="txt3">
<input type="submit">
</form>
"""
ImmutableMultiDict([('txt3', 'text 3')])
Only the txt3
input had a name
, so it's the only key present in request.form
.
回答16:
To anyone who needs my code set
app.py code
from flask import Flask, render_template, request
from models import db, User
app = Flask(__name__)
POSTGRES = {
'user': 'postgres',
'pw': 'silverTip',
'db': 'flaskmovie',
'host': 'localhost',
'port': '5432',
}
app.config['DEBUG'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://%(user)s:\
%(pw)s@%(host)s:%(port)s/%(db)s' % POSTGRES
db.init_app(app)
@app.route('/')
def index():
return render_template('addU.html')
@app.route('/postU', methods=['POST', 'GET'])
def postU():
if request.form:
user = User(id=request.form.get("id"), username=request.form.get("username"),email=request.form.get("email"))
db.session.add(user)
db.session.commit()
return render_template('addU.html')
if __name__ == '__main__':
app.run()
models.py code
from flask_sqlalchemy import SQLAlchemy
import datetime
db = SQLAlchemy()
class BaseModel(db.Model):
"""Base data model for all objects"""
__abstract__ = True
def __init__(self, *args):
super().__init__(*args)
def __repr__(self):
"""Define a base way to print models"""
return '%s(%s)' % (self.__class__.__name__, {
column: value
for column, value in self._to_dict().items()
})
def json(self):
"""
Define a base way to jsonify models, dealing with datetime objects
"""
return {
column: value if not isinstance(value, datetime.date) else value.strftime('%Y-%m-%d')
for column, value in self._to_dict().items()
}
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(80), unique=True)
def __init__(self,id, username, email):
self.id = id
self.username = username
self.email = email
manage.py code
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app, db
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
addU.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<form method="post" action="/postU">
<label>id:</label>
<input id="id" type="text" name="id">
<label>Username:</label>
<input type="text" name="username">
<label>Email:</label>
<input type="text" name="email">
<input type="submit" />
</form>
</body>
</html>
The code lines given in the image are the code lines responsible for sending data from front end flask app to the database, in my case postgreSQL db
来源:https://stackoverflow.com/questions/10434599/get-the-data-received-in-a-flask-request