如何在Flask请求中获取数据

时间:2012-05-03 15:31:27

标签: python flask

我希望能够将数据发送到我的Flask应用程序。我试过访问request.data但它是一个空字符串。你如何访问请求数据?

@app.route('/', methods=['GET', 'POST'])
def parse_request():
    data = request.data  # data is empty
    # need posted data here

这个问题的答案让我接下来问Get raw POST body in Python Flask regardless of Content-Type header,这是关于获取原始数据而不是解析数据。

21 个答案:

答案 0 :(得分:873)

docs描述请求中可用的属性。在大多数情况下,request.data将为空,因为它被用作后备:

  

request.data包含传入的请求数据作为字符串,以防它带有Flask无法处理的mimetype。

  • request.args:网址查询字符串中的键/值对
  • request.form:正文中的键/值对,来自HTML帖子表单或非JSON编码的JavaScript请求
  • request.files:正文中的文件,Flask与form分开。 HTML表单必须使用enctype=multipart/form-data或文件不会上传。
  • request.values:合并argsform,如果密钥重叠则更喜欢args

所有这些都是MultiDict个实例。您可以使用以下方式访问值:

  • request.form['name']:如果您知道密钥存在,则使用索引
  • request.form.get('name'):如果密钥可能不存在,请使用get
  • request.form.getlist('name'):如果多次发送密钥并且您想要一个值列表,请使用getlistget仅返回第一个值。

答案 1 :(得分:180)

from flask import request
request.data

答案 2 :(得分:147)

简单如下

对于网址查询参数,请使用 request.args

search = request.args.get("search")
page = request.args.get("page")

对于表单输入,请使用 request.form

email = request.form.get('email')
password = request.form.get('password')

对于数据类型application / json ,请使用 request.data

# data in string format and you have to parse into dictionary
data = request.data
dataDict = json.loads(data)

答案 3 :(得分:68)

我举一个 application / json 的完整示例:

from flask import Flask, abort, request 
import json

app = Flask(__name__)


@app.route('/foo', methods=['POST']) 
def foo():
    if not request.json:
        abort(400)
    print request.json
    return json.dumps(request.json)


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

使用Postman发帖请求:

enter image description here

使用 curl 命令:

curl -i -H "Content-Type: application/json" -X POST -d '{"userId":"1", "username": "fizz bizz"}' http://localhost:5000/foo

P.S。 对于URL查询参数示例,您可以在Multiple parameters in in Flask approute

中查看我的答案

答案 4 :(得分:29)

Flask还有另一个JSON快捷方式:

标题:

{Content-Type: application/json}

@app.route("/something", methods=["POST"])
def do_something():
    data = request.get_json()

答案 5 :(得分:22)

如果您想要原始帖子正文而不考虑内容类型,则应使用request.get_data(),因为request.form已转换为werkzeug.ImmutableMultiDict格式。

答案 6 :(得分:9)

@app.route('/', methods=['POST'])
def process_data():
    req_data = request.get_json(force=True) # force=True will make sure this works even if a client does not specify application/json
    language = req_data['language'] # or whatever key you have in your json

    return '''The language value is: {}'''.format(language)

答案 7 :(得分:8)

简单来说,您可以通过以下方式获取数据:

@app.before_request
def before_request():
    g.data = request.get_json() or request.values

现在,g.datawerkzeug.ImmutableMultiDict的一个实例。然后,您可以使用可以处理大部分要求的g.data。例如,您可以像这样使用它:

@app.route("/something", methods=["POST"])
def do_something():
    result = handle(g.data)
    return jsonify(data=result)

当然,您可以使用blueprint代替app ~~

答案 8 :(得分:8)

使用request.form

您可以通过解析request.form["field_name"]对象提供的ImmutableDict来获取所有发布的数据,而不是获取单个表单数据(request.form),如下所示:

烧瓶(路线)

@app.route('/data', methods=['POST'])                                           
def f_data():                                                                   
    if request.method == "POST":
        fields = [k for k in request.form]                                      
        values = [request.form[k] for k in request.form]
        data = dict(zip(fields, values))
    return jsonify(data) 

<强>贝壳

$ curl http://127.0.0.1:5000/data -d "name=ivanleoncz&role=Software Developer"
{
  "name": "ivanleoncz", 
  "role": "Software Developer"
}

有关详细信息,请Gist

答案 9 :(得分:6)

length = request.headers["Content-Length"]
data=request.stream.read()

现在,数据是请求正文

答案 10 :(得分:4)

如果识别出mime类型,则request.datarequest.get_data()都将返回空字符串。

无论如何要获取全部内容,您需要致电request.get_data(as_text=True)

请参见http://flask.pocoo.org/docs/1.0/api/#flask.Request.get_data

答案 11 :(得分:3)

导入请求:

from flask import request

网址查询参数:

name = request.args.get("name")
age = request.args.get("age")

表单输入:

name = request.form.get('name')
age = request.form.get('age')

OR(如果您知道键存在,则使用索引,指定输入字段的名称

name = request.form['name']
age = request.form['age']

JSON 数据(用于内容类型 application/json

data = request.get_json()

答案 12 :(得分:3)

我的问题是相似的。当用户从我的slackbot中单击payload时,我收到了button的POST请求。 Content-Typeapplication/x-www-form-urlencoded。我用的是Flask,Python3。

我尝试了这种解决方案,但没有用

@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)

我的解决方案1是:

from urllib.parse import parse_qs
# Some code
@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():    
    # request.get_data() returned a bytestring
    # parse_qs() returned a dict from a bytestring. This dict has 1 pair
    # I tried payload_dict.keys() to see what keys in the dict and it had one key only
    payload_dict = parse_qs(request.get_data())

    # Get the value of the key from payload_dict
    # Value of the key from payload_dict is an array, length = 1
    payload_dict_value_arr = payload_dict[b'payload']

    # Get data from the index[0] of the array payload_dict_value_arr
    data = payload_dict_value_arr[0]   

    # convert a string (representation of a Dict)) to a Dict
    # Note that if you have single quotes as a part of your keys or values this will
    # fail due to improper character replacement.
    # This solution is only recommended if you have a strong aversion 
    # to the eval solution.
    datajson = json.loads(data)

    # get value of key "channel"
    channel = datajson["channel"]
    print(channel) {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

我的解决方案2,短一点:

@ app.route('/slack/request_handler', methods=['POST'])
def request_handler():
   payload = request.form  # return an ImmutableMultiDict with 1 pair

   a1 = payload['payload']  # get value of key 'payload'

   # Note that if you have single quotes as a part of your keys or values this will
   # fail due to improper character replacement.
   # convert a string (representation of a Dict)) to a Dict
   a2 = json.loads(a1)

   # get value of key "channel"
   channel = a2["channel"] 
   print(channel) # {'id': 'D01ACC2E8S3', 'name': 'directmessage'}

flask.Request.get_dataUnicode in Flask

答案 13 :(得分:3)

这是一种肮脏的技巧,无论如何发送,都可以获取所有请求数据,但是我认真地使用:

def get_request_info():
    args = str(request.args)
    form = str(request.form)
    files = str(request.files)
    maybe_json = request.get_json(silent=True, cache=False)
    if maybe_json:
        thejson = json.dumps(maybe_json)
    else:
        thejson = "no json"
    return # whatever you want 

,然后我只返回连接这些字符串的字符串,或者,如果我觉得不错,我跳过字符串调用/ json转储并合并所有字典。然后可以将其记录下来,并在视图函数中返回,无论如何,无论包含什么内容,您实际上都可以看到整个请求。

答案 14 :(得分:2)

from flask import request

content = request.get_json()
name = content.get('name', '')

如果请求类型为json,则获取数据,您还可以在其中提及默认参数

from flask import request

content = request.form
name = content.get('name', '')

如果请求类型为表格,则获取数据

from flask import request

request.args.get("name", "")

通过GET请求从网址中获取参数

答案 15 :(得分:2)

对于像我这样忘记了HTML的人,请确保您<input>中的<form>具有name=""属性!

from flask import Flask, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    print("Posted data : {}".format(request.form))

    return """
<form method="post">
    <input type="text">
    <input type="text" id="idtxt2">
    <input type="text" name="txt3" id="idtxt3">  
    <input type="submit" Value="Hopla!">
</form>
"""

if __name__ == "__main__":
    app.run()

控制台上的结果:

freezed@machine % python3 run.py
 * Serving Flask app "flaskstuff.views" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 268-634-781
127.0.0.1 - - [20/Aug/2018 16:52:59] "POST / HTTP/1.1" 200 -
Posted data : ImmutableMultiDict([('txt3', 'text 3')])

ImmutableMultiDict([])中没有名称属性 = 没有数据

答案 16 :(得分:1)

向需要我的代码集的任何人

app.py代码

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代码

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代码

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>

enter image description here  图像中给出的代码行是负责将数据从前端烧瓶应用程序发送到数据库的代码行,在我的情况下是postgreSQL db

答案 17 :(得分:0)

尝试request.arg,否则当您从POST调用传递数据或有效载荷时,将内容类型传递为“ application / json”,以便您可以使用request.json或request.data进行访问

答案 18 :(得分:0)

@app.route('/addData', methods=['POST'])
def add_data():
     data_in = mongo.db.Data
     id = request.values.get("id")
     name = request.values.get("name")
     newuser = {'id' : id, 'name' : name}
     if voter.find({'id' : id, 'name' : name}).count() > 0:
            return "Data Exists"
     else:
            data_in.insert(newuser)
            return "Data Added"

答案 19 :(得分:-1)

from flask import Flask, request, jsonify

@app.route('/added', methods=['POST'])
def add():
    data = request.get_json(force=True)
    l = {'name': data['name']}
    lingual.append(l)

    return jsonify({'lang': lingual})

答案 20 :(得分:-2)

request.data

这很好用,但请记住,它以字符串形式出现,并且需要迭代。