10

FlaskFlask-RESTfulを使用して REST API を構築しています。この API 内で、リソースの一部に他のリソースへの URL 関係が含まれています。

これらのリソースへの POST リクエストを実行すると、着信 URL を解析するために Flask の url_for() 関数の逆が必要であることがわかりました。

たとえば、POST tohttps://www.example.com/buildingsには次の json が含まれる場合があります。

{
  "address": "123 Lyall St",
  ...
  "owner": {
      "href": "https://www.example.com/users/21414512"
  },
  "tenant": {
      "href": "https://www.example.com/users/16324642"
  },
}

次のルートを使用しownerてIDを解析したいと思います。tenant

"https://www.example.com/users/<int:id>"

Flask または Werkzueg 内でこれを行う便利な方法はありますか、それとも自分で URL を解析する必要がありますか? すでに定義されているルートを再利用できるといいですね...

この投稿を見つけましたが、リクエスト以外でそれを行う方法が説明されていないようです。

4

2 に答える 2

10

テストリクエストコンテキストを作成する最も簡単な方法 ( Leon Youngに感謝):

with app.test_request_context(YOUR_URL) as request_ctx:
    url_rule = request_ctx.request.url_rule

しかし、リクエストコンテキストを作成することのすべての意味は次のとおりです。

from flask.testing import make_test_environ_builder

builder = make_test_environ_builder(app, YOUR_URL)
environ = builder.get_environ()
url_adapter = app.url_map.bind_to_environ(environ)
url_rule, view_args = url_adapter.match(return_rule=True)

理由がない場合は、プロトコルとホストを確認して、特別な一致方法を作成できます。

from functools import partial

url_adapter = app.url_map.bind('localhost')
match = partial(url_adapter.match, return_rule=True)

プロトコルとホストなしで使用します。

owner_url_rule, owner_view_args = match('/users/21414512')
tenant_url_rule, tenant_view_args = match('/users/16324642')
于 2013-10-02T08:46:48.067 に答える
4

route_from以下の関数を使用します。

from flask.globals import _app_ctx_stack, _request_ctx_stack
from werkzeug.urls import url_parse

def route_from(url, method = None):
    appctx = _app_ctx_stack.top
    reqctx = _request_ctx_stack.top
    if appctx is None:
        raise RuntimeError('Attempted to match a URL without the '
                           'application context being pushed. This has to be '
                           'executed when application context is available.')

    if reqctx is not None:
        url_adapter = reqctx.url_adapter
    else:
        url_adapter = appctx.url_adapter
        if url_adapter is None:
            raise RuntimeError('Application was not able to create a URL '
                               'adapter for request independent URL matching. '
                               'You might be able to fix this by setting '
                               'the SERVER_NAME config variable.')
    parsed_url = url_parse(url)
    if parsed_url.netloc is not "" and parsed_url.netloc != url_adapter.server_name:
        raise NotFound()
    return url_adapter.match(parsed_url.path, method)

url_forの実装を見て逆に書いてみました。

url引数は、完全な URL にすることも、パス情報部分のみにすることもできます。戻り値は、エンドポイント名とdict引数を含むタプルです。

免責事項:私は広範囲にテストしていません。最終的にはプル リクエストとして送信する予定でしたが、完全にテストして単体テストを作成することはできなかったようです。うまくいかない場合は、お知らせください。

于 2013-10-02T19:28:57.690 に答える