mirror of https://github.com/pallets/flask.git
Added request.get_json().
This commit is contained in:
parent
335cbe01ce
commit
964174931d
2
CHANGES
2
CHANGES
|
@ -77,6 +77,8 @@ Release date to be decided.
|
||||||
- Added `appcontext_pushed` and `appcontext_popped` signals.
|
- Added `appcontext_pushed` and `appcontext_popped` signals.
|
||||||
- The builtin run method now takes the ``SERVER_NAME`` into account when
|
- The builtin run method now takes the ``SERVER_NAME`` into account when
|
||||||
picking the default port to run on.
|
picking the default port to run on.
|
||||||
|
- Added `flask.request.get_json()` as a replacement for the old
|
||||||
|
`flask.request.json` property.
|
||||||
|
|
||||||
Version 0.9
|
Version 0.9
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -33,7 +33,7 @@ class JSONTestCase(FlaskTestCase):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
@app.route('/json', methods=['POST'])
|
@app.route('/json', methods=['POST'])
|
||||||
def return_json():
|
def return_json():
|
||||||
return flask.jsonify(foo=text_type(flask.request.json))
|
return flask.jsonify(foo=text_type(flask.request.get_json()))
|
||||||
c = app.test_client()
|
c = app.test_client()
|
||||||
rv = c.post('/json', data='malformed', content_type='application/json')
|
rv = c.post('/json', data='malformed', content_type='application/json')
|
||||||
self.assert_equal(rv.status_code, 400)
|
self.assert_equal(rv.status_code, 400)
|
||||||
|
@ -43,7 +43,7 @@ class JSONTestCase(FlaskTestCase):
|
||||||
app.testing = True
|
app.testing = True
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
def index():
|
def index():
|
||||||
return flask.request.json
|
return flask.request.get_json()
|
||||||
|
|
||||||
c = app.test_client()
|
c = app.test_client()
|
||||||
resp = c.get('/', data=u'"Hällo Wörld"'.encode('iso-8859-15'),
|
resp = c.get('/', data=u'"Hällo Wörld"'.encode('iso-8859-15'),
|
||||||
|
@ -82,7 +82,8 @@ class JSONTestCase(FlaskTestCase):
|
||||||
app = flask.Flask(__name__)
|
app = flask.Flask(__name__)
|
||||||
@app.route('/add', methods=['POST'])
|
@app.route('/add', methods=['POST'])
|
||||||
def add():
|
def add():
|
||||||
return text_type(flask.request.json['a'] + flask.request.json['b'])
|
json = flask.request.get_json()
|
||||||
|
return text_type(json['a'] + json['b'])
|
||||||
c = app.test_client()
|
c = app.test_client()
|
||||||
rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}),
|
rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}),
|
||||||
content_type='application/json')
|
content_type='application/json')
|
||||||
|
@ -127,7 +128,7 @@ class JSONTestCase(FlaskTestCase):
|
||||||
app.json_decoder = MyDecoder
|
app.json_decoder = MyDecoder
|
||||||
@app.route('/', methods=['POST'])
|
@app.route('/', methods=['POST'])
|
||||||
def index():
|
def index():
|
||||||
return flask.json.dumps(flask.request.json['x'])
|
return flask.json.dumps(flask.request.get_json()['x'])
|
||||||
c = app.test_client()
|
c = app.test_client()
|
||||||
rv = c.post('/', data=flask.json.dumps({
|
rv = c.post('/', data=flask.json.dumps({
|
||||||
'x': {'_foo': 42}
|
'x': {'_foo': 42}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from werkzeug.wrappers import Request as RequestBase, Response as ResponseBase
|
from werkzeug.wrappers import Request as RequestBase, Response as ResponseBase
|
||||||
from werkzeug.utils import cached_property
|
|
||||||
from werkzeug.exceptions import BadRequest
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
from .debughelpers import attach_enctype_error_multidict
|
from .debughelpers import attach_enctype_error_multidict
|
||||||
|
@ -18,6 +17,16 @@ from . import json
|
||||||
from .globals import _request_ctx_stack
|
from .globals import _request_ctx_stack
|
||||||
|
|
||||||
|
|
||||||
|
_missing = object()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_data(req, cache):
|
||||||
|
getter = getattr(req, 'get_data', None)
|
||||||
|
if getter is not None:
|
||||||
|
return getter(cache=cache)
|
||||||
|
return req.data
|
||||||
|
|
||||||
|
|
||||||
class Request(RequestBase):
|
class Request(RequestBase):
|
||||||
"""The request object used by default in Flask. Remembers the
|
"""The request object used by default in Flask. Remembers the
|
||||||
matched endpoint and view arguments.
|
matched endpoint and view arguments.
|
||||||
|
@ -88,24 +97,60 @@ class Request(RequestBase):
|
||||||
if self.url_rule and '.' in self.url_rule.endpoint:
|
if self.url_rule and '.' in self.url_rule.endpoint:
|
||||||
return self.url_rule.endpoint.rsplit('.', 1)[0]
|
return self.url_rule.endpoint.rsplit('.', 1)[0]
|
||||||
|
|
||||||
@cached_property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
"""If the mimetype is `application/json` this will contain the
|
"""If the mimetype is `application/json` this will contain the
|
||||||
parsed JSON data. Otherwise this will be `None`.
|
parsed JSON data. Otherwise this will be `None`.
|
||||||
|
|
||||||
|
The :meth:`get_json` method should be used instead.
|
||||||
"""
|
"""
|
||||||
if self.mimetype == 'application/json':
|
# XXX: deprecate property
|
||||||
request_charset = self.mimetype_params.get('charset')
|
return self.get_json()
|
||||||
try:
|
|
||||||
if request_charset is not None:
|
def get_json(self, force=False, silent=False, cache=True):
|
||||||
return json.loads(self.data, encoding=request_charset)
|
"""Parses the incoming JSON request data and returns it. If
|
||||||
return json.loads(self.data)
|
parsing fails the :meth:`on_json_loading_failed` method on the
|
||||||
except ValueError as e:
|
request object will be invoked. By default this function will
|
||||||
return self.on_json_loading_failed(e)
|
only load the json data if the mimetype is ``application/json``
|
||||||
|
but this can be overriden by the `force` parameter.
|
||||||
|
|
||||||
|
:param force: if set to `True` the mimetype is ignored.
|
||||||
|
:param silent: if set to `False` this method will fail silently
|
||||||
|
and return `False`.
|
||||||
|
:param cache: if set to `True` the parsed JSON data is remembered
|
||||||
|
on the request.
|
||||||
|
"""
|
||||||
|
rv = getattr(self, '_cached_json', _missing)
|
||||||
|
if rv is not _missing:
|
||||||
|
return rv
|
||||||
|
|
||||||
|
if self.mimetype != 'application/json' and not force:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# We accept a request charset against the specification as
|
||||||
|
# certain clients have been using this in the past. This
|
||||||
|
# fits our general approach of being nice in what we accept
|
||||||
|
# and strict in what we send out.
|
||||||
|
request_charset = self.mimetype_params.get('charset')
|
||||||
|
try:
|
||||||
|
data = _get_data(self, cache)
|
||||||
|
if request_charset is not None:
|
||||||
|
rv = json.loads(data, encoding=request_charset)
|
||||||
|
else:
|
||||||
|
rv = json.loads(data)
|
||||||
|
except ValueError as e:
|
||||||
|
if silent:
|
||||||
|
rv = None
|
||||||
|
else:
|
||||||
|
rv = self.on_json_loading_failed(e)
|
||||||
|
if cache:
|
||||||
|
self._cached_json = rv
|
||||||
|
return rv
|
||||||
|
|
||||||
def on_json_loading_failed(self, e):
|
def on_json_loading_failed(self, e):
|
||||||
"""Called if decoding of the JSON data failed. The return value of
|
"""Called if decoding of the JSON data failed. The return value of
|
||||||
this method is used by :attr:`json` when an error occurred. The default
|
this method is used by :meth:`get_json` when an error occurred. The
|
||||||
implementation just raises a :class:`BadRequest` exception.
|
default implementation just raises a :class:`BadRequest` exception.
|
||||||
|
|
||||||
.. versionchanged:: 0.10
|
.. versionchanged:: 0.10
|
||||||
Removed buggy previous behavior of generating a random JSON
|
Removed buggy previous behavior of generating a random JSON
|
||||||
|
|
Loading…
Reference in New Issue