kopia lustrzana https://github.com/simonw/datasette
New implementation for RequestParams
- no longer subclasses dict - request.args[key] now returns first item, not all items - removed request.raw_args entirely Closes #774pull/783/head
rodzic
f272cbc65f
commit
81be31322a
|
@ -32,7 +32,7 @@ def json_renderer(args, data, view_name):
|
|||
# Handle the _json= parameter which may modify data["rows"]
|
||||
json_cols = []
|
||||
if "_json" in args:
|
||||
json_cols = args["_json"]
|
||||
json_cols = args.getlist("_json")
|
||||
if json_cols and "rows" in data and "columns" in data:
|
||||
data["rows"] = convert_specific_columns_to_json(
|
||||
data["rows"], data["columns"], json_cols
|
||||
|
|
|
@ -753,17 +753,41 @@ def escape_fts(query):
|
|||
)
|
||||
|
||||
|
||||
class RequestParameters(dict):
|
||||
class RequestParameters:
|
||||
def __init__(self, data):
|
||||
# data is a dictionary of key => [list, of, values]
|
||||
assert isinstance(data, dict), "data should be a dictionary of key => [list]"
|
||||
for key in data:
|
||||
assert isinstance(
|
||||
data[key], list
|
||||
), "data should be a dictionary of key => [list]"
|
||||
self._data = data
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._data
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._data[key][0]
|
||||
|
||||
def keys(self):
|
||||
return self._data.keys()
|
||||
|
||||
def __iter__(self):
|
||||
yield from self._data.keys()
|
||||
|
||||
def __len__(self):
|
||||
return len(self._data)
|
||||
|
||||
def get(self, name, default=None):
|
||||
"Return first value in the list, if available"
|
||||
try:
|
||||
return super().get(name)[0]
|
||||
return self._data.get(name)[0]
|
||||
except (KeyError, TypeError):
|
||||
return default
|
||||
|
||||
def getlist(self, name):
|
||||
"Return full list"
|
||||
return super().get(name) or []
|
||||
return self._data.get(name) or []
|
||||
|
||||
|
||||
class ConnectionProblem(Exception):
|
||||
|
|
|
@ -63,11 +63,6 @@ class Request:
|
|||
def args(self):
|
||||
return RequestParameters(parse_qs(qs=self.query_string))
|
||||
|
||||
@property
|
||||
def raw_args(self):
|
||||
# Deprecated, undocumented - may be removed in Datasette 1.0
|
||||
return {key: value[0] for key, value in self.args.items()}
|
||||
|
||||
async def post_vars(self):
|
||||
body = []
|
||||
body = b""
|
||||
|
|
|
@ -277,11 +277,11 @@ class TableView(RowTableShared):
|
|||
# it can still be queried using ?_col__exact=blah
|
||||
special_args = {}
|
||||
other_args = []
|
||||
for key, value in args.items():
|
||||
for key in args:
|
||||
if key.startswith("_") and "__" not in key:
|
||||
special_args[key] = value[0]
|
||||
special_args[key] = args[key]
|
||||
else:
|
||||
for v in value:
|
||||
for v in args.getlist(key):
|
||||
other_args.append((key, v))
|
||||
|
||||
# Handle ?_filter_column and redirect, if present
|
||||
|
|
|
@ -268,12 +268,16 @@ The object also has one awaitable method:
|
|||
The RequestParameters class
|
||||
---------------------------
|
||||
|
||||
This class, returned by ``request.args``, is a subclass of a Python dictionary that provides methods for working with keys that map to lists of values.
|
||||
This class, returned by ``request.args``, is a dictionary-like object.
|
||||
|
||||
Conider the querystring ``?foo=1&foo=2``. This will produce a ``request.args`` that looks like this::
|
||||
Consider the querystring ``?foo=1&foo=2``. This will produce a ``request.args`` that looks like this::
|
||||
|
||||
RequestParameters({"foo": ["1", "2"]})
|
||||
|
||||
Calling ``request.args.get("foo")`` will return the first value, ``"1"``. If that key is not present it will return ``None`` - or the second argument if you passed one, which will be used as the default.
|
||||
``request.args["foo"]`` returns the first value, ``"1"`` - or raises ``KeyError`` if that key is missing.
|
||||
|
||||
Calling ``request.args.getlist("foo")`` will return the full list, ``["1", "2"]``. If you call it on a missing key it will return ``[]``.
|
||||
``request.args.get("foo")`` returns ``"1"`` - or ``None`` if the key is missing. A second argument can be used to specify a different default value.
|
||||
|
||||
``request.args.getlist("foo")`` returns the full list, ``["1", "2"]``. If you call it on a missing key it will return ``[]``.
|
||||
|
||||
You can use ``if key in request.args`` to check if a key is present. ``for key in request.args`` will iterate through the keys, or you can use ``request.args.keys()`` to get all of the keys.
|
||||
|
|
|
@ -452,8 +452,18 @@ def test_request_args():
|
|||
request = Request.fake("/foo?multi=1&multi=2&single=3")
|
||||
assert "1" == request.args.get("multi")
|
||||
assert "3" == request.args.get("single")
|
||||
assert "1" == request.args["multi"]
|
||||
assert "3" == request.args["single"]
|
||||
assert ["1", "2"] == request.args.getlist("multi")
|
||||
assert [] == request.args.getlist("missing")
|
||||
assert "multi" in request.args
|
||||
assert "single" in request.args
|
||||
assert "missing" not in request.args
|
||||
expected = ["multi", "single"]
|
||||
assert expected == list(request.args.keys())
|
||||
for i, key in enumerate(request.args):
|
||||
assert expected[i] == key
|
||||
assert 2 == len(request.args)
|
||||
with pytest.raises(KeyError):
|
||||
request.args["missing"]
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue