Skip to content
Closed

AI junk #6090

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/views.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ method maps to a method of the class with the same (lowercase) name.
methods defined by the class. It even knows how to handle subclasses
that override or define other methods.

The standard HTTP ``QUERY`` method is also supported by defining a
``query`` method. This is useful for safe, idempotent queries that need
to send a request body.

We can make a generic ``ItemAPI`` class that provides get (detail),
patch (edit), and delete methods for a given model. A ``GroupAPI`` can
provide get (list) and post (create) methods.
Expand Down
8 changes: 8 additions & 0 deletions src/flask/sansio/scaffold.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,14 @@ def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
"""
return self._method_route("PATCH", rule, options)

@setupmethod
def query(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
"""Shortcut for :meth:`route` with ``methods=["QUERY"]``.

.. versionadded:: 3.2
"""
return self._method_route("QUERY", rule, options)

@setupmethod
def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
"""Decorate a view function to register it with the given URL
Expand Down
2 changes: 1 addition & 1 deletion src/flask/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
F = t.TypeVar("F", bound=t.Callable[..., t.Any])

http_method_funcs = frozenset(
["get", "post", "head", "options", "delete", "put", "trace", "patch"]
["get", "post", "head", "options", "delete", "put", "trace", "patch", "query"]
)


Expand Down
10 changes: 7 additions & 3 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,20 @@ def index_put():
assert sorted(rv.allow) == ["GET", "HEAD", "OPTIONS", "POST", "PUT"]


@pytest.mark.parametrize("method", ["get", "post", "put", "delete", "patch"])
@pytest.mark.parametrize("method", ["get", "post", "put", "delete", "patch", "query"])
def test_method_route(app, client, method):
method_route = getattr(app, method)
client_method = getattr(client, method)

@method_route("/")
def hello():
return "Hello"

assert client_method("/").data == b"Hello"
if method == "query":
response = client.open("/", method="QUERY")
else:
response = getattr(client, method)("/")

assert response.data == b"Hello"


def test_method_route_no_methods(app):
Expand Down
11 changes: 11 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ def post(self):
common_test(app)


def test_query_method_view(app, client):
class Index(flask.views.MethodView):
def query(self):
return "QUERY"

app.add_url_rule("/", view_func=Index.as_view("index"))

assert client.open("/", method="QUERY").data == b"QUERY"
assert "QUERY" in app.url_map._rules_by_endpoint["index"][0].methods


def test_view_patching(app):
class Index(flask.views.MethodView):
def get(self):
Expand Down
Loading