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.
|
||||
- The builtin run method now takes the ``SERVER_NAME`` into account when
|
||||
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
|
||||
-----------
|
||||
|
|
|
@ -33,7 +33,7 @@ class JSONTestCase(FlaskTestCase):
|
|||
app = flask.Flask(__name__)
|
||||
@app.route('/json', methods=['POST'])
|
||||
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()
|
||||
rv = c.post('/json', data='malformed', content_type='application/json')
|
||||
self.assert_equal(rv.status_code, 400)
|
||||
|
@ -43,7 +43,7 @@ class JSONTestCase(FlaskTestCase):
|
|||
app.testing = True
|
||||
@app.route('/')
|
||||
def index():
|
||||
return flask.request.json
|
||||
return flask.request.get_json()
|
||||
|
||||
c = app.test_client()
|
||||
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.route('/add', methods=['POST'])
|
||||
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()
|
||||
rv = c.post('/add', data=flask.json.dumps({'a': 1, 'b': 2}),
|
||||
content_type='application/json')
|
||||
|
@ -127,7 +128,7 @@ class JSONTestCase(FlaskTestCase):
|
|||
app.json_decoder = MyDecoder
|
||||
@app.route('/', methods=['POST'])
|
||||
def index():
|
||||
return flask.json.dumps(flask.request.json['x'])
|
||||
return flask.json.dumps(flask.request.get_json()['x'])
|
||||
c = app.test_client()
|
||||
rv = c.post('/', data=flask.json.dumps({
|
||||
'x': {'_foo': 42}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
"""
|
||||
|
||||
from werkzeug.wrappers import Request as RequestBase, Response as ResponseBase
|
||||
from werkzeug.utils import cached_property
|
||||
from werkzeug.exceptions import BadRequest
|
||||
|
||||
from .debughelpers import attach_enctype_error_multidict
|
||||
|
@ -18,6 +17,16 @@ from . import json
|
|||
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):
|
||||
"""The request object used by default in Flask. Remembers the
|
||||
matched endpoint and view arguments.
|
||||
|
@ -88,24 +97,60 @@ class Request(RequestBase):
|
|||
if self.url_rule and '.' in self.url_rule.endpoint:
|
||||
return self.url_rule.endpoint.rsplit('.', 1)[0]
|
||||
|
||||
@cached_property
|
||||
@property
|
||||
def json(self):
|
||||
"""If the mimetype is `application/json` this will contain the
|
||||
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
|
||||
return self.get_json()
|
||||
|
||||
def get_json(self, force=False, silent=False, cache=True):
|
||||
"""Parses the incoming JSON request data and returns it. If
|
||||
parsing fails the :meth:`on_json_loading_failed` method on the
|
||||
request object will be invoked. By default this function will
|
||||
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:
|
||||
return json.loads(self.data, encoding=request_charset)
|
||||
return json.loads(self.data)
|
||||
rv = json.loads(data, encoding=request_charset)
|
||||
else:
|
||||
rv = json.loads(data)
|
||||
except ValueError as e:
|
||||
return self.on_json_loading_failed(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):
|
||||
"""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
|
||||
implementation just raises a :class:`BadRequest` exception.
|
||||
this method is used by :meth:`get_json` when an error occurred. The
|
||||
default implementation just raises a :class:`BadRequest` exception.
|
||||
|
||||
.. versionchanged:: 0.10
|
||||
Removed buggy previous behavior of generating a random JSON
|
||||
|
|
Loading…
Reference in New Issue