add url_for method to app

This commit is contained in:
Ivan Sushkov 2022-05-02 12:29:55 -06:00 committed by David Lord
parent fac630379d
commit 92acd05d9b
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
2 changed files with 46 additions and 37 deletions

View file

@ -23,6 +23,7 @@ from werkzeug.routing import MapAdapter
from werkzeug.routing import RequestRedirect from werkzeug.routing import RequestRedirect
from werkzeug.routing import RoutingException from werkzeug.routing import RoutingException
from werkzeug.routing import Rule from werkzeug.routing import Rule
from werkzeug.urls import url_quote
from werkzeug.utils import redirect as _wz_redirect from werkzeug.utils import redirect as _wz_redirect
from werkzeug.wrappers import Response as BaseResponse from werkzeug.wrappers import Response as BaseResponse
@ -1661,6 +1662,50 @@ class Flask(Scaffold):
return asgiref_async_to_sync(func) return asgiref_async_to_sync(func)
def url_for(
self,
endpoint: str,
external: bool,
url_adapter,
**values: t.Any,
) -> str:
anchor = values.pop("_anchor", None)
method = values.pop("_method", None)
scheme = values.pop("_scheme", None)
self.inject_url_defaults(endpoint, values)
# This is not the best way to deal with this but currently the
# underlying Werkzeug router does not support overriding the scheme on
# a per build call basis.
old_scheme = None
if scheme is not None:
if not external:
raise ValueError("When specifying _scheme, _external must be True")
old_scheme = url_adapter.url_scheme
url_adapter.url_scheme = scheme
try:
try:
rv = url_adapter.build(
endpoint, values, method=method, force_external=external
)
finally:
if old_scheme is not None:
url_adapter.url_scheme = old_scheme
except BuildError as error:
# We need to inject the values again so that the app callback can
# deal with that sort of stuff.
values["_external"] = external
values["_anchor"] = anchor
values["_method"] = method
values["_scheme"] = scheme
return self.handle_url_build_error(error, endpoint, values)
if anchor is not None:
rv += f"#{url_quote(anchor)}"
return rv
def redirect(self, location: str, code: int = 302) -> BaseResponse: def redirect(self, location: str, code: int = 302) -> BaseResponse:
"""Create a redirect response object. """Create a redirect response object.

View file

@ -11,8 +11,6 @@ from threading import RLock
import werkzeug.utils import werkzeug.utils
from werkzeug.exceptions import abort as _wz_abort from werkzeug.exceptions import abort as _wz_abort
from werkzeug.routing import BuildError
from werkzeug.urls import url_quote
from werkzeug.utils import redirect as _wz_redirect from werkzeug.utils import redirect as _wz_redirect
from .globals import _app_ctx_stack from .globals import _app_ctx_stack
@ -307,41 +305,7 @@ def url_for(endpoint: str, **values: t.Any) -> str:
external = values.pop("_external", True) external = values.pop("_external", True)
anchor = values.pop("_anchor", None) return current_app.url_for(endpoint, external, url_adapter, **values)
method = values.pop("_method", None)
scheme = values.pop("_scheme", None)
appctx.app.inject_url_defaults(endpoint, values)
# This is not the best way to deal with this but currently the
# underlying Werkzeug router does not support overriding the scheme on
# a per build call basis.
old_scheme = None
if scheme is not None:
if not external:
raise ValueError("When specifying _scheme, _external must be True")
old_scheme = url_adapter.url_scheme
url_adapter.url_scheme = scheme
try:
try:
rv = url_adapter.build(
endpoint, values, method=method, force_external=external
)
finally:
if old_scheme is not None:
url_adapter.url_scheme = old_scheme
except BuildError as error:
# We need to inject the values again so that the app callback can
# deal with that sort of stuff.
values["_external"] = external
values["_anchor"] = anchor
values["_method"] = method
values["_scheme"] = scheme
return appctx.app.handle_url_build_error(error, endpoint, values)
if anchor is not None:
rv += f"#{url_quote(anchor)}"
return rv
def redirect( def redirect(