From 491ea32803cb05fb8fc4dfb81ec6c96f94529eb0 Mon Sep 17 00:00:00 2001 From: laggardkernel Date: Tue, 1 Jun 2021 13:43:28 +0800 Subject: [PATCH 01/87] Optimize loop in Flask._find_error_handler() --- src/flask/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flask/app.py b/src/flask/app.py index cacb40a5b..f66564581 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -1276,7 +1276,7 @@ def _find_error_handler(self, e: Exception) -> t.Optional[ErrorHandlerCallable]: """ exc_class, code = self._get_exc_class_and_code(type(e)) - for c in [code, None]: + for c in [code, None] if code is not None else [None]: for name in chain(request.blueprints, [None]): handler_map = self.error_handler_spec[name][c] From 270eb2df2a1606383f50ff079a32240966b43fbc Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Fri, 28 May 2021 00:01:48 +0100 Subject: [PATCH 02/87] Support View and MethodView instances with async handlers --- CHANGES.rst | 1 + docs/async-await.rst | 6 ++++++ src/flask/views.py | 5 +++-- tests/test_async.py | 25 ++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 7920e5abc..be2639705 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,7 @@ Unreleased decorators. :issue:`4104` - Fixed the issue where typing requires template global decorators to accept functions with no arguments. :issue:`4098` +- Support View and MethodView instances with async handlers. :issue:`4112` Version 2.0.1 diff --git a/docs/async-await.rst b/docs/async-await.rst index ad7cbf384..71e5f4522 100644 --- a/docs/async-await.rst +++ b/docs/async-await.rst @@ -18,6 +18,12 @@ defined with ``async def`` and use ``await``. data = await async_db_query(...) return jsonify(data) +Pluggable class-based views also support handlers that are implemented as +coroutines. This applies to the :meth:`~flask.views.View.dispatch_request` +method in views that inherit from the :class:`flask.views.View` class, as +well as all the HTTP method handlers in views that inherit from the +:class:`flask.views.MethodView` class. + .. admonition:: Using ``async`` on Windows on Python 3.8 Python 3.8 has a bug related to asyncio on Windows. If you encounter diff --git a/src/flask/views.py b/src/flask/views.py index 339ffa18f..1bd5c68b0 100644 --- a/src/flask/views.py +++ b/src/flask/views.py @@ -1,5 +1,6 @@ import typing as t +from .globals import current_app from .globals import request from .typing import ResponseReturnValue @@ -80,7 +81,7 @@ def as_view( def view(*args: t.Any, **kwargs: t.Any) -> ResponseReturnValue: self = view.view_class(*class_args, **class_kwargs) # type: ignore - return self.dispatch_request(*args, **kwargs) + return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs) if cls.decorators: view.__name__ = name @@ -154,4 +155,4 @@ def dispatch_request(self, *args: t.Any, **kwargs: t.Any) -> ResponseReturnValue meth = getattr(self, "get", None) assert meth is not None, f"Unimplemented method {request.method!r}" - return meth(*args, **kwargs) + return current_app.ensure_sync(meth)(*args, **kwargs) diff --git a/tests/test_async.py b/tests/test_async.py index 26a91118c..344e9fe6f 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -6,6 +6,8 @@ from flask import Blueprint from flask import Flask from flask import request +from flask.views import MethodView +from flask.views import View pytest.importorskip("asgiref") @@ -18,6 +20,24 @@ class BlueprintError(Exception): pass +class AsyncView(View): + methods = ["GET", "POST"] + + async def dispatch_request(self): + await asyncio.sleep(0) + return request.method + + +class AsyncMethodView(MethodView): + async def get(self): + await asyncio.sleep(0) + return 'GET' + + async def post(self): + await asyncio.sleep(0) + return 'POST' + + @pytest.fixture(name="async_app") def _async_app(): app = Flask(__name__) @@ -53,11 +73,14 @@ async def bp_error(): app.register_blueprint(blueprint, url_prefix="/bp") + app.add_url_rule('/view', view_func=AsyncView.as_view('view')) + app.add_url_rule('/methodview', view_func=AsyncMethodView.as_view('methodview')) + return app @pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7") -@pytest.mark.parametrize("path", ["/", "/home", "/bp/"]) +@pytest.mark.parametrize("path", ["/", "/home", "/bp/", "/view", "/methodview"]) def test_async_route(path, async_app): test_client = async_app.test_client() response = test_client.get(path) From 5205cd4ea979f6c322e4e6a256a72e7808592818 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Jun 2021 17:56:33 +0000 Subject: [PATCH 03/87] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_async.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_async.py b/tests/test_async.py index 344e9fe6f..8276c4a89 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -31,11 +31,11 @@ async def dispatch_request(self): class AsyncMethodView(MethodView): async def get(self): await asyncio.sleep(0) - return 'GET' + return "GET" async def post(self): await asyncio.sleep(0) - return 'POST' + return "POST" @pytest.fixture(name="async_app") @@ -73,8 +73,8 @@ async def bp_error(): app.register_blueprint(blueprint, url_prefix="/bp") - app.add_url_rule('/view', view_func=AsyncView.as_view('view')) - app.add_url_rule('/methodview', view_func=AsyncMethodView.as_view('methodview')) + app.add_url_rule("/view", view_func=AsyncView.as_view("view")) + app.add_url_rule("/methodview", view_func=AsyncMethodView.as_view("methodview")) return app From 6a4e7e948d7e5bd5b2b76c1b7f1a0392644bee1e Mon Sep 17 00:00:00 2001 From: Pascal Corpet Date: Mon, 31 May 2021 12:28:44 +0200 Subject: [PATCH 04/87] improve typing for `app.errorhandler` decorator --- CHANGES.rst | 1 + src/flask/app.py | 6 ++++-- src/flask/blueprints.py | 6 ++++-- src/flask/scaffold.py | 27 +++++++++++++++++++-------- src/flask/typing.py | 11 ++++++++++- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index be2639705..d8dd974f4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -11,6 +11,7 @@ Unreleased - Fixed the issue where typing requires template global decorators to accept functions with no arguments. :issue:`4098` - Support View and MethodView instances with async handlers. :issue:`4112` +- Enhance typing of ``app.errorhandler`` decorator. :issue:`4095` Version 2.0.1 diff --git a/src/flask/app.py b/src/flask/app.py index f66564581..22cc9abc5 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -61,7 +61,6 @@ from .typing import AfterRequestCallable from .typing import BeforeFirstRequestCallable from .typing import BeforeRequestCallable -from .typing import ErrorHandlerCallable from .typing import ResponseReturnValue from .typing import TeardownCallable from .typing import TemplateContextProcessorCallable @@ -78,6 +77,7 @@ from .blueprints import Blueprint from .testing import FlaskClient from .testing import FlaskCliRunner + from .typing import ErrorHandlerCallable if sys.version_info >= (3, 8): iscoroutinefunction = inspect.iscoroutinefunction @@ -1268,7 +1268,9 @@ def shell_context_processor(self, f: t.Callable) -> t.Callable: self.shell_context_processors.append(f) return f - def _find_error_handler(self, e: Exception) -> t.Optional[ErrorHandlerCallable]: + def _find_error_handler( + self, e: Exception + ) -> t.Optional["ErrorHandlerCallable[Exception]"]: """Return a registered error handler for an exception in this order: blueprint handler for a specific code, app handler for a specific code, blueprint handler for an exception class, app handler for an exception diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py index 883fc2fff..8241420be 100644 --- a/src/flask/blueprints.py +++ b/src/flask/blueprints.py @@ -8,7 +8,6 @@ from .typing import AfterRequestCallable from .typing import BeforeFirstRequestCallable from .typing import BeforeRequestCallable -from .typing import ErrorHandlerCallable from .typing import TeardownCallable from .typing import TemplateContextProcessorCallable from .typing import TemplateFilterCallable @@ -19,6 +18,7 @@ if t.TYPE_CHECKING: from .app import Flask + from .typing import ErrorHandlerCallable DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] @@ -581,7 +581,9 @@ def app_errorhandler(self, code: t.Union[t.Type[Exception], int]) -> t.Callable: handler is used for all requests, even if outside of the blueprint. """ - def decorator(f: ErrorHandlerCallable) -> ErrorHandlerCallable: + def decorator( + f: "ErrorHandlerCallable[Exception]", + ) -> "ErrorHandlerCallable[Exception]": self.record_once(lambda s: s.app.errorhandler(code)(f)) return f diff --git a/src/flask/scaffold.py b/src/flask/scaffold.py index 239bc46a4..e80e1915c 100644 --- a/src/flask/scaffold.py +++ b/src/flask/scaffold.py @@ -21,7 +21,7 @@ from .typing import AfterRequestCallable from .typing import AppOrBlueprintKey from .typing import BeforeRequestCallable -from .typing import ErrorHandlerCallable +from .typing import GenericException from .typing import TeardownCallable from .typing import TemplateContextProcessorCallable from .typing import URLDefaultCallable @@ -29,6 +29,7 @@ if t.TYPE_CHECKING: from .wrappers import Response + from .typing import ErrorHandlerCallable # a singleton sentinel value for parameter defaults _sentinel = object() @@ -144,7 +145,10 @@ def __init__( #: directly and its format may change at any time. self.error_handler_spec: t.Dict[ AppOrBlueprintKey, - t.Dict[t.Optional[int], t.Dict[t.Type[Exception], ErrorHandlerCallable]], + t.Dict[ + t.Optional[int], + t.Dict[t.Type[Exception], "ErrorHandlerCallable[Exception]"], + ], ] = defaultdict(lambda: defaultdict(dict)) #: A data structure of functions to call at the beginning of @@ -643,8 +647,11 @@ def url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable: @setupmethod def errorhandler( - self, code_or_exception: t.Union[t.Type[Exception], int] - ) -> t.Callable[[ErrorHandlerCallable], ErrorHandlerCallable]: + self, code_or_exception: t.Union[t.Type[GenericException], int] + ) -> t.Callable[ + ["ErrorHandlerCallable[GenericException]"], + "ErrorHandlerCallable[GenericException]", + ]: """Register a function to handle errors by code or exception class. A decorator that is used to register a function given an @@ -674,7 +681,9 @@ def special_exception_handler(error): an arbitrary exception """ - def decorator(f: ErrorHandlerCallable) -> ErrorHandlerCallable: + def decorator( + f: "ErrorHandlerCallable[GenericException]", + ) -> "ErrorHandlerCallable[GenericException]": self.register_error_handler(code_or_exception, f) return f @@ -683,8 +692,8 @@ def decorator(f: ErrorHandlerCallable) -> ErrorHandlerCallable: @setupmethod def register_error_handler( self, - code_or_exception: t.Union[t.Type[Exception], int], - f: ErrorHandlerCallable, + code_or_exception: t.Union[t.Type[GenericException], int], + f: "ErrorHandlerCallable[GenericException]", ) -> None: """Alternative error attach function to the :meth:`errorhandler` decorator that is more straightforward to use for non decorator @@ -708,7 +717,9 @@ def register_error_handler( " instead." ) - self.error_handler_spec[None][code][exc_class] = f + self.error_handler_spec[None][code][exc_class] = t.cast( + "ErrorHandlerCallable[Exception]", f + ) @staticmethod def _get_exc_class_and_code( diff --git a/src/flask/typing.py b/src/flask/typing.py index b1a6cbdcf..f1c846702 100644 --- a/src/flask/typing.py +++ b/src/flask/typing.py @@ -33,11 +33,12 @@ "WSGIApplication", ] +GenericException = t.TypeVar("GenericException", bound=Exception, contravariant=True) + AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named AfterRequestCallable = t.Callable[["Response"], "Response"] BeforeFirstRequestCallable = t.Callable[[], None] BeforeRequestCallable = t.Callable[[], t.Optional[ResponseReturnValue]] -ErrorHandlerCallable = t.Callable[[Exception], ResponseReturnValue] TeardownCallable = t.Callable[[t.Optional[BaseException]], None] TemplateContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]] TemplateFilterCallable = t.Callable[..., t.Any] @@ -45,3 +46,11 @@ TemplateTestCallable = t.Callable[..., bool] URLDefaultCallable = t.Callable[[str, dict], None] URLValuePreprocessorCallable = t.Callable[[t.Optional[str], t.Optional[dict]], None] + + +if t.TYPE_CHECKING: + import typing_extensions as te + + class ErrorHandlerCallable(te.Protocol[GenericException]): + def __call__(self, error: GenericException) -> ResponseReturnValue: + ... From 63893a427bd022d192febadad0b31ae06fa80776 Mon Sep 17 00:00:00 2001 From: pgjones Date: Sun, 6 Jun 2021 11:09:03 +0100 Subject: [PATCH 05/87] Improve the changelog entry The fix to the teardown_request also applies to all teardown_* methods. --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index d8dd974f4..c27b623f6 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Version 2.0.2 Unreleased -- Fix type annotation for ``teardown_request``. :issue:`4093` +- Fix type annotation for ``teardown_*`` methods. :issue:`4093` - Fix type annotation for ``before_request`` and ``before_app_request`` decorators. :issue:`4104` - Fixed the issue where typing requires template global From 92bed6619459da93f79e85ec674b24cb6fa322f6 Mon Sep 17 00:00:00 2001 From: Hugo Montenegro Date: Tue, 8 Jun 2021 19:01:07 +0200 Subject: [PATCH 06/87] Update celery.rst small typo --- docs/patterns/celery.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/patterns/celery.rst b/docs/patterns/celery.rst index e1f6847e1..38a9a0252 100644 --- a/docs/patterns/celery.rst +++ b/docs/patterns/celery.rst @@ -64,7 +64,7 @@ An example task Let's write a task that adds two numbers together and returns the result. We configure Celery's broker and backend to use Redis, create a ``celery`` -application using the factor from above, and then use it to define the task. :: +application using the factory from above, and then use it to define the task. :: from flask import Flask From 34027d8d876c140f84e18d6b56c0aecc5481874c Mon Sep 17 00:00:00 2001 From: Grey Li Date: Mon, 14 Jun 2021 14:20:04 +0800 Subject: [PATCH 07/87] Improve the contributing guide --- CONTRIBUTING.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3a9177a46..a3c8b8512 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -12,14 +12,16 @@ to address bugs and feature requests in Flask itself. Use one of the following resources for questions about using Flask or issues with your own code: -- The ``#get-help`` channel on our Discord chat: +- The ``#questions`` channel on our Discord chat: https://discord.gg/pallets - The mailing list flask@python.org for long term discussion or larger issues. - Ask on `Stack Overflow`_. Search with Google first using: ``site:stackoverflow.com flask {search term, exception message, etc.}`` +- Ask on our `GitHub Discussions`_. .. _Stack Overflow: https://stackoverflow.com/questions/tagged/flask?tab=Frequent +.. _GitHub Discussions: https://github.com/pallets/flask/discussions Reporting issues @@ -92,7 +94,7 @@ First time setup .. code-block:: text - git remote add fork https://github.com/{username}/flask + $ git remote add fork https://github.com/{username}/flask - Create a virtualenv. From a44c7228600044f530856a33c7da147c528644ff Mon Sep 17 00:00:00 2001 From: pgjones Date: Sat, 5 Jun 2021 16:08:51 +0100 Subject: [PATCH 08/87] Fix registering a blueprint twice with differing names Previously the blueprint recorded aspects (before request, after request etc) would only be added to the app if it was the first registration of the blueprint instance. However only the record-once aspects (app-before requests, app-after request) should be added once on registration of the instance, whereas everything else should be added on every unique name registration. This ensures that these trigger under the new name as well as the old. --- CHANGES.rst | 1 + src/flask/blueprints.py | 8 +++++--- tests/test_blueprints.py | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c27b623f6..bdfa9f010 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,7 @@ Unreleased decorators to accept functions with no arguments. :issue:`4098` - Support View and MethodView instances with async handlers. :issue:`4112` - Enhance typing of ``app.errorhandler`` decorator. :issue:`4095` +- Fix registering a blueprint twice with differing names. :issue:`4124` Version 2.0.1 diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py index 8241420be..c8ce67a41 100644 --- a/src/flask/blueprints.py +++ b/src/flask/blueprints.py @@ -293,7 +293,6 @@ def register(self, app: "Flask", options: dict) -> None: Registering the same blueprint with the same name multiple times is deprecated and will become an error in Flask 2.1. """ - first_registration = not any(bp is self for bp in app.blueprints.values()) name_prefix = options.get("name_prefix", "") self_name = options.get("name", self.name) name = f"{name_prefix}.{self_name}".lstrip(".") @@ -318,9 +317,12 @@ def register(self, app: "Flask", options: dict) -> None: stacklevel=4, ) + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + app.blueprints[name] = self self._got_registered_once = True - state = self.make_setup_state(app, options, first_registration) + state = self.make_setup_state(app, options, first_bp_registration) if self.has_static_folder: state.add_url_rule( @@ -330,7 +332,7 @@ def register(self, app: "Flask", options: dict) -> None: ) # Merge blueprint data into parent. - if first_registration: + if first_bp_registration or first_name_registration: def extend(bp_dict, parent_dict): for key, values in bp_dict.items(): diff --git a/tests/test_blueprints.py b/tests/test_blueprints.py index 088ad7793..a124c612e 100644 --- a/tests/test_blueprints.py +++ b/tests/test_blueprints.py @@ -899,6 +899,14 @@ def test_blueprint_renaming(app, client) -> None: def index(): return flask.request.endpoint + @bp.get("/error") + def error(): + flask.abort(403) + + @bp.errorhandler(403) + def forbidden(_: Exception): + return "Error", 403 + @bp2.get("/") def index2(): return flask.request.endpoint @@ -911,3 +919,5 @@ def index2(): assert client.get("/b/").data == b"alt.index" assert client.get("/a/a/").data == b"bp.sub.index2" assert client.get("/b/a/").data == b"alt.sub.index2" + assert client.get("/a/error").data == b"Error" + assert client.get("/b/error").data == b"Error" From f353d126d199071c7933e2f62409e5532333bec5 Mon Sep 17 00:00:00 2001 From: Frank Yu <1032897296@qq.com> Date: Fri, 18 Jun 2021 10:10:29 +0800 Subject: [PATCH 09/87] Update docs of rendering templates (#4153) * Update docs of rendering templates * Improve the grammar Co-authored-by: Grey Li --- docs/quickstart.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 5cd59f414..b5071ab05 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -444,9 +444,9 @@ Here is an example template:

Hello, World!

{% endif %} -Inside templates you also have access to the :class:`~flask.request`, -:class:`~flask.session` and :class:`~flask.g` [#]_ objects -as well as the :func:`~flask.get_flashed_messages` function. +Inside templates you also have access to the :data:`~flask.Flask.config`, +:class:`~flask.request`, :class:`~flask.session` and :class:`~flask.g` [#]_ objects +as well as the :func:`~flask.url_for` and :func:`~flask.get_flashed_messages` functions. Templates are especially useful if inheritance is used. If you want to know how that works, see :doc:`patterns/templateinheritance`. Basically From 5fa7d2efe757e028a734d3dc56e9f13bb812a92a Mon Sep 17 00:00:00 2001 From: Frank Yu Date: Fri, 18 Jun 2021 20:15:02 +0800 Subject: [PATCH 10/87] Update templating.rst --- docs/templating.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templating.rst b/docs/templating.rst index b0964df8b..dcc757c38 100644 --- a/docs/templating.rst +++ b/docs/templating.rst @@ -37,7 +37,7 @@ by default: .. data:: config :noindex: - The current configuration object (:data:`flask.config`) + The current configuration object (:data:`flask.Flask.config`) .. versionadded:: 0.6 From 7b696e076a8ebf22e8ad096b7278051d475c88be Mon Sep 17 00:00:00 2001 From: Frank Yu Date: Fri, 18 Jun 2021 22:18:15 +0800 Subject: [PATCH 11/87] Update testing.rst --- docs/testing.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/testing.rst b/docs/testing.rst index 2fedc600d..73230b4b7 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -48,20 +48,21 @@ the application for testing and initializes a new database:: import pytest from flaskr import create_app + from flaskr.db import init_db @pytest.fixture def client(): - db_fd, flaskr.app.config['DATABASE'] = tempfile.mkstemp() - flaskr.app.config['TESTING'] = True + db_fd, db_path = tempfile.mkstemp() + app = create_app({'TESTING': True, 'DATABASE': db_path}) - with flaskr.app.test_client() as client: - with flaskr.app.app_context(): - flaskr.init_db() + with app.test_client() as client: + with app.app_context(): + init_db() yield client os.close(db_fd) - os.unlink(flaskr.app.config['DATABASE']) + os.unlink(db_path) This client fixture will be called by each individual test. It gives us a simple interface to the application, where we can trigger test requests to the From 35eb582bf3ddbe995681363167eb3233f539ef8b Mon Sep 17 00:00:00 2001 From: Frank Yu Date: Sun, 20 Jun 2021 23:20:14 +0800 Subject: [PATCH 12/87] Change flask.xxx to plain version in testing docs --- docs/testing.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/testing.rst b/docs/testing.rst index 73230b4b7..061d46d24 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -225,13 +225,13 @@ temporarily. With this you can access the :class:`~flask.request`, :class:`~flask.g` and :class:`~flask.session` objects like in view functions. Here is a full example that demonstrates this approach:: - import flask + from flask import Flask, request - app = flask.Flask(__name__) + app = Flask(__name__) with app.test_request_context('/?name=Peter'): - assert flask.request.path == '/' - assert flask.request.args['name'] == 'Peter' + assert request.path == '/' + assert request.args['name'] == 'Peter' All the other objects that are context bound can be used in the same way. @@ -248,7 +248,7 @@ the test request context leaves the ``with`` block. If you do want the :meth:`~flask.Flask.before_request` functions to be called as well, you need to call :meth:`~flask.Flask.preprocess_request` yourself:: - app = flask.Flask(__name__) + app = Flask(__name__) with app.test_request_context('/?name=Peter'): app.preprocess_request() @@ -261,7 +261,7 @@ If you want to call the :meth:`~flask.Flask.after_request` functions you need to call into :meth:`~flask.Flask.process_response` which however requires that you pass it a response object:: - app = flask.Flask(__name__) + app = Flask(__name__) with app.test_request_context('/?name=Peter'): resp = Response('...') @@ -330,7 +330,7 @@ context around for a little longer so that additional introspection can happen. With Flask 0.4 this is possible by using the :meth:`~flask.Flask.test_client` with a ``with`` block:: - app = flask.Flask(__name__) + app = Flask(__name__) with app.test_client() as c: rv = c.get('/?tequila=42') @@ -354,7 +354,7 @@ keep the context around and access :data:`flask.session`:: with app.test_client() as c: rv = c.get('/') - assert flask.session['foo'] == 42 + assert session['foo'] == 42 This however does not make it possible to also modify the session or to access the session before a request was fired. Starting with Flask 0.8 we From c224832acccbb9b16485c7adeb7714c71fce1ea8 Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sat, 26 Jun 2021 18:58:15 +0800 Subject: [PATCH 13/87] Fix typo in docs/views.rst --- docs/views.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/views.rst b/docs/views.rst index 1d2daec74..63d26c5c3 100644 --- a/docs/views.rst +++ b/docs/views.rst @@ -113,8 +113,8 @@ Method Based Dispatching For RESTful APIs it's especially helpful to execute a different function for each HTTP method. With the :class:`flask.views.MethodView` you can -easily do that. Each HTTP method maps to a function with the same name -(just in lowercase):: +easily do that. Each HTTP method maps to a method of the class with the +same name (just in lowercase):: from flask.views import MethodView From 6e1b72096d5ae1e2cc4d8592ff8271b62548d9cf Mon Sep 17 00:00:00 2001 From: Adrian Moennich Date: Tue, 6 Jul 2021 22:05:31 +0200 Subject: [PATCH 14/87] Fix typo in docs --- src/flask/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flask/app.py b/src/flask/app.py index 22cc9abc5..8c3c39d44 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -1306,7 +1306,7 @@ def handle_http_exception( .. versionchanged:: 1.0 Exceptions are looked up by code *and* by MRO, so - ``HTTPExcpetion`` subclasses can be handled with a catch-all + ``HTTPException`` subclasses can be handled with a catch-all handler for the base ``HTTPException``. .. versionadded:: 0.3 From 922e91b278c19bee1154ea32a7c0c99f87d4d9b6 Mon Sep 17 00:00:00 2001 From: Frank Yu Date: Wed, 7 Jul 2021 15:16:29 +0800 Subject: [PATCH 15/87] Omit the type attribute of script tag --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index e68628783..09fc71a96 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -256,7 +256,7 @@ the filter to render data inside `` From 29c09a92c45bc0120331dd22f7079f9161d72ab7 Mon Sep 17 00:00:00 2001 From: Frank Yu Date: Wed, 7 Jul 2021 15:18:04 +0800 Subject: [PATCH 16/87] Omit the type attribute of script tag --- docs/patterns/jquery.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/patterns/jquery.rst b/docs/patterns/jquery.rst index fafbdf182..0a75bb71a 100644 --- a/docs/patterns/jquery.rst +++ b/docs/patterns/jquery.rst @@ -23,8 +23,7 @@ to add a script statement to the bottom of your ```` to load jQuery: .. sourcecode:: html - + Another method is using Google's `AJAX Libraries API `_ to load jQuery: @@ -59,7 +58,7 @@ like this: .. sourcecode:: html+jinja - @@ -109,7 +108,7 @@ usually a better idea to have that in a separate script file: .. sourcecode:: html - ``," " escaping causes it to be rendered as text, rather than running the " "script in the user's browser." msgstr "" -#: ../../quickstart.rst:212 +#: ../../quickstart.rst:232 msgid "" "```` in the route captures a value from the URL and passes it to " "the view function. These variable rules are explained below." msgstr "" -#: ../../quickstart.rst:217 +#: ../../quickstart.rst:237 msgid "Routing" msgstr "" -#: ../../quickstart.rst:219 +#: ../../quickstart.rst:239 msgid "" "Modern web applications use meaningful URLs to help users. Users are more" " likely to like a page and come back if the page uses a meaningful URL " "they can remember and use to directly visit a page." msgstr "" -#: ../../quickstart.rst:223 +#: ../../quickstart.rst:243 msgid "" "Use the :meth:`~flask.Flask.route` decorator to bind a function to a URL." " ::" msgstr "" -#: ../../quickstart.rst:233 +#: ../../quickstart.rst:253 msgid "" "You can do more! You can make parts of the URL dynamic and attach " "multiple rules to a function." msgstr "" -#: ../../quickstart.rst:237 +#: ../../quickstart.rst:257 msgid "Variable Rules" msgstr "" -#: ../../quickstart.rst:239 +#: ../../quickstart.rst:259 msgid "" "You can add variable sections to a URL by marking sections with " "````. Your function then receives the ```` " @@ -301,59 +312,59 @@ msgid "" " type of the argument like ````. ::" msgstr "" -#: ../../quickstart.rst:261 +#: ../../quickstart.rst:281 msgid "Converter types:" msgstr "" -#: ../../quickstart.rst:264 +#: ../../quickstart.rst:284 msgid "``string``" msgstr "" -#: ../../quickstart.rst:264 +#: ../../quickstart.rst:284 msgid "(default) accepts any text without a slash" msgstr "" -#: ../../quickstart.rst:265 +#: ../../quickstart.rst:285 msgid "``int``" msgstr "" -#: ../../quickstart.rst:265 +#: ../../quickstart.rst:285 msgid "accepts positive integers" msgstr "" -#: ../../quickstart.rst:266 +#: ../../quickstart.rst:286 msgid "``float``" msgstr "" -#: ../../quickstart.rst:266 +#: ../../quickstart.rst:286 msgid "accepts positive floating point values" msgstr "" -#: ../../quickstart.rst:267 +#: ../../quickstart.rst:287 msgid "``path``" msgstr "" -#: ../../quickstart.rst:267 +#: ../../quickstart.rst:287 msgid "like ``string`` but also accepts slashes" msgstr "" -#: ../../quickstart.rst:268 +#: ../../quickstart.rst:288 msgid "``uuid``" msgstr "" -#: ../../quickstart.rst:268 +#: ../../quickstart.rst:288 msgid "accepts UUID strings" msgstr "" -#: ../../quickstart.rst:273 +#: ../../quickstart.rst:293 msgid "Unique URLs / Redirection Behavior" msgstr "" -#: ../../quickstart.rst:275 +#: ../../quickstart.rst:295 msgid "The following two rules differ in their use of a trailing slash. ::" msgstr "" -#: ../../quickstart.rst:285 +#: ../../quickstart.rst:305 msgid "" "The canonical URL for the ``projects`` endpoint has a trailing slash. " "It's similar to a folder in a file system. If you access the URL without " @@ -361,7 +372,7 @@ msgid "" "URL with the trailing slash (``/projects/``)." msgstr "" -#: ../../quickstart.rst:290 +#: ../../quickstart.rst:310 msgid "" "The canonical URL for the ``about`` endpoint does not have a trailing " "slash. It's similar to the pathname of a file. Accessing the URL with a " @@ -370,11 +381,11 @@ msgid "" "avoid indexing the same page twice." msgstr "" -#: ../../quickstart.rst:300 +#: ../../quickstart.rst:320 msgid "URL Building" msgstr "" -#: ../../quickstart.rst:302 +#: ../../quickstart.rst:322 msgid "" "To build a URL to a specific function, use the :func:`~flask.url_for` " "function. It accepts the name of the function as its first argument and " @@ -383,40 +394,40 @@ msgid "" "parameters." msgstr "" -#: ../../quickstart.rst:307 +#: ../../quickstart.rst:327 msgid "" "Why would you want to build URLs using the URL reversing function " ":func:`~flask.url_for` instead of hard-coding them into your templates?" msgstr "" -#: ../../quickstart.rst:310 +#: ../../quickstart.rst:330 msgid "Reversing is often more descriptive than hard-coding the URLs." msgstr "" -#: ../../quickstart.rst:311 +#: ../../quickstart.rst:331 msgid "" "You can change your URLs in one go instead of needing to remember to " "manually change hard-coded URLs." msgstr "" -#: ../../quickstart.rst:313 +#: ../../quickstart.rst:333 msgid "URL building handles escaping of special characters transparently." msgstr "" -#: ../../quickstart.rst:314 +#: ../../quickstart.rst:334 msgid "" "The generated paths are always absolute, avoiding unexpected behavior of " "relative paths in browsers." msgstr "" -#: ../../quickstart.rst:316 +#: ../../quickstart.rst:336 msgid "" "If your application is placed outside the URL root, for example, in " "``/myapplication`` instead of ``/``, :func:`~flask.url_for` properly " "handles that for you." msgstr "" -#: ../../quickstart.rst:320 +#: ../../quickstart.rst:340 msgid "" "For example, here we use the :meth:`~flask.Flask.test_request_context` " "method to try out :func:`~flask.url_for`. " @@ -425,11 +436,11 @@ msgid "" ":`context-locals`." msgstr "" -#: ../../quickstart.rst:356 +#: ../../quickstart.rst:376 msgid "HTTP Methods" msgstr "" -#: ../../quickstart.rst:358 +#: ../../quickstart.rst:378 msgid "" "Web applications use different HTTP methods when accessing URLs. You " "should familiarize yourself with the HTTP methods as you work with Flask." @@ -438,18 +449,18 @@ msgid "" "handle different HTTP methods. ::" msgstr "" -#: ../../quickstart.rst:373 +#: ../../quickstart.rst:393 msgid "" "If ``GET`` is present, Flask automatically adds support for the ``HEAD`` " "method and handles ``HEAD`` requests according to the `HTTP RFC`_. " "Likewise, ``OPTIONS`` is automatically implemented for you." msgstr "" -#: ../../quickstart.rst:380 +#: ../../quickstart.rst:400 msgid "Static Files" msgstr "" -#: ../../quickstart.rst:382 +#: ../../quickstart.rst:402 msgid "" "Dynamic web applications also need static files. That's usually where " "the CSS and JavaScript files are coming from. Ideally your web server is" @@ -459,21 +470,21 @@ msgid "" "application." msgstr "" -#: ../../quickstart.rst:388 +#: ../../quickstart.rst:408 msgid "" "To generate URLs for static files, use the special ``'static'`` endpoint " "name::" msgstr "" -#: ../../quickstart.rst:392 +#: ../../quickstart.rst:412 msgid "The file has to be stored on the filesystem as :file:`static/style.css`." msgstr "" -#: ../../quickstart.rst:395 +#: ../../quickstart.rst:415 msgid "Rendering Templates" msgstr "" -#: ../../quickstart.rst:397 +#: ../../quickstart.rst:417 msgid "" "Generating HTML from within Python is not fun, and actually pretty " "cumbersome because you have to do the HTML escaping on your own to keep " @@ -482,7 +493,7 @@ msgid "" "automatically." msgstr "" -#: ../../quickstart.rst:402 +#: ../../quickstart.rst:422 msgid "" "To render a template you can use the :func:`~flask.render_template` " "method. All you have to do is provide the name of the template and the " @@ -490,40 +501,41 @@ msgid "" "Here's a simple example of how to render a template::" msgstr "" -#: ../../quickstart.rst:414 +#: ../../quickstart.rst:434 msgid "" "Flask will look for templates in the :file:`templates` folder. So if " "your application is a module, this folder is next to that module, if it's" " a package it's actually inside your package:" msgstr "" -#: ../../quickstart.rst:418 +#: ../../quickstart.rst:438 msgid "**Case 1**: a module::" msgstr "" -#: ../../quickstart.rst:424 +#: ../../quickstart.rst:444 msgid "**Case 2**: a package::" msgstr "" -#: ../../quickstart.rst:431 +#: ../../quickstart.rst:451 msgid "" "For templates you can use the full power of Jinja2 templates. Head over " "to the official `Jinja2 Template Documentation " "`_ for more information." msgstr "" -#: ../../quickstart.rst:435 +#: ../../quickstart.rst:455 msgid "Here is an example template:" msgstr "" -#: ../../quickstart.rst:447 +#: ../../quickstart.rst:467 msgid "" -"Inside templates you also have access to the :class:`~flask.request`, " -":class:`~flask.session` and :class:`~flask.g` [#]_ objects as well as the" -" :func:`~flask.get_flashed_messages` function." +"Inside templates you also have access to the :data:`~flask.Flask.config`," +" :class:`~flask.request`, :class:`~flask.session` and :class:`~flask.g` " +"[#]_ objects as well as the :func:`~flask.url_for` and " +":func:`~flask.get_flashed_messages` functions." msgstr "" -#: ../../quickstart.rst:451 +#: ../../quickstart.rst:471 msgid "" "Templates are especially useful if inheritance is used. If you want to " "know how that works, see :doc:`patterns/templateinheritance`. Basically " @@ -531,7 +543,7 @@ msgid "" "page (like header, navigation and footer)." msgstr "" -#: ../../quickstart.rst:456 +#: ../../quickstart.rst:476 msgid "" "Automatic escaping is enabled, so if ``name`` contains HTML it will be " "escaped automatically. If you can trust a variable and you know that it " @@ -541,13 +553,13 @@ msgid "" " template. Head over to the Jinja 2 documentation for more examples." msgstr "" -#: ../../quickstart.rst:463 +#: ../../quickstart.rst:483 msgid "" "Here is a basic introduction to how the :class:`~markupsafe.Markup` class" " works::" msgstr "" -#: ../../quickstart.rst:475 +#: ../../quickstart.rst:495 msgid "" "Autoescaping is no longer enabled for all templates. The following " "extensions for templates trigger autoescaping: ``.html``, ``.htm``, " @@ -555,18 +567,18 @@ msgid "" "autoescaping disabled." msgstr "" -#: ../../quickstart.rst:480 +#: ../../quickstart.rst:500 msgid "" "Unsure what that :class:`~flask.g` object is? It's something in which you" " can store information for your own needs. See the documentation for " ":class:`flask.g` and :doc:`patterns/sqlite3`." msgstr "" -#: ../../quickstart.rst:486 +#: ../../quickstart.rst:506 msgid "Accessing Request Data" msgstr "" -#: ../../quickstart.rst:488 +#: ../../quickstart.rst:508 msgid "" "For web applications it's crucial to react to the data a client sends to " "the server. In Flask this information is provided by the global " @@ -575,21 +587,21 @@ msgid "" "manages to still be threadsafe. The answer is context locals:" msgstr "" -#: ../../quickstart.rst:498 +#: ../../quickstart.rst:518 msgid "Context Locals" msgstr "" -#: ../../quickstart.rst:500 +#: ../../quickstart.rst:520 msgid "Insider Information" msgstr "" -#: ../../quickstart.rst:502 +#: ../../quickstart.rst:522 msgid "" "If you want to understand how that works and how you can implement tests " "with context locals, read this section, otherwise just skip it." msgstr "" -#: ../../quickstart.rst:505 +#: ../../quickstart.rst:525 msgid "" "Certain objects in Flask are global objects, but not of the usual kind. " "These objects are actually proxies to objects that are local to a " @@ -597,7 +609,7 @@ msgid "" "understand." msgstr "" -#: ../../quickstart.rst:509 +#: ../../quickstart.rst:529 msgid "" "Imagine the context being the handling thread. A request comes in and " "the web server decides to spawn a new thread (or something else, the " @@ -609,7 +621,7 @@ msgid "" "another application without breaking." msgstr "" -#: ../../quickstart.rst:518 +#: ../../quickstart.rst:538 msgid "" "So what does this mean to you? Basically you can completely ignore that " "this is the case unless you are doing something like unit testing. You " @@ -622,17 +634,17 @@ msgid "" "that you can interact with it. Here is an example::" msgstr "" -#: ../../quickstart.rst:535 +#: ../../quickstart.rst:555 msgid "" "The other possibility is passing a whole WSGI environment to the " ":meth:`~flask.Flask.request_context` method::" msgstr "" -#: ../../quickstart.rst:542 +#: ../../quickstart.rst:562 msgid "The Request Object" msgstr "" -#: ../../quickstart.rst:544 +#: ../../quickstart.rst:564 msgid "" "The request object is documented in the API section and we will not cover" " it here in detail (see :class:`~flask.Request`). Here is a broad " @@ -640,7 +652,7 @@ msgid "" " import it from the ``flask`` module::" msgstr "" -#: ../../quickstart.rst:551 +#: ../../quickstart.rst:571 msgid "" "The current request method is available by using the " ":attr:`~flask.Request.method` attribute. To access form data (data " @@ -649,7 +661,7 @@ msgid "" " attributes mentioned above::" msgstr "" -#: ../../quickstart.rst:570 +#: ../../quickstart.rst:590 msgid "" "What happens if the key does not exist in the ``form`` attribute? In " "that case a special :exc:`KeyError` is raised. You can catch it like a " @@ -658,37 +670,37 @@ msgid "" "deal with that problem." msgstr "" -#: ../../quickstart.rst:576 +#: ../../quickstart.rst:596 msgid "" "To access parameters submitted in the URL (``?key=value``) you can use " "the :attr:`~flask.Request.args` attribute::" msgstr "" -#: ../../quickstart.rst:581 +#: ../../quickstart.rst:601 msgid "" "We recommend accessing URL parameters with `get` or by catching the " ":exc:`KeyError` because users might change the URL and presenting them a " "400 bad request page in that case is not user friendly." msgstr "" -#: ../../quickstart.rst:585 +#: ../../quickstart.rst:605 msgid "" "For a full list of methods and attributes of the request object, head " "over to the :class:`~flask.Request` documentation." msgstr "" -#: ../../quickstart.rst:590 +#: ../../quickstart.rst:610 msgid "File Uploads" msgstr "" -#: ../../quickstart.rst:592 +#: ../../quickstart.rst:612 msgid "" "You can handle uploaded files with Flask easily. Just make sure not to " "forget to set the ``enctype=\"multipart/form-data\"`` attribute on your " "HTML form, otherwise the browser will not transmit your files at all." msgstr "" -#: ../../quickstart.rst:596 +#: ../../quickstart.rst:616 msgid "" "Uploaded files are stored in memory or at a temporary location on the " "filesystem. You can access those files by looking at the " @@ -700,7 +712,7 @@ msgid "" "example showing how that works::" msgstr "" -#: ../../quickstart.rst:614 +#: ../../quickstart.rst:634 msgid "" "If you want to know how the file was named on the client before it was " "uploaded to your application, you can access the " @@ -712,15 +724,15 @@ msgid "" "for you::" msgstr "" -#: ../../quickstart.rst:632 +#: ../../quickstart.rst:652 msgid "For some better examples, see :doc:`patterns/fileuploads`." msgstr "" -#: ../../quickstart.rst:635 +#: ../../quickstart.rst:655 msgid "Cookies" msgstr "" -#: ../../quickstart.rst:637 +#: ../../quickstart.rst:657 msgid "" "To access cookies you can use the :attr:`~flask.Request.cookies` " "attribute. To set cookies you can use the " @@ -732,15 +744,15 @@ msgid "" "you." msgstr "" -#: ../../quickstart.rst:645 +#: ../../quickstart.rst:665 msgid "Reading cookies::" msgstr "" -#: ../../quickstart.rst:655 +#: ../../quickstart.rst:675 msgid "Storing cookies::" msgstr "" -#: ../../quickstart.rst:665 +#: ../../quickstart.rst:685 msgid "" "Note that cookies are set on response objects. Since you normally just " "return strings from the view functions Flask will convert them into " @@ -748,58 +760,58 @@ msgid "" "the :meth:`~flask.make_response` function and then modify it." msgstr "" -#: ../../quickstart.rst:670 +#: ../../quickstart.rst:690 msgid "" "Sometimes you might want to set a cookie at a point where the response " "object does not exist yet. This is possible by utilizing the " ":doc:`patterns/deferredcallbacks` pattern." msgstr "" -#: ../../quickstart.rst:674 +#: ../../quickstart.rst:694 msgid "For this also see :ref:`about-responses`." msgstr "" -#: ../../quickstart.rst:677 +#: ../../quickstart.rst:697 msgid "Redirects and Errors" msgstr "" -#: ../../quickstart.rst:679 +#: ../../quickstart.rst:699 msgid "" "To redirect a user to another endpoint, use the :func:`~flask.redirect` " "function; to abort a request early with an error code, use the " ":func:`~flask.abort` function::" msgstr "" -#: ../../quickstart.rst:694 +#: ../../quickstart.rst:714 msgid "" "This is a rather pointless example because a user will be redirected from" " the index to a page they cannot access (401 means access denied) but it " "shows how that works." msgstr "" -#: ../../quickstart.rst:698 +#: ../../quickstart.rst:718 msgid "" "By default a black and white error page is shown for each error code. If" " you want to customize the error page, you can use the " ":meth:`~flask.Flask.errorhandler` decorator::" msgstr "" -#: ../../quickstart.rst:708 +#: ../../quickstart.rst:728 msgid "" "Note the ``404`` after the :func:`~flask.render_template` call. This " "tells Flask that the status code of that page should be 404 which means " "not found. By default 200 is assumed which translates to: all went well." msgstr "" -#: ../../quickstart.rst:712 +#: ../../quickstart.rst:732 msgid "See :doc:`errorhandling` for more details." msgstr "" -#: ../../quickstart.rst:717 +#: ../../quickstart.rst:737 msgid "About Responses" msgstr "" -#: ../../quickstart.rst:719 +#: ../../quickstart.rst:739 msgid "" "The return value from a view function is automatically converted into a " "response object for you. If the return value is a string it's converted " @@ -810,23 +822,23 @@ msgid "" "follows:" msgstr "" -#: ../../quickstart.rst:727 +#: ../../quickstart.rst:747 msgid "" "If a response object of the correct type is returned it's directly " "returned from the view." msgstr "" -#: ../../quickstart.rst:729 +#: ../../quickstart.rst:749 msgid "" "If it's a string, a response object is created with that data and the " "default parameters." msgstr "" -#: ../../quickstart.rst:731 +#: ../../quickstart.rst:751 msgid "If it's a dict, a response object is created using ``jsonify``." msgstr "" -#: ../../quickstart.rst:732 +#: ../../quickstart.rst:752 msgid "" "If a tuple is returned the items in the tuple can provide extra " "information. Such tuples have to be in the form ``(response, status)``, " @@ -835,41 +847,41 @@ msgid "" "list or dictionary of additional header values." msgstr "" -#: ../../quickstart.rst:738 +#: ../../quickstart.rst:758 msgid "" "If none of that works, Flask will assume the return value is a valid WSGI" " application and convert that into a response object." msgstr "" -#: ../../quickstart.rst:741 +#: ../../quickstart.rst:761 msgid "" "If you want to get hold of the resulting response object inside the view " "you can use the :func:`~flask.make_response` function." msgstr "" -#: ../../quickstart.rst:744 +#: ../../quickstart.rst:764 msgid "Imagine you have a view like this::" msgstr "" -#: ../../quickstart.rst:752 +#: ../../quickstart.rst:772 msgid "" "You just need to wrap the return expression with " ":func:`~flask.make_response` and get the response object to modify it, " "then return it::" msgstr "" -#: ../../quickstart.rst:766 +#: ../../quickstart.rst:786 msgid "APIs with JSON" msgstr "" -#: ../../quickstart.rst:768 +#: ../../quickstart.rst:788 msgid "" "A common response format when writing an API is JSON. It's easy to get " "started writing such an API with Flask. If you return a ``dict`` from a " "view, it will be converted to a JSON response." msgstr "" -#: ../../quickstart.rst:783 +#: ../../quickstart.rst:803 msgid "" "Depending on your API design, you may want to create JSON responses for " "types other than ``dict``. In that case, use the " @@ -878,11 +890,11 @@ msgid "" " complex applications." msgstr "" -#: ../../quickstart.rst:802 +#: ../../quickstart.rst:822 msgid "Sessions" msgstr "" -#: ../../quickstart.rst:804 +#: ../../quickstart.rst:824 msgid "" "In addition to the request object there is also a second object called " ":class:`~flask.session` which allows you to store information specific to" @@ -892,17 +904,17 @@ msgid "" "modify it, unless they know the secret key used for signing." msgstr "" -#: ../../quickstart.rst:811 +#: ../../quickstart.rst:831 msgid "" "In order to use sessions you have to set a secret key. Here is how " "sessions work::" msgstr "" -#: ../../quickstart.rst:843 +#: ../../quickstart.rst:863 msgid "How to generate good secret keys" msgstr "" -#: ../../quickstart.rst:845 +#: ../../quickstart.rst:865 msgid "" "A secret key should be as random as possible. Your operating system has " "ways to generate pretty random data based on a cryptographic random " @@ -910,7 +922,7 @@ msgid "" ":attr:`Flask.secret_key` (or :data:`SECRET_KEY`)::" msgstr "" -#: ../../quickstart.rst:853 +#: ../../quickstart.rst:873 msgid "" "A note on cookie-based sessions: Flask will take the values you put into " "the session object and serialize them into a cookie. If you are finding " @@ -920,18 +932,18 @@ msgid "" "browsers." msgstr "" -#: ../../quickstart.rst:859 +#: ../../quickstart.rst:879 msgid "" "Besides the default client-side based sessions, if you want to handle " "sessions on the server-side instead, there are several Flask extensions " "that support this." msgstr "" -#: ../../quickstart.rst:864 +#: ../../quickstart.rst:884 msgid "Message Flashing" msgstr "" -#: ../../quickstart.rst:866 +#: ../../quickstart.rst:886 msgid "" "Good applications and user interfaces are all about feedback. If the " "user does not get enough feedback they will probably end up hating the " @@ -942,7 +954,7 @@ msgid "" "layout template to expose the message." msgstr "" -#: ../../quickstart.rst:874 +#: ../../quickstart.rst:894 msgid "" "To flash a message use the :func:`~flask.flash` method, to get hold of " "the messages you can use :func:`~flask.get_flashed_messages` which is " @@ -950,11 +962,11 @@ msgid "" "example." msgstr "" -#: ../../quickstart.rst:880 +#: ../../quickstart.rst:900 msgid "Logging" msgstr "" -#: ../../quickstart.rst:884 +#: ../../quickstart.rst:904 msgid "" "Sometimes you might be in a situation where you deal with data that " "should be correct, but actually is not. For example you may have some " @@ -965,33 +977,33 @@ msgid "" "and the code has to continue working." msgstr "" -#: ../../quickstart.rst:892 +#: ../../quickstart.rst:912 msgid "" "You may still want to log that something fishy happened. This is where " "loggers come in handy. As of Flask 0.3 a logger is preconfigured for you" " to use." msgstr "" -#: ../../quickstart.rst:896 +#: ../../quickstart.rst:916 msgid "Here are some example log calls::" msgstr "" -#: ../../quickstart.rst:902 +#: ../../quickstart.rst:922 msgid "" "The attached :attr:`~flask.Flask.logger` is a standard logging " ":class:`~logging.Logger`, so head over to the official :mod:`logging` " "docs for more information." msgstr "" -#: ../../quickstart.rst:906 +#: ../../quickstart.rst:926 msgid "See :doc:`errorhandling`." msgstr "" -#: ../../quickstart.rst:910 +#: ../../quickstart.rst:930 msgid "Hooking in WSGI Middleware" msgstr "" -#: ../../quickstart.rst:912 +#: ../../quickstart.rst:932 msgid "" "To add WSGI middleware to your Flask application, wrap the application's " "``wsgi_app`` attribute. For example, to apply Werkzeug's " @@ -999,32 +1011,40 @@ msgid "" "behind Nginx:" msgstr "" -#: ../../quickstart.rst:922 +#: ../../quickstart.rst:942 msgid "" "Wrapping ``app.wsgi_app`` instead of ``app`` means that ``app`` still " "points at your Flask application, not at the middleware, so you can " "continue to use and configure ``app`` directly." msgstr "" -#: ../../quickstart.rst:927 +#: ../../quickstart.rst:947 msgid "Using Flask Extensions" msgstr "" -#: ../../quickstart.rst:929 +#: ../../quickstart.rst:949 msgid "" "Extensions are packages that help you accomplish common tasks. For " "example, Flask-SQLAlchemy provides SQLAlchemy support that makes it " "simple and easy to use with Flask." msgstr "" -#: ../../quickstart.rst:933 +#: ../../quickstart.rst:953 msgid "For more on Flask extensions, see :doc:`extensions`." msgstr "" -#: ../../quickstart.rst:936 +#: ../../quickstart.rst:956 msgid "Deploying to a Web Server" msgstr "" -#: ../../quickstart.rst:938 +#: ../../quickstart.rst:958 msgid "Ready to deploy your new Flask app? See :doc:`deploying/index`." msgstr "" + +#~ msgid "" +#~ "Inside templates you also have access" +#~ " to the :class:`~flask.request`, " +#~ ":class:`~flask.session` and :class:`~flask.g` [#]_" +#~ " objects as well as the " +#~ ":func:`~flask.get_flashed_messages` function." +#~ msgstr "" diff --git a/docs/locales/zh_CN/LC_MESSAGES/reqcontext.po b/docs/locales/zh_CN/LC_MESSAGES/reqcontext.po index b6daabcce..c111a4f8f 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/reqcontext.po +++ b/docs/locales/zh_CN/LC_MESSAGES/reqcontext.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: rosekc \n" "Language-Team: zh_CN \n" @@ -28,18 +28,18 @@ msgid "" "runs during a request, the :data:`request` and :data:`session` proxies " "are accessed instead." msgstr "" -"在请求当中,请求上下文保持对请求层级的数据的追踪。相比在请求当中把请求对" -"象传递到每个函数当中,Flask 使用了 :data:`request` 与 :data:`session` 代理" -"对象来访问请求对象。" +"在请求当中,请求上下文保持对请求层级的数据的追踪。相比在请求当中把请求对象传递到每个函数当中,Flask 使用了 :data:`request` " +"与 :data:`session` 代理对象来访问请求对象。" #: ../../reqcontext.rst:11 +#, fuzzy msgid "" -"This is similar to the :doc:`/appcontext`, which keeps track of the " +"This is similar to :doc:`/appcontext`, which keeps track of the " "application-level data independent of a request. A corresponding " "application context is pushed when a request context is pushed." msgstr "" -"这与 :doc:`/appcontext` 类似,只不过应用上下文跟踪独立于请求的应用层级数据。" -"在请求上下文被推入线程局部栈时,对应的应用上下文也被推入。" +"这与 :doc:`/appcontext` " +"类似,只不过应用上下文跟踪独立于请求的应用层级数据。在请求上下文被推入线程局部栈时,对应的应用上下文也被推入。" #: ../../reqcontext.rst:17 msgid "Purpose of the Context" @@ -54,11 +54,9 @@ msgid "" "be considered global to that worker during that request. Flask uses the " "term *context local* for this." msgstr "" -"当 :class:`Flask` 应用处理请求,根据从 WSGI 服务器获取到的环境,创建出相应的 :" -"class:`Request` 对象。因为 *工作者* (根据不同的服务器可能为线" -"程,进程或协程)一次只能处理一个请求,在请求当中,请求数据可以认为" -"对工作者全局可见、Flask 用术语 *上下文局部变量(context local)* 来表示" -"这种设计。" +"当 :class:`Flask` 应用处理请求,根据从 WSGI 服务器获取到的环境,创建出相应的 :class:`Request` 对象。因为 " +"*工作者* (根据不同的服务器可能为线程,进程或协程)一次只能处理一个请求,在请求当中,请求数据可以认为对工作者全局可见、Flask 用术语 " +"*上下文局部变量(context local)* 来表示这种设计。" #: ../../reqcontext.rst:26 msgid "" @@ -67,22 +65,22 @@ msgid "" "request will have access to the :data:`request` proxy, which points to " "the request object for the current request." msgstr "" -"Flask 在处理请求时,会自动 *推入* 请求上下文。视图函数,错误处理钩" -"子函数与其他在请求当中运行的函数可以访问指向当前请求的请求对象代理对象 :" -"data:`request`。" +"Flask 在处理请求时,会自动 *推入* 请求上下文。视图函数,错误处理钩子函数与其他在请求当中运行的函数可以访问指向当前请求的请求对象代理对象" +" :data:`request`。" #: ../../reqcontext.rst:33 msgid "Lifetime of the Context" msgstr "上下文的生命周期" #: ../../reqcontext.rst:35 +#, fuzzy msgid "" "When a Flask application begins handling a request, it pushes a request " -"context, which also pushes an :doc:`/appcontext`. When the request ends " -"it pops the request context then the application context." +"context, which also pushes an :doc:`app context `. When the " +"request ends it pops the request context then the application context." msgstr "" -"当 Flask 应用开始处理请求时,推入请求上下文的同时也推入了 :doc:`/" -"appcontext`。当请求结束,会先弹出请求上下文,然后再弹出应用上下文。" +"当 Flask 应用开始处理请求时,推入请求上下文的同时也推入了 " +":doc:`/appcontext`。当请求结束,会先弹出请求上下文,然后再弹出应用上下文。" #: ../../reqcontext.rst:39 msgid "" @@ -91,16 +89,14 @@ msgid "" " have a different context stack and will not know about the request the " "parent thread was pointing to." msgstr "" -"每个线程(或者其他工作者类型)的上下文是独立的。:data:`request` 不能传入其" -"他线程,其他线程有不同的上下文栈,因此不会知道父线程会指向哪个请求。" +"每个线程(或者其他工作者类型)的上下文是独立的。:data:`request` " +"不能传入其他线程,其他线程有不同的上下文栈,因此不会知道父线程会指向哪个请求。" #: ../../reqcontext.rst:44 msgid "" "Context locals are implemented in Werkzeug. See :doc:`werkzeug:local` for" " more information on how this works internally." -msgstr "" -"上下文局部变量的实现在 Werkzeug 中。若要了解更多内部工作细节,参见 :doc:" -"`werkzeug:local`。" +msgstr "上下文局部变量的实现在 Werkzeug 中。若要了解更多内部工作细节,参见 :doc:`werkzeug:local`。" #: ../../reqcontext.rst:49 msgid "Manually Push a Context" @@ -110,9 +106,7 @@ msgstr "手动推入上下文" msgid "" "If you try to access :data:`request`, or anything that uses it, outside a" " request context, you'll get this error message:" -msgstr "" -"如果要在应用上下文之外的地方试图去获取或者使用依赖 :data:`request` 的任何东西," -"有可能会收到这样的错误信息:" +msgstr "如果要在应用上下文之外的地方试图去获取或者使用依赖 :data:`request` 的任何东西,有可能会收到这样的错误信息:" #: ../../reqcontext.rst:62 msgid "" @@ -123,27 +117,23 @@ msgid "" "that runs in the block will have access to :data:`request`, populated " "with your test data. ::" msgstr "" -"这通常只会在测试需要活动请求的代码时候发生。其中一个方法是使用 :meth:" -"`test client ` 来模拟一个完整请求。或者可以在 ``with`` " -"块使用 :meth:`~Flask.test_request_context`,所有在块中运行的代码将会可以访" -"问由测试数据生成的 :data:`request`。 ::" +"这通常只会在测试需要活动请求的代码时候发生。其中一个方法是使用 :meth:`test client ` " +"来模拟一个完整请求。或者可以在 ``with`` 块使用 " +":meth:`~Flask.test_request_context`,所有在块中运行的代码将会可以访问由测试数据生成的 " +":data:`request`。 ::" #: ../../reqcontext.rst:77 msgid "" "If you see that error somewhere else in your code not related to testing," " it most likely indicates that you should move that code into a view " "function." -msgstr "" -"如果你在测试应用以外场景遇到这个错误,绝大多数情况下意味着这些代码应该转移" -"到视图函数下。" +msgstr "如果你在测试应用以外场景遇到这个错误,绝大多数情况下意味着这些代码应该转移到视图函数下。" #: ../../reqcontext.rst:81 msgid "" "For information on how to use the request context from the interactive " "Python shell, see :doc:`/shell`." -msgstr "" -"了解更多如何在 Python 交互式命令行中使用请求上下文的信息,参见 :doc:`/" -"shell`。" +msgstr "了解更多如何在 Python 交互式命令行中使用请求上下文的信息,参见 :doc:`/shell`。" #: ../../reqcontext.rst:86 msgid "How the Context Works" @@ -158,10 +148,9 @@ msgid "" "proxies that depend on them are available and point at information from " "the top context on the stack." msgstr "" -"在处理每个请求时,都会调用 :meth:`Flask.wsgi_app` 方法。它在请求中控制上下" -"文。具体来说,存储请求上下文和应用上下文的数据结构为栈,分别为 :data:" -"`_request_ctx_stack` 以及 :data:`_app_ctx_stack`。当上下文被推入栈,依赖栈" -"的代理对象变得可用,指向在栈顶的上下文。" +"在处理每个请求时,都会调用 :meth:`Flask.wsgi_app` " +"方法。它在请求中控制上下文。具体来说,存储请求上下文和应用上下文的数据结构为栈,分别为 :data:`_request_ctx_stack` 以及" +" :data:`_app_ctx_stack`。当上下文被推入栈,依赖栈的代理对象变得可用,指向在栈顶的上下文。" #: ../../reqcontext.rst:95 msgid "" @@ -172,10 +161,10 @@ msgid "" " and :data:`session` proxies are available to the original thread " "handling the request." msgstr "" -"当请求开始,将创建并推入 :class:`~ctx.RequestContext` 对象。如果此时应" -"用上下文不在上下文栈的顶部,将先创建 :class:`~ctx.AppContext`。当这些" -"上下文被推入,代理对象 :data:`current_app`、:data:`g`、:data:`request` 以" -"及 :data:`session` 在处理请求的线程变得可用。" +"当请求开始,将创建并推入 :class:`~ctx.RequestContext` 对象。如果此时应用上下文不在上下文栈的顶部,将先创建 " +":class:`~ctx.AppContext`。当这些上下文被推入,代理对象 " +":data:`current_app`、:data:`g`、:data:`request` 以及 :data:`session` " +"在处理请求的线程变得可用。" #: ../../reqcontext.rst:102 msgid "" @@ -183,10 +172,7 @@ msgid "" "the proxies during a request. While this is not a common pattern, it can " "be used in advanced applications to, for example, do internal redirects " "or chain different applications together." -msgstr "" -"因为上下文对象存放在栈中,在请求中,其他上下文对象推入时可能会改变代理" -"对象的指向。尽管这不是常见的设计模式,但它可以让应用能够内部重定向或者" -"将不同应用串联在一起。" +msgstr "因为上下文对象存放在栈中,在请求中,其他上下文对象推入时可能会改变代理对象的指向。尽管这不是常见的设计模式,但它可以让应用能够内部重定向或者将不同应用串联在一起。" #: ../../reqcontext.rst:107 msgid "" @@ -196,10 +182,9 @@ msgid "" "and :meth:`~Flask.teardown_appcontext` functions are executed. These " "execute even if an unhandled exception occurred during dispatch." msgstr "" -"当请求被分配到视图函数,生成并发送响应,请求上下文先被弹出,然后应用上下文" -"也被弹出。在上下文被弹出前,函数 :meth:`~Flask.teardown_request` 以及 :" -"meth:`~Flask.teardown_appcontext` 会被执行。即使在请求被分配过程中有未处理" -"的请求抛出,这些函数也会被执行。" +"当请求被分配到视图函数,生成并发送响应,请求上下文先被弹出,然后应用上下文也被弹出。在上下文被弹出前,函数 " +":meth:`~Flask.teardown_request` 以及 :meth:`~Flask.teardown_appcontext` " +"会被执行。即使在请求被分配过程中有未处理的请求抛出,这些函数也会被执行。" #: ../../reqcontext.rst:117 msgid "Callbacks and Errors" @@ -210,18 +195,14 @@ msgid "" "Flask dispatches a request in multiple stages which can affect the " "request, response, and how errors are handled. The contexts are active " "during all of these stages." -msgstr "" -"Flask 在不同阶段中会分配请求,这会影响请求、响应以及错误处理。在这些阶段" -"中,上下文处于可用状态。" +msgstr "Flask 在不同阶段中会分配请求,这会影响请求、响应以及错误处理。在这些阶段中,上下文处于可用状态。" #: ../../reqcontext.rst:123 msgid "" "A :class:`Blueprint` can add handlers for these events that are specific " "to the blueprint. The handlers for a blueprint will run if the blueprint " "owns the route that matches the request." -msgstr "" -":class:`Blueprint` 可以为这些事件添加蓝图专属的钩子函数。当蓝图所属的路由" -"匹配上请求,那么蓝图内的钩子函数将被执行。" +msgstr ":class:`Blueprint` 可以为这些事件添加蓝图专属的钩子函数。当蓝图所属的路由匹配上请求,那么蓝图内的钩子函数将被执行。" #: ../../reqcontext.rst:127 msgid "" @@ -230,18 +211,15 @@ msgid "" "skipped. The return value is treated as the response and the view " "function is not called." msgstr "" -"在每个请求前,会调用 :meth:`~Flask.before_request` 函数。如果其中的一个函" -"数返回了值,那么其他函数会被跳过执行。返回值会当作响应,视图函数不会被调" -"用。" +"在每个请求前,会调用 :meth:`~Flask.before_request` " +"函数。如果其中的一个函数返回了值,那么其他函数会被跳过执行。返回值会当作响应,视图函数不会被调用。" #: ../../reqcontext.rst:132 msgid "" "If the :meth:`~Flask.before_request` functions did not return a response," " the view function for the matched route is called and returns a " "response." -msgstr "" -"如果 :meth:`~Flask.before_request` 函数不返回响应,被路由匹配的视图函" -"数将被调用,返回请求。" +msgstr "如果 :meth:`~Flask.before_request` 函数不返回响应,被路由匹配的视图函数将被调用,返回请求。" #: ../../reqcontext.rst:136 msgid "" @@ -249,8 +227,8 @@ msgid "" "and passed to the :meth:`~Flask.after_request` functions. Each function " "returns a modified or new response object." msgstr "" -"视图函数返回的值会被转换成实际的响应对象,然后传递到 :meth:`~Flask." -"after_request` 函数。每个函数返回一个被修改的或者是新的响应对象。" +"视图函数返回的值会被转换成实际的响应对象,然后传递到 :meth:`~Flask.after_request` " +"函数。每个函数返回一个被修改的或者是新的响应对象。" #: ../../reqcontext.rst:140 msgid "" @@ -259,9 +237,8 @@ msgid "" "functions. These functions are called even if an unhandled exception was " "raised at any point above." msgstr "" -"当响应被返回,在弹出上下文的过程中,会调用 :meth:`~Flask." -"teardown_request` 和 :meth:`~Flask.teardown_appcontext` 函数。即使内部有一" -"个未处理的异常抛出,这些函数也会被执行。" +"当响应被返回,在弹出上下文的过程中,会调用 :meth:`~Flask.teardown_request` 和 " +":meth:`~Flask.teardown_appcontext` 函数。即使内部有一个未处理的异常抛出,这些函数也会被执行。" #: ../../reqcontext.rst:145 msgid "" @@ -272,10 +249,9 @@ msgid "" "Internal Server Error`` response. The teardown functions are still " "called, and are passed the exception object." msgstr "" -"如果异常在清理(teardown)函数中抛出,Flask 会尝试使用 :meth:`~Flask." -"errorhandler` 函数去处理异常,返回响应。如果没有错误钩子函数,或者钩子函数" -"本身抛出了异常,Flask 返回了通用的 ``500 Internal Server Error`` 响" -"应。清理函数一样会调用,而且会传入异常对象。" +"如果异常在清理(teardown)函数中抛出,Flask 会尝试使用 :meth:`~Flask.errorhandler` " +"函数去处理异常,返回响应。如果没有错误钩子函数,或者钩子函数本身抛出了异常,Flask 返回了通用的 ``500 Internal Server " +"Error`` 响应。清理函数一样会调用,而且会传入异常对象。" #: ../../reqcontext.rst:152 msgid "" @@ -284,9 +260,8 @@ msgid "" "allows the development server to present the interactive debugger with " "the traceback." msgstr "" -"在 debug 模式开启的时候,未处理的异常不会被转换为 ``500`` 响应,而是传递" -"给 WSGI 服务器。这让开发服务器可以展示带有异常跟踪(trackback)的交互式" -"调试器。" +"在 debug 模式开启的时候,未处理的异常不会被转换为 ``500`` 响应,而是传递给 WSGI " +"服务器。这让开发服务器可以展示带有异常跟踪(trackback)的交互式调试器。" #: ../../reqcontext.rst:159 msgid "Teardown Callbacks" @@ -301,11 +276,7 @@ msgid "" " parts of the request dispatch have run first. Be sure to write these " "functions in a way that does not depend on other callbacks and will not " "fail." -msgstr "" -"清理钩子函数独立于请求分配,而是在上下文被弹出的时候才调用。当在请求分配的" -"过程中,或者在手动推入的的上下文中有未捕抓的异常,这些函数依然会被调用。这" -"意味着不会保证在请求分配的每一部分都会首先执行。确保在编写这些函数的时候不" -"要依赖其他钩子函数,不要假设函数不会失败。" +msgstr "清理钩子函数独立于请求分配,而是在上下文被弹出的时候才调用。当在请求分配的过程中,或者在手动推入的的上下文中有未捕抓的异常,这些函数依然会被调用。这意味着不会保证在请求分配的每一部分都会首先执行。确保在编写这些函数的时候不要依赖其他钩子函数,不要假设函数不会失败。" #: ../../reqcontext.rst:169 msgid "" @@ -314,9 +285,8 @@ msgid "" "Use the :meth:`~Flask.test_client` as a ``with`` block to preserve the " "contexts until the ``with`` block exits." msgstr "" -"在测试的过程中,在请求结束的时候推迟弹出上下文是一种很有用的手段,它可以让" -"测试函数访问上下文中的数据。在 ``with`` 块中使用 :meth:`~Flask." -"test_client` 来让上下文在离开 ``with`` 块前保留。" +"在测试的过程中,在请求结束的时候推迟弹出上下文是一种很有用的手段,它可以让测试函数访问上下文中的数据。在 ``with`` 块中使用 " +":meth:`~Flask.test_client` 来让上下文在离开 ``with`` 块前保留。" #: ../../reqcontext.rst:203 msgid "Signals" @@ -332,17 +302,13 @@ msgstr "如果 :data:`~signals.signals_available` 为真,下列信号将被发 msgid "" ":data:`request_started` is sent before the :meth:`~Flask.before_request` " "functions are called." -msgstr "" -"在 :meth:`~Flask.before_request` 被调用前,:data:`request_started` 信号会" -"被发送。" +msgstr "在 :meth:`~Flask.before_request` 被调用前,:data:`request_started` 信号会被发送。" #: ../../reqcontext.rst:211 msgid "" ":data:`request_finished` is sent after the :meth:`~Flask.after_request` " "functions are called." -msgstr "" -"在 :meth:`~Flask.after_request` 被调用前,:data:`request_finished` 信号会" -"被发送。" +msgstr "在 :meth:`~Flask.after_request` 被调用前,:data:`request_finished` 信号会被发送。" #: ../../reqcontext.rst:214 msgid "" @@ -350,8 +316,8 @@ msgid "" "handled, but before an :meth:`~Flask.errorhandler` is looked up or " "called." msgstr "" -"当异常开始处理时,:data:`got_request_exception` 信号会在 :meth:`~Flask." -"errorhandler` 被查看或调用前被发送。" +"当异常开始处理时,:data:`got_request_exception` 信号会在 :meth:`~Flask.errorhandler` " +"被查看或调用前被发送。" #: ../../reqcontext.rst:218 msgid "" @@ -370,9 +336,7 @@ msgid "" "At the end of a request, the request context is popped and all data " "associated with it is destroyed. If an error occurs during development, " "it is useful to delay destroying the data for debugging purposes." -msgstr "" -"在请求结束时,上下文会被弹出,所有与上下文相关的数据会被销毁。如果在开发环" -"境中有错误发生,推迟销毁上下文数据对调试来说非常有用。" +msgstr "在请求结束时,上下文会被弹出,所有与上下文相关的数据会被销毁。如果在开发环境中有错误发生,推迟销毁上下文数据对调试来说非常有用。" #: ../../reqcontext.rst:229 msgid "" @@ -389,16 +353,14 @@ msgid "" ":data:`PRESERVE_CONTEXT_ON_EXCEPTION` config. As described above, it " "defaults to ``True`` in the development environment." msgstr "" -"这一行为能被 :data:`PRESERVE_CONTEXT_ON_EXCEPTION` 设置项所控制。如上文所" -"述。在开发环境中默认设置为 ``True``。" +"这一行为能被 :data:`PRESERVE_CONTEXT_ON_EXCEPTION` 设置项所控制。如上文所述。在开发环境中默认设置为 " +"``True``。" #: ../../reqcontext.rst:237 msgid "" "Do not enable :data:`PRESERVE_CONTEXT_ON_EXCEPTION` in production, as it " "will cause your application to leak memory on exceptions." -msgstr "" -"不要在生产环境中开启 :data:`PRESERVE_CONTEXT_ON_EXCEPTION`,因为这会让应用" -"在出现异常时内存泄露。" +msgstr "不要在生产环境中开启 :data:`PRESERVE_CONTEXT_ON_EXCEPTION`,因为这会让应用在出现异常时内存泄露。" #: ../../reqcontext.rst:244 msgid "Notes On Proxies" @@ -411,39 +373,32 @@ msgid "" " the unique object bound to each worker behind the scenes as described on" " this page." msgstr "" -"一些 Flask 提供的对象,是其他对象的代理。在每个工作线程中,代理对象会以" -"相同的方式被访问。在内部实现中,代理对象指向绑定到工作者的唯一的对象。细" -"节如本页所述。" +"一些 Flask " +"提供的对象,是其他对象的代理。在每个工作线程中,代理对象会以相同的方式被访问。在内部实现中,代理对象指向绑定到工作者的唯一的对象。细节如本页所述。" #: ../../reqcontext.rst:251 msgid "" "Most of the time you don't have to care about that, but there are some " "exceptions where it is good to know that this object is actually a proxy:" -msgstr "" -"大多数时候,这些细节无需担心。但有些时候最好还是知道这个对象实际上是一个代" -"理:" +msgstr "大多数时候,这些细节无需担心。但有些时候最好还是知道这个对象实际上是一个代理:" #: ../../reqcontext.rst:254 msgid "" "The proxy objects cannot fake their type as the actual object types. If " "you want to perform instance checks, you have to do that on the object " "being proxied." -msgstr "" -"代理对象不能冒充实际指向的对象类型。如果要进行实例检查,应当要在被代理的对" -"象本身进行检查。" +msgstr "代理对象不能冒充实际指向的对象类型。如果要进行实例检查,应当要在被代理的对象本身进行检查。" #: ../../reqcontext.rst:257 msgid "" "The reference to the proxied object is needed in some situations, such as" " sending :doc:`signals` or passing data to a background thread." -msgstr "" -"在某些要使用被代理对象的引用的时候,如发送 :doc:`signals` 或者向后台线程传" -"递数据。" +msgstr "在某些要使用被代理对象的引用的时候,如发送 :doc:`signals` 或者向后台线程传递数据。" #: ../../reqcontext.rst:261 msgid "" "If you need to access the underlying object that is proxied, use the " ":meth:`~werkzeug.local.LocalProxy._get_current_object` method::" msgstr "" -"如果需要访问在底层被代理的对象,使用 :meth:`~werkzeug.local.LocalProxy." -"_get_current_object` 这个方法: ::" +"如果需要访问在底层被代理的对象,使用 :meth:`~werkzeug.local.LocalProxy._get_current_object`" +" 这个方法: ::" diff --git a/docs/locales/zh_CN/LC_MESSAGES/security.po b/docs/locales/zh_CN/LC_MESSAGES/security.po index b3755c1b9..fc86a69f4 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/security.po +++ b/docs/locales/zh_CN/LC_MESSAGES/security.po @@ -7,16 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: 2021-06-15 17:09+0800\n" +"Last-Translator: kylin \n" +"Language: zh_CN\n" "Language-Team: zh_CN \n" +"Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.9.1\n" -"Last-Translator: kylin \n" -"Language: zh_CN\n" -"X-Generator: Poedit 3.0\n" #: ../../security.rst:2 msgid "Security Considerations" @@ -24,12 +24,11 @@ msgstr "安全注意事项" #: ../../security.rst:4 msgid "" -"Web applications usually face all kinds of security problems and it's very hard " -"to get everything right. Flask tries to solve a few of these things for you, " -"but there are a couple more you have to take care of yourself." -msgstr "" -"Web 应用通常会面临各种安全问题,很难把他们全都处理好。Flask 试图为你解决其" -"中的一些问题,但还有很多需要你自己处理。" +"Web applications usually face all kinds of security problems and it's " +"very hard to get everything right. Flask tries to solve a few of these " +"things for you, but there are a couple more you have to take care of " +"yourself." +msgstr "Web 应用通常会面临各种安全问题,很难把他们全都处理好。Flask 试图为你解决其中的一些问题,但还有很多需要你自己处理。" #: ../../security.rst:11 msgid "Cross-Site Scripting (XSS)" @@ -37,25 +36,25 @@ msgstr "跨站脚本攻击(XSS)" #: ../../security.rst:13 msgid "" -"Cross site scripting is the concept of injecting arbitrary HTML (and with it " -"JavaScript) into the context of a website. To remedy this, developers have to " -"properly escape text so that it cannot include arbitrary HTML tags. For more " -"information on that have a look at the Wikipedia article on `Cross-Site " -"Scripting `_." +"Cross site scripting is the concept of injecting arbitrary HTML (and with" +" it JavaScript) into the context of a website. To remedy this, " +"developers have to properly escape text so that it cannot include " +"arbitrary HTML tags. For more information on that have a look at the " +"Wikipedia article on `Cross-Site Scripting `_." msgstr "" -"跨站脚本攻击是指将恶意的 HTML(以及附带的 JavaScript)代码注入到网站的环境中。" -"为了解决这个问题,开发人员必须正确地转义文本,使其无法包含恶意的 HTML 标签。更" -"多信息请看维基百科上的文章 `Cross-Site Scripting `_。" +"跨站脚本攻击是指将恶意的 HTML(以及附带的 " +"JavaScript)代码注入到网站的环境中。为了解决这个问题,开发人员必须正确地转义文本,使其无法包含恶意的 HTML " +"标签。更多信息请看维基百科上的文章 `Cross-Site Scripting `_。" #: ../../security.rst:20 msgid "" -"Flask configures Jinja2 to automatically escape all values unless explicitly " -"told otherwise. This should rule out all XSS problems caused in templates, but " -"there are still other places where you have to be careful:" -msgstr "" -"Flask 配置了 Jinja2 自动转义所有值,除非显式指明不转义。这应该可以排除所有由模板" -"引起的 XSS 问题,但仍有其他地方需要注意:" +"Flask configures Jinja2 to automatically escape all values unless " +"explicitly told otherwise. This should rule out all XSS problems caused " +"in templates, but there are still other places where you have to be " +"careful:" +msgstr "Flask 配置了 Jinja2 自动转义所有值,除非显式指明不转义。这应该可以排除所有由模板引起的 XSS 问题,但仍有其他地方需要注意:" #: ../../security.rst:25 msgid "generating HTML without the help of Jinja2" @@ -69,66 +68,62 @@ msgstr "在用户提交的数据上调用 :class:`~flask.Markup`" msgid "" "sending out HTML from uploaded files, never do that, use the ``Content-" "Disposition: attachment`` header to prevent that problem." -msgstr "" -"发送上传的 HTML 文件,千万不要这样做,应该使用 ``Content-Disposition: " -"attachment`` 头部来避免这个问题。" +msgstr "发送上传的 HTML 文件,千万不要这样做,应该使用 ``Content-Disposition: attachment`` 头部来避免这个问题。" #: ../../security.rst:29 msgid "" -"sending out textfiles from uploaded files. Some browsers are using content-" -"type guessing based on the first few bytes so users could trick a browser to " -"execute HTML." -msgstr "" -"发送上传的文本文件。一些浏览器会基于文件开头的几个字节推测文件的内容类型,因此用" -"户可以欺骗浏览器执行 HTML。" +"sending out textfiles from uploaded files. Some browsers are using " +"content-type guessing based on the first few bytes so users could trick a" +" browser to execute HTML." +msgstr "发送上传的文本文件。一些浏览器会基于文件开头的几个字节推测文件的内容类型,因此用户可以欺骗浏览器执行 HTML。" #: ../../security.rst:33 msgid "" -"Another thing that is very important are unquoted attributes. While Jinja2 can " -"protect you from XSS issues by escaping HTML, there is one thing it cannot " -"protect you from: XSS by attribute injection. To counter this possible attack " -"vector, be sure to always quote your attributes with either double or single " -"quotes when using Jinja expressions in them:" +"Another thing that is very important are unquoted attributes. While " +"Jinja2 can protect you from XSS issues by escaping HTML, there is one " +"thing it cannot protect you from: XSS by attribute injection. To counter" +" this possible attack vector, be sure to always quote your attributes " +"with either double or single quotes when using Jinja expressions in them:" msgstr "" -"另外值得注意的是未经引号包裹的属性。虽然 Jinja2 可以通过转义 HTML 避免 XSS 问题," -"但无法避免通过属性注入的 XSS。为了对付这种可能存在的攻击手段,在属性中使用 " -"Jinja 表达式时,请保证属性值始终被包括在双引号或单引号内:" +"另外值得注意的是未经引号包裹的属性。虽然 Jinja2 可以通过转义 HTML 避免 XSS 问题,但无法避免通过属性注入的 " +"XSS。为了对付这种可能存在的攻击手段,在属性中使用 Jinja 表达式时,请保证属性值始终被包括在双引号或单引号内:" #: ../../security.rst:43 msgid "" -"Why is this necessary? Because if you would not be doing that, an attacker " -"could easily inject custom JavaScript handlers. For example an attacker could " -"inject this piece of HTML+JavaScript:" +"Why is this necessary? Because if you would not be doing that, an " +"attacker could easily inject custom JavaScript handlers. For example an " +"attacker could inject this piece of HTML+JavaScript:" msgstr "" -"为什么必须这样做?因为如果不这样做,攻击者可以轻易注入定制的 JavaScript 事件处理" -"器。例如,攻击者可以注入以下 HTML + JavaScript 代码:" +"为什么必须这样做?因为如果不这样做,攻击者可以轻易注入定制的 JavaScript 事件处理器。例如,攻击者可以注入以下 HTML + " +"JavaScript 代码:" #: ../../security.rst:51 msgid "" -"When the user would then move with the mouse over the input, the cookie would " -"be presented to the user in an alert window. But instead of showing the cookie " -"to the user, a good attacker might also execute any other JavaScript code. In " -"combination with CSS injections the attacker might even make the element fill " -"out the entire page so that the user would just have to have the mouse anywhere " -"on the page to trigger the attack." +"When the user would then move with the mouse over the input, the cookie " +"would be presented to the user in an alert window. But instead of " +"showing the cookie to the user, a good attacker might also execute any " +"other JavaScript code. In combination with CSS injections the attacker " +"might even make the element fill out the entire page so that the user " +"would just have to have the mouse anywhere on the page to trigger the " +"attack." msgstr "" -"当用户将鼠标移到输入框时,cookie 信息就会显示在弹出的警告窗口中。 一个聪明的攻击" -"者可能不会直接向用户显示 cookie 信息,而是执行其他的 JavaScript 代码。 结合 CSS " -"注入,攻击者甚至可能使该元素填满整个页面,这样用户将鼠标放在页面的任何位置都会触" -"发攻击。" +"当用户将鼠标移到输入框时,cookie 信息就会显示在弹出的警告窗口中。 一个聪明的攻击者可能不会直接向用户显示 cookie " +"信息,而是执行其他的 JavaScript 代码。 结合 CSS " +"注入,攻击者甚至可能使该元素填满整个页面,这样用户将鼠标放在页面的任何位置都会触发攻击。" #: ../../security.rst:58 msgid "" "There is one class of XSS issues that Jinja's escaping does not protect " -"against. The ``a`` tag's ``href`` attribute can contain a `javascript:` URI, " -"which the browser will execute when clicked if not secured properly." +"against. The ``a`` tag's ``href`` attribute can contain a `javascript:` " +"URI, which the browser will execute when clicked if not secured properly." msgstr "" -"有一类 XSS 问题,Jinja 的转义并不能防止。``a`` 标签的 ``href`` 属性可以包含一" -"个 `javascript:` URI,如果没有采取合理的安全措施,在点击时浏览器就会执行。" +"有一类 XSS 问题,Jinja 的转义并不能防止。``a`` 标签的 ``href`` 属性可以包含一个 `javascript:` " +"URI,如果没有采取合理的安全措施,在点击时浏览器就会执行。" #: ../../security.rst:67 msgid "" -"To prevent this, you'll need to set the :ref:`security-csp` response header." +"To prevent this, you'll need to set the :ref:`security-csp` response " +"header." msgstr "为了防止这种问题发生,你需要设置 :ref:`security-csp` 响应头部。" #: ../../security.rst:70 @@ -137,68 +132,60 @@ msgstr "跨站请求伪造(CSRF)" #: ../../security.rst:72 msgid "" -"Another big problem is CSRF. This is a very complex topic and I won't outline " -"it here in detail just mention what it is and how to theoretically prevent it." -msgstr "" -"另一个大问题是跨站请求伪造。这是一个很复杂的话题,细节不在这里赘述,只谈谈它是" -"什么以及如何在理论上避免这个问题。" +"Another big problem is CSRF. This is a very complex topic and I won't " +"outline it here in detail just mention what it is and how to " +"theoretically prevent it." +msgstr "另一个大问题是跨站请求伪造。这是一个很复杂的话题,细节不在这里赘述,只谈谈它是什么以及如何在理论上避免这个问题。" #: ../../security.rst:76 msgid "" -"If your authentication information is stored in cookies, you have implicit " -"state management. The state of \"being logged in\" is controlled by a cookie, " -"and that cookie is sent with each request to a page. Unfortunately that " -"includes requests triggered by 3rd party sites. If you don't keep that in " -"mind, some people might be able to trick your application's users with social " -"engineering to do stupid things without them knowing." +"If your authentication information is stored in cookies, you have " +"implicit state management. The state of \"being logged in\" is " +"controlled by a cookie, and that cookie is sent with each request to a " +"page. Unfortunately that includes requests triggered by 3rd party sites." +" If you don't keep that in mind, some people might be able to trick your" +" application's users with social engineering to do stupid things without " +"them knowing." msgstr "" -"如果你的认证信息存储在 cookie 中,你就有了隐式状态管理。“登录”的状态是由一个 " -"cookie 控制的,对每个页面的请求都会带上这个 cookie。不幸的是,由第三方网站发起的" -"请求也遵循同样的机制。如果你不牢记这一点,有人可能会用社交工程欺骗应用程序的用" -"户,让他们在不知情的情况下做一些愚蠢的事情。" +"如果你的认证信息存储在 cookie 中,你就有了隐式状态管理。“登录”的状态是由一个 cookie 控制的,对每个页面的请求都会带上这个 " +"cookie。不幸的是,由第三方网站发起的请求也遵循同样的机制。如果你不牢记这一点,有人可能会用社交工程欺骗应用程序的用户,让他们在不知情的情况下做一些愚蠢的事情。" #: ../../security.rst:84 msgid "" -"Say you have a specific URL that, when you sent ``POST`` requests to will " -"delete a user's profile (say ``http://example.com/user/delete``). If an " -"attacker now creates a page that sends a post request to that page with some " -"JavaScript they just have to trick some users to load that page and their " -"profiles will end up being deleted." +"Say you have a specific URL that, when you sent ``POST`` requests to will" +" delete a user's profile (say ``http://example.com/user/delete``). If an" +" attacker now creates a page that sends a post request to that page with " +"some JavaScript they just have to trick some users to load that page and " +"their profiles will end up being deleted." msgstr "" "假设你有一个特定的 URL,当你发送 ``POST`` 请求时会删除一个用户的资料(例如 " -"``http://example.com/user/delete``)。 如果攻击者现在创建了一个页面可以通过一些 " -"JavaScript 代码向你的特定 URL 发送 post 请求,只要欺骗用户来加载这个页面,用户资" -"料就会被删除了。" +"``http://example.com/user/delete``)。 如果攻击者现在创建了一个页面可以通过一些 JavaScript " +"代码向你的特定 URL 发送 post 请求,只要欺骗用户来加载这个页面,用户资料就会被删除了。" #: ../../security.rst:90 msgid "" -"Imagine you were to run Facebook with millions of concurrent users and someone " -"would send out links to images of little kittens. When users would go to that " -"page, their profiles would get deleted while they are looking at images of " -"fluffy cats." -msgstr "" -"想象一下有数百万并发用户的 Facebook,有人发出小猫咪图片的链接。 当用户访问该" -"页面看着毛茸茸的猫片时,他们的资料就被删除了。" +"Imagine you were to run Facebook with millions of concurrent users and " +"someone would send out links to images of little kittens. When users " +"would go to that page, their profiles would get deleted while they are " +"looking at images of fluffy cats." +msgstr "想象一下有数百万并发用户的 Facebook,有人发出小猫咪图片的链接。 当用户访问该页面看着毛茸茸的猫片时,他们的资料就被删除了。" #: ../../security.rst:95 msgid "" -"How can you prevent that? Basically for each request that modifies content on " -"the server you would have to either use a one-time token and store that in the " -"cookie **and** also transmit it with the form data. After receiving the data on " -"the server again, you would then have to compare the two tokens and ensure they " -"are equal." +"How can you prevent that? Basically for each request that modifies " +"content on the server you would have to either use a one-time token and " +"store that in the cookie **and** also transmit it with the form data. " +"After receiving the data on the server again, you would then have to " +"compare the two tokens and ensure they are equal." msgstr "" -"如何防止这种情况呢?基本思路是:每一个修改服务器内容的请求,必须使用一个" -"一次性令牌,并将其存储在 cookie 中,传输表单数据时带上它。服务器再次接收到数据" -"后,必须比较两个令牌,确保它们是相等的。" +"如何防止这种情况呢?基本思路是:每一个修改服务器内容的请求,必须使用一个一次性令牌,并将其存储在 cookie " +"中,传输表单数据时带上它。服务器再次接收到数据后,必须比较两个令牌,确保它们是相等的。" #: ../../security.rst:101 msgid "" -"Why does Flask not do that for you? The ideal place for this to happen is the " -"form validation framework, which does not exist in Flask." -msgstr "" -"为什么 Flask 不替你完成这个呢?因为这是表单验证框架要做的事,而 Flask 自身不包含" -"表单验证。" +"Why does Flask not do that for you? The ideal place for this to happen " +"is the form validation framework, which does not exist in Flask." +msgstr "为什么 Flask 不替你完成这个呢?因为这是表单验证框架要做的事,而 Flask 自身不包含表单验证。" #: ../../security.rst:107 msgid "JSON Security" @@ -206,24 +193,25 @@ msgstr "JSON 安全" #: ../../security.rst:109 msgid "" -"In Flask 0.10 and lower, :func:`~flask.jsonify` did not serialize top-level " -"arrays to JSON. This was because of a security vulnerability in ECMAScript 4." +"In Flask 0.10 and lower, :func:`~flask.jsonify` did not serialize top-" +"level arrays to JSON. This was because of a security vulnerability in " +"ECMAScript 4." msgstr "" "在 Flask 0.10 以及更低版本中,因为 ECMAScript 4 中的安全漏洞,:func:`~flask.jsonify` " "没有将顶层数组序列化为 JSON。" #: ../../security.rst:112 msgid "" -"ECMAScript 5 closed this vulnerability, so only extremely old browsers are " -"still vulnerable. All of these browsers have `other more serious " -"vulnerabilities `_, so this behavior was changed and :func:" -"`~flask.jsonify` now supports serializing arrays." +"ECMAScript 5 closed this vulnerability, so only extremely old browsers " +"are still vulnerable. All of these browsers have `other more serious " +"vulnerabilities " +"`_, so" +" this behavior was changed and :func:`~flask.jsonify` now supports " +"serializing arrays." msgstr "" -"ECMAScript 5 关闭了这个漏洞,所以只有非常老的浏览器仍然容易受到攻击,这些" -"浏览器还存在 `其他更严重的漏洞 `_,因而这个行为被改变了,:func:`~flask.jsonify` " -"现在支持序列化数组。" +"ECMAScript 5 关闭了这个漏洞,所以只有非常老的浏览器仍然容易受到攻击,这些浏览器还存在 `其他更严重的漏洞 " +"`_,因而这个行为被改变了,:func:`~flask.jsonify`" +" 现在支持序列化数组。" #: ../../security.rst:120 msgid "Security Headers" @@ -231,13 +219,13 @@ msgstr "安全头部" #: ../../security.rst:122 msgid "" -"Browsers recognize various response headers in order to control security. We " -"recommend reviewing each of the headers below for use in your application. The " -"`Flask-Talisman`_ extension can be used to manage HTTPS and the security " -"headers for you." +"Browsers recognize various response headers in order to control security." +" We recommend reviewing each of the headers below for use in your " +"application. The `Flask-Talisman`_ extension can be used to manage HTTPS " +"and the security headers for you." msgstr "" -"为了控制安全性,浏览器识别各种响应头部。我们建议你在应用程序中检查以下每种头" -"部,`Flask-Talisman`_ 扩展可用于管理 HTTPS 和安全头部。" +"为了控制安全性,浏览器识别各种响应头部。我们建议你在应用程序中检查以下每种头部,`Flask-Talisman`_ 扩展可用于管理 HTTPS " +"和安全头部。" #: ../../security.rst:130 msgid "HTTP Strict Transport Security (HSTS)" @@ -245,17 +233,17 @@ msgstr "HTTP 严格传输安全(HSTS)" #: ../../security.rst:132 msgid "" -"Tells the browser to convert all HTTP requests to HTTPS, preventing man-in-the-" -"middle (MITM) attacks. ::" +"Tells the browser to convert all HTTP requests to HTTPS, preventing man-" +"in-the-middle (MITM) attacks. ::" msgstr "指示浏览器把所有 HTTP 请求转为 HTTPS,防止中间人攻击(MITM)。" #: ../../security.rst:137 msgid "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-" -"Security" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-" +"Transport-Security" msgstr "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-" -"Security" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-" +"Transport-Security" #: ../../security.rst:142 msgid "Content Security Policy (CSP)" @@ -263,12 +251,10 @@ msgstr "内容安全策略(CSP)" #: ../../security.rst:144 msgid "" -"Tell the browser where it can load various types of resource from. This header " -"should be used whenever possible, but requires some work to define the correct " -"policy for your site. A very strict policy would be::" -msgstr "" -"告诉浏览器可以从哪里加载各种类型的资源。应当尽可能使用这个头部,但需要为网站定义" -"正确的策略。一个非常严格的策略是:" +"Tell the browser where it can load various types of resource from. This " +"header should be used whenever possible, but requires some work to define" +" the correct policy for your site. A very strict policy would be::" +msgstr "告诉浏览器可以从哪里加载各种类型的资源。应当尽可能使用这个头部,但需要为网站定义正确的策略。一个非常严格的策略是:" #: ../../security.rst:150 msgid "https://csp.withgoogle.com/docs/index.html" @@ -276,11 +262,11 @@ msgstr "https://csp.withgoogle.com/docs/index.html" #: ../../security.rst:151 msgid "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-" -"Policy" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-" +"Security-Policy" msgstr "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-" -"Policy" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-" +"Security-Policy" #: ../../security.rst:154 msgid "X-Content-Type-Options" @@ -288,17 +274,18 @@ msgstr "X-Content-Type-Options" #: ../../security.rst:156 msgid "" -"Forces the browser to honor the response content type instead of trying to " -"detect it, which can be abused to generate a cross-site scripting (XSS) " -"attack. ::" -msgstr "" -"强制浏览器接受响应的内容类型,而不是尝试检测它,防止被滥用而产生跨站脚本攻击(XSS)。" +"Forces the browser to honor the response content type instead of trying " +"to detect it, which can be abused to generate a cross-site scripting " +"(XSS) attack. ::" +msgstr "强制浏览器接受响应的内容类型,而不是尝试检测它,防止被滥用而产生跨站脚本攻击(XSS)。" #: ../../security.rst:162 msgid "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-" +"Options" msgstr "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options" +"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-" +"Options" #: ../../security.rst:165 msgid "X-Frame-Options" @@ -307,166 +294,161 @@ msgstr "X-Frame-Options" #: ../../security.rst:167 msgid "" "Prevents external sites from embedding your site in an ``iframe``. This " -"prevents a class of attacks where clicks in the outer frame can be translated " -"invisibly to clicks on your page's elements. This is also known as " -"\"clickjacking\". ::" -msgstr "" -"防止外部网站将你的网站嵌入 ``iframe`` 中,可以避免一类攻击:对外框的点击无形地转" -"化为对你的页面元素的点击。这也被称为“点击劫持”。" +"prevents a class of attacks where clicks in the outer frame can be " +"translated invisibly to clicks on your page's elements. This is also " +"known as \"clickjacking\". ::" +msgstr "防止外部网站将你的网站嵌入 ``iframe`` 中,可以避免一类攻击:对外框的点击无形地转化为对你的页面元素的点击。这也被称为“点击劫持”。" #: ../../security.rst:174 msgid "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options" msgstr "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options" -#: ../../security.rst:177 -msgid "X-XSS-Protection" -msgstr "X-XSS-Protection" - #: ../../security.rst:179 -msgid "" -"The browser will try to prevent reflected XSS attacks by not loading the page " -"if the request contains something that looks like JavaScript and the response " -"contains the same data. ::" -msgstr "" -"如果请求中含有一些类似 JavaScript 代码的东西,且响应中包含相同的数据,浏览器将试" -"图通过不加载页面来防止反射式 XSS 攻击。" - -#: ../../security.rst:185 -msgid "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection" -msgstr "" -"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection" - -#: ../../security.rst:191 msgid "Set-Cookie options" msgstr "Set-Cookie 选项" -#: ../../security.rst:193 +#: ../../security.rst:181 msgid "" "These options can be added to a ``Set-Cookie`` header to improve their " -"security. Flask has configuration options to set these on the session cookie. " -"They can be set on other cookies too." +"security. Flask has configuration options to set these on the session " +"cookie. They can be set on other cookies too." msgstr "" -"下面这些选项可以添加到 ``Set-Cookie`` 头部中以提高安全性。Flask 有配置选项可以将这" -"些设置在会话 cookie 或者其他 cookie 上。" +"下面这些选项可以添加到 ``Set-Cookie`` 头部中以提高安全性。Flask 有配置选项可以将这些设置在会话 cookie 或者其他 " +"cookie 上。" -#: ../../security.rst:197 +#: ../../security.rst:185 msgid "``Secure`` limits cookies to HTTPS traffic only." msgstr "``Secure`` 限制 cookies 只用于 HTTPS 流量。" -#: ../../security.rst:198 +#: ../../security.rst:186 msgid "" -"``HttpOnly`` protects the contents of cookies from being read with JavaScript." +"``HttpOnly`` protects the contents of cookies from being read with " +"JavaScript." msgstr "``HttpOnly`` 保护 cookies 内容不被 JavaScript 读取。" -#: ../../security.rst:200 +#: ../../security.rst:188 msgid "" -"``SameSite`` restricts how cookies are sent with requests from external sites. " -"Can be set to ``'Lax'`` (recommended) or ``'Strict'``. ``Lax`` prevents sending " -"cookies with CSRF-prone requests from external sites, such as submitting a " -"form. ``Strict`` prevents sending cookies with all external requests, including " -"following regular links." +"``SameSite`` restricts how cookies are sent with requests from external " +"sites. Can be set to ``'Lax'`` (recommended) or ``'Strict'``. ``Lax`` " +"prevents sending cookies with CSRF-prone requests from external sites, " +"such as submitting a form. ``Strict`` prevents sending cookies with all " +"external requests, including following regular links." msgstr "" -"``SameSite`` 限制 cookies 如何与外部网站的请求一起发送。可设置为 ``’Lax’``(推荐)" -"或 ``’Strict’``。``Lax`` 防止外部网站有 CSRF 请求倾向时(例如提交表单)发送 " -"cookies。``Strict`` 禁止所有外部请求发送 cookie,包括常规链接。" +"``SameSite`` 限制 cookies 如何与外部网站的请求一起发送。可设置为 ``’Lax’``(推荐)或 " +"``’Strict’``。``Lax`` 防止外部网站有 CSRF 请求倾向时(例如提交表单)发送 cookies。``Strict`` " +"禁止所有外部请求发送 cookie,包括常规链接。" -#: ../../security.rst:216 +#: ../../security.rst:204 msgid "" -"Specifying ``Expires`` or ``Max-Age`` options, will remove the cookie after the " -"given time, or the current time plus the age, respectively. If neither option " -"is set, the cookie will be removed when the browser is closed. ::" +"Specifying ``Expires`` or ``Max-Age`` options, will remove the cookie " +"after the given time, or the current time plus the age, respectively. If " +"neither option is set, the cookie will be removed when the browser is " +"closed. ::" msgstr "" -"指定 ``Expires`` 或 ``Max-Age`` 选项时,cookie 会在超过了给定的时间或当前时间加上" -"的期限之后被删除。如果两个选项都没有设置,cookie 将在浏览器关闭时被删除。" +"指定 ``Expires`` 或 ``Max-Age`` 选项时,cookie " +"会在超过了给定的时间或当前时间加上的期限之后被删除。如果两个选项都没有设置,cookie 将在浏览器关闭时被删除。" -#: ../../security.rst:223 +#: ../../security.rst:211 msgid "" -"For the session cookie, if :attr:`session.permanent ` " -"is set, then :data:`PERMANENT_SESSION_LIFETIME` is used to set the expiration. " -"Flask's default cookie implementation validates that the cryptographic " -"signature is not older than this value. Lowering this value may help mitigate " +"For the session cookie, if :attr:`session.permanent " +"` is set, then " +":data:`PERMANENT_SESSION_LIFETIME` is used to set the expiration. Flask's" +" default cookie implementation validates that the cryptographic signature" +" is not older than this value. Lowering this value may help mitigate " "replay attacks, where intercepted cookies can be sent at a later time. ::" msgstr "" -"对于会话 cookie,如果设置了 :attr:`session.permanent `," -"那么就用 :data:`PERMANENT_SESSION_LIFETIME` 设置到期时间,Flask 的" -"默认 cookie 实现会验证加密签名不超过这个值,降低此值有助于减少重复攻击,防止 " -"cookie 被拦截后还可以在一段时间内有效发送的漏洞。" +"对于会话 cookie,如果设置了 :attr:`session.permanent " +"`,那么就用 :data:`PERMANENT_SESSION_LIFETIME` " +"设置到期时间,Flask 的默认 cookie 实现会验证加密签名不超过这个值,降低此值有助于减少重复攻击,防止 cookie " +"被拦截后还可以在一段时间内有效发送的漏洞。" -#: ../../security.rst:241 +#: ../../security.rst:229 msgid "" -"Use :class:`itsdangerous.TimedSerializer` to sign and validate other cookie " -"values (or any values that need secure signatures)." -msgstr "" -"使用 :class:`itsdangerous.TimedSerializer` 来签名和验证其他 cookie 值(或任何需" -"要安全签名的值)。" +"Use :class:`itsdangerous.TimedSerializer` to sign and validate other " +"cookie values (or any values that need secure signatures)." +msgstr "使用 :class:`itsdangerous.TimedSerializer` 来签名和验证其他 cookie 值(或任何需要安全签名的值)。" -#: ../../security.rst:244 +#: ../../security.rst:232 msgid "https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies" msgstr "https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies" -#: ../../security.rst:245 +#: ../../security.rst:233 msgid "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie" msgstr "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie" -#: ../../security.rst:251 +#: ../../security.rst:239 msgid "HTTP Public Key Pinning (HPKP)" msgstr "HTTP 公钥锁定(HPKP)" -#: ../../security.rst:253 +#: ../../security.rst:241 msgid "" -"This tells the browser to authenticate with the server using only the specific " -"certificate key to prevent MITM attacks." +"This tells the browser to authenticate with the server using only the " +"specific certificate key to prevent MITM attacks." msgstr "它告诉浏览器只使用特定的证书密钥与服务器进行验证,以防止 MITM 攻击。" -#: ../../security.rst:257 +#: ../../security.rst:245 msgid "" -"Be careful when enabling this, as it is very difficult to undo if you set up or " -"upgrade your key incorrectly." +"Be careful when enabling this, as it is very difficult to undo if you set" +" up or upgrade your key incorrectly." msgstr "启用这个要小心,如果设置密钥或升级密钥不正确则难以撤销。" -#: ../../security.rst:260 +#: ../../security.rst:248 msgid "https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning" msgstr "https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning" -#: ../../security.rst:264 +#: ../../security.rst:252 msgid "Copy/Paste to Terminal" msgstr "复制/粘贴到终端" -#: ../../security.rst:266 +#: ../../security.rst:254 msgid "" -"Hidden characters such as the backspace character (``\\b``, ``^H``) can cause " -"text to render differently in HTML than how it is interpreted if `pasted into a " -"terminal `__." +"Hidden characters such as the backspace character (``\\b``, ``^H``) can " +"cause text to render differently in HTML than how it is interpreted if " +"`pasted into a terminal `__." msgstr "" -"隐藏的字符如退格符(``\\b``, ``^H``)会导致文本在 HTML 中的显示方式与 `粘贴到终" -"端 `__ 的呈现方式不同。" +"隐藏的字符如退格符(``\\b``, ``^H``)会导致文本在 HTML 中的显示方式与 `粘贴到终端 " +"`__ 的呈现方式不同。" -#: ../../security.rst:270 +#: ../../security.rst:258 msgid "" "For example, ``import y\\bose\\bm\\bi\\bt\\be\\b`` renders as ``import " -"yosemite`` in HTML, but the backspaces are applied when pasted into a terminal, " -"and it becomes ``import os``." +"yosemite`` in HTML, but the backspaces are applied when pasted into a " +"terminal, and it becomes ``import os``." msgstr "" "例如,``import y\\bose\\bm\\bi\\bt\\be\\b`` 在 HTML 中显示为 ``import " "yosemite``,但在粘贴到终端时退格符生效,变成 ``import os``." -#: ../../security.rst:274 +#: ../../security.rst:262 msgid "" -"If you expect users to copy and paste untrusted code from your site, such as " -"from comments posted by users on a technical blog, consider applying extra " -"filtering, such as replacing all ``\\b`` characters." -msgstr "" -"如果用户有可能从你的网站上复制和粘贴不受信任的代码,比如在技术博客上发布的评论," -"要考虑使用更多的过滤条件,例如替换所有 ``\\b`` 字符。" +"If you expect users to copy and paste untrusted code from your site, such" +" as from comments posted by users on a technical blog, consider applying " +"extra filtering, such as replacing all ``\\b`` characters." +msgstr "如果用户有可能从你的网站上复制和粘贴不受信任的代码,比如在技术博客上发布的评论,要考虑使用更多的过滤条件,例如替换所有 ``\\b`` 字符。" -#: ../../security.rst:282 +#: ../../security.rst:270 msgid "" "Most modern terminals will warn about and remove hidden characters when " "pasting, so this isn't strictly necessary. It's also possible to craft " -"dangerous commands in other ways that aren't possible to filter. Depending on " -"your site's use case, it may be good to show a warning about copying code in " -"general." -msgstr "" -"大多数现代终端在粘贴时都会警告并删除隐藏的字符,所以严格来说这并不是必须的。还有" -"以其他方式生成危险命令的可能,这些都是不可能完全过滤的。根据你的网站的使用情况来" -"做决定,复制代码时显示一个一般警告也是可以的。" +"dangerous commands in other ways that aren't possible to filter. " +"Depending on your site's use case, it may be good to show a warning about" +" copying code in general." +msgstr "大多数现代终端在粘贴时都会警告并删除隐藏的字符,所以严格来说这并不是必须的。还有以其他方式生成危险命令的可能,这些都是不可能完全过滤的。根据你的网站的使用情况来做决定,复制代码时显示一个一般警告也是可以的。" + +#~ msgid "X-XSS-Protection" +#~ msgstr "X-XSS-Protection" + +#~ msgid "" +#~ "The browser will try to prevent " +#~ "reflected XSS attacks by not loading " +#~ "the page if the request contains " +#~ "something that looks like JavaScript and" +#~ " the response contains the same data." +#~ " ::" +#~ msgstr "如果请求中含有一些类似 JavaScript 代码的东西,且响应中包含相同的数据,浏览器将试图通过不加载页面来防止反射式 XSS 攻击。" + +#~ msgid "" +#~ "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X" +#~ "-XSS-Protection" +#~ msgstr "" +#~ "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X" +#~ "-XSS-Protection" diff --git a/docs/locales/zh_CN/LC_MESSAGES/server.po b/docs/locales/zh_CN/LC_MESSAGES/server.po index 647e24d50..61d8c6448 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/server.po +++ b/docs/locales/zh_CN/LC_MESSAGES/server.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_CN \n" @@ -56,14 +56,18 @@ msgid "Bash" msgstr "" #: ../../server.rst:36 -msgid "CMD" +msgid "Fish" msgstr "" #: ../../server.rst:44 -msgid "Powershell" +msgid "CMD" msgstr "" #: ../../server.rst:52 +msgid "Powershell" +msgstr "" + +#: ../../server.rst:60 msgid "" "This enables the development environment, including the interactive " "debugger and reloader, and then starts the server on " @@ -72,7 +76,7 @@ msgid "" " using the CLI." msgstr "" -#: ../../server.rst:60 +#: ../../server.rst:68 msgid "" "Prior to Flask 1.0 the ``FLASK_ENV`` environment variable was not " "supported and you needed to enable debug mode by exporting " @@ -80,11 +84,64 @@ msgid "" "should prefer setting the development environment as shown above." msgstr "" -#: ../../server.rst:68 +#: ../../server.rst:78 +msgid "Address already in use" +msgstr "" + +#: ../../server.rst:80 +msgid "" +"If another program is already using port 5000, you'll see an ``OSError`` " +"when the server tries to start. It may have one of the following " +"messages:" +msgstr "" + +#: ../../server.rst:84 +msgid "``OSError: [Errno 98] Address already in use``" +msgstr "" + +#: ../../server.rst:85 +msgid "" +"``OSError: [WinError 10013] An attempt was made to access a socket in a " +"way forbidden by its access permissions``" +msgstr "" + +#: ../../server.rst:88 +msgid "" +"Either identify and stop the other program, or use ``flask run --port " +"5001`` to pick a different port." +msgstr "" + +#: ../../server.rst:91 +msgid "" +"You can use ``netstat`` or ``lsof`` to identify what process id is using " +"a port, then use other operating system tools stop that process. The " +"following example shows that process id 6847 is using port 5000." +msgstr "" + +#: ../../server.rst:97 +msgid "``netstat`` (Linux)" +msgstr "" + +#: ../../server.rst:104 +msgid "``lsof`` (macOS / Linux)" +msgstr "" + +#: ../../server.rst:111 +msgid "``netstat`` (Windows)" +msgstr "" + +#: ../../server.rst:118 +msgid "" +"macOS Monterey and later automatically starts a service that uses port " +"5000. To disable the service, go to System Preferences, Sharing, and " +"disable \"AirPlay Receiver\"." +msgstr "" + +#: ../../server.rst:124 msgid "Lazy or Eager Loading" msgstr "" -#: ../../server.rst:70 +#: ../../server.rst:126 msgid "" "When using the ``flask run`` command with the reloader, the server will " "continue to run even if you introduce syntax errors or other " @@ -93,7 +150,7 @@ msgid "" " feature is called \"lazy loading\"." msgstr "" -#: ../../server.rst:76 +#: ../../server.rst:132 msgid "" "If a syntax error is already present when calling ``flask run``, it will " "fail immediately and show the traceback rather than waiting until the " @@ -101,18 +158,18 @@ msgid "" "while still allowing the server to handle errors on reload." msgstr "" -#: ../../server.rst:81 +#: ../../server.rst:137 msgid "" "To override this behavior and always fail immediately, even on reload, " "pass the ``--eager-loading`` option. To always keep the server running, " "even on the initial call, pass ``--lazy-loading``." msgstr "" -#: ../../server.rst:87 +#: ../../server.rst:143 msgid "In Code" msgstr "" -#: ../../server.rst:89 +#: ../../server.rst:145 msgid "" "As an alternative to the ``flask run`` command, the development server " "can also be started from Python with the :meth:`Flask.run` method. This " @@ -121,14 +178,14 @@ msgid "" " there are errors when reloading." msgstr "" -#: ../../server.rst:95 +#: ../../server.rst:151 msgid "" "``debug=True`` can be passed to enable the debugger and reloader, but the" " ``FLASK_ENV=development`` environment variable is still required to " "fully enable development mode." msgstr "" -#: ../../server.rst:99 +#: ../../server.rst:155 msgid "" "Place the call in a main block, otherwise it will interfere when trying " "to import and run the application with a production server later." diff --git a/docs/locales/zh_CN/LC_MESSAGES/shell.po b/docs/locales/zh_CN/LC_MESSAGES/shell.po index 07cd5a29e..2becf83e6 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/shell.po +++ b/docs/locales/zh_CN/LC_MESSAGES/shell.po @@ -7,16 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: 2021-06-12 13:42+0800\n" +"Last-Translator: LTakamori \n" +"Language: zh_CN\n" "Language-Team: zh_CN \n" +"Plural-Forms: nplurals=1; plural=0\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.9.1\n" -"Last-Translator: LTakamori \n" -"Language: zh_CN\n" -"X-Generator: Poedit 3.0\n" #: ../../shell.rst:2 msgid "Working with the Shell" @@ -27,26 +27,23 @@ msgid "" "One of the reasons everybody loves Python is the interactive shell. It " "basically allows you to execute Python commands in real time and " "immediately get results back. Flask itself does not come with an " -"interactive shell, because it does not require any specific setup upfront, " -"just import your application and start playing around." +"interactive shell, because it does not require any specific setup " +"upfront, just import your application and start playing around." msgstr "" -"人们喜爱 Python 的原因之一就是它交互式的 shell。它基本上允许你实时地执行 " -"Python 指令并立即获得反馈结果。 Flask 本身并没有附带一个交互式的 shell,因为" -"它并不需要任何具体的前置条件,你只需要导入你的程序就可以愉快地玩耍了。" +"人们喜爱 Python 的原因之一就是它交互式的 shell。它基本上允许你实时地执行 Python 指令并立即获得反馈结果。 Flask " +"本身并没有附带一个交互式的 shell,因为它并不需要任何具体的前置条件,你只需要导入你的程序就可以愉快地玩耍了。" #: ../../shell.rst:12 msgid "" -"There are however some handy helpers to make playing around in the shell a " -"more pleasant experience. The main issue with interactive console sessions " -"is that you're not triggering a request like a browser does which means " -"that :data:`~flask.g`, :data:`~flask.request` and others are not " -"available. But the code you want to test might depend on them, so what can " -"you do?" +"There are however some handy helpers to make playing around in the shell " +"a more pleasant experience. The main issue with interactive console " +"sessions is that you're not triggering a request like a browser does " +"which means that :data:`~flask.g`, :data:`~flask.request` and others are " +"not available. But the code you want to test might depend on them, so " +"what can you do?" msgstr "" -"不过依然存在一些便利的辅助工具,它们使得你使用 shell 的体验更加愉快。交互式" -"的控制台中的主要问题是你不能像浏览器一样触发一个请求,即无法使用 :data:" -"`~flask.g`,:data:`~flask.request` 等对象。但假如你写的代码依赖它们来进行调" -"试,那么你应该怎么做呢?" +"不过依然存在一些便利的辅助工具,它们使得你使用 shell 的体验更加愉快。交互式的控制台中的主要问题是你不能像浏览器一样触发一个请求,即无法使用" +" :data:`~flask.g`,:data:`~flask.request` 等对象。但假如你写的代码依赖它们来进行调试,那么你应该怎么做呢?" #: ../../shell.rst:19 msgid "" @@ -54,132 +51,123 @@ msgid "" "that these functions are not only there for interactive shell usage, but " "also for unit testing and other situations that require a faked request " "context." -msgstr "" -"这就是一些辅助函数大展拳脚的场景了。不过请牢记,这些函数不仅适用于交互式 " -"shell 的场景下,还能用于单元测试以及其他需要伪造请求的情况。" +msgstr "这就是一些辅助函数大展拳脚的场景了。不过请牢记,这些函数不仅适用于交互式 shell 的场景下,还能用于单元测试以及其他需要伪造请求的情况。" #: ../../shell.rst:24 -msgid "" -"Generally it's recommended that you read the :doc:`reqcontext` chapter of " -"the documentation first." +#, fuzzy +msgid "Generally it's recommended that you read :doc:`reqcontext` first." msgstr "通常情况下建议先阅读 :doc:`reqcontext` 这一章节。" -#: ../../shell.rst:28 +#: ../../shell.rst:27 msgid "Command Line Interface" msgstr "命令行接口" -#: ../../shell.rst:30 +#: ../../shell.rst:29 msgid "" -"Starting with Flask 0.11 the recommended way to work with the shell is the " -"``flask shell`` command which does a lot of this automatically for you. For " -"instance the shell is automatically initialized with a loaded application " -"context." +"Starting with Flask 0.11 the recommended way to work with the shell is " +"the ``flask shell`` command which does a lot of this automatically for " +"you. For instance the shell is automatically initialized with a loaded " +"application context." msgstr "" -"自 Flask 0.11 开始,推荐使用 ``flask shell`` 命令来使用 shell ,它能为你自动" -"完成许多工作。比如自动地为你初始化一个 shell 并加载好应用上下文。" +"自 Flask 0.11 开始,推荐使用 ``flask shell`` 命令来使用 shell " +",它能为你自动完成许多工作。比如自动地为你初始化一个 shell 并加载好应用上下文。" -#: ../../shell.rst:35 +#: ../../shell.rst:34 msgid "For more information see :doc:`/cli`." msgstr "更多信息可以查阅 :doc:`/cli`。" -#: ../../shell.rst:38 +#: ../../shell.rst:37 msgid "Creating a Request Context" msgstr "创建一个请求上下文" -#: ../../shell.rst:40 +#: ../../shell.rst:39 msgid "" "The easiest way to create a proper request context from the shell is by " -"using the :attr:`~flask.Flask.test_request_context` method which creates us " -"a :class:`~flask.ctx.RequestContext`:" +"using the :attr:`~flask.Flask.test_request_context` method which creates " +"us a :class:`~flask.ctx.RequestContext`:" msgstr "" -"在 shell 中创建一个正确的请求上下文最简单的方法就是使用 :attr:`~flask.Flask." -"test_request_context` 方法,它能为我们创建一个 :class:`~flask.ctx." -"RequestContext`:" +"在 shell 中创建一个正确的请求上下文最简单的方法就是使用 :attr:`~flask.Flask.test_request_context`" +" 方法,它能为我们创建一个 :class:`~flask.ctx.RequestContext`:" -#: ../../shell.rst:46 +#: ../../shell.rst:45 msgid "" -"Normally you would use the ``with`` statement to make this request object " -"active, but in the shell it's easier to use the :meth:`~flask.ctx." -"RequestContext.push` and :meth:`~flask.ctx.RequestContext.pop` methods by " -"hand:" +"Normally you would use the ``with`` statement to make this request object" +" active, but in the shell it's easier to use the " +":meth:`~flask.ctx.RequestContext.push` and " +":meth:`~flask.ctx.RequestContext.pop` methods by hand:" msgstr "" -"通常来说你会使用 ``with`` 语句来激活请求对象,不过在 shell 中更方便的做法是" -"手动调用 :meth:`~flask.ctx.RequestContext.push` 和 :meth:`~flask.ctx." -"RequestContext.pop` 方法:" +"通常来说你会使用 ``with`` 语句来激活请求对象,不过在 shell 中更方便的做法是手动调用 " +":meth:`~flask.ctx.RequestContext.push` 和 " +":meth:`~flask.ctx.RequestContext.pop` 方法:" -#: ../../shell.rst:53 +#: ../../shell.rst:52 msgid "" -"From that point onwards you can work with the request object until you call " -"`pop`:" +"From that point onwards you can work with the request object until you " +"call `pop`:" msgstr "从这时开始,直到调用 `pop` 之前,你可以使用请求对象:" -#: ../../shell.rst:59 +#: ../../shell.rst:58 msgid "Firing Before/After Request" msgstr "触发请求前/后的动作" -#: ../../shell.rst:61 +#: ../../shell.rst:60 msgid "" -"By just creating a request context, you still don't have run the code that " -"is normally run before a request. This might result in your database being " -"unavailable if you are connecting to the database in a before-request " -"callback or the current user not being stored on the :data:`~flask.g` " -"object etc." +"By just creating a request context, you still don't have run the code " +"that is normally run before a request. This might result in your " +"database being unavailable if you are connecting to the database in a " +"before-request callback or the current user not being stored on the " +":data:`~flask.g` object etc." msgstr "" -"仅仅创建请求上下文还不够,你还没有执行请求前的一般会执行的动作。假如在请求前" -"的钩子中包含了连接数据库的操作,这会导致你的数据库仍不可用,这么做还有可能导" -"致当前用户没有被存储在 :data:`~flask.g` 中等一系列错误。" +"仅仅创建请求上下文还不够,你还没有执行请求前的一般会执行的动作。假如在请求前的钩子中包含了连接数据库的操作,这会导致你的数据库仍不可用,这么做还有可能导致当前用户没有被存储在" +" :data:`~flask.g` 中等一系列错误。" -#: ../../shell.rst:67 +#: ../../shell.rst:66 msgid "" -"This however can easily be done yourself. Just call :meth:`~flask.Flask." -"preprocess_request`:" -msgstr "" -"我们可以很轻松地解决这个问题。只要调用 :meth:`~flask.Flask." -"preprocess_request` 就可以了:" +"This however can easily be done yourself. Just call " +":meth:`~flask.Flask.preprocess_request`:" +msgstr "我们可以很轻松地解决这个问题。只要调用 :meth:`~flask.Flask.preprocess_request` 就可以了:" -#: ../../shell.rst:74 +#: ../../shell.rst:73 msgid "" "Keep in mind that the :meth:`~flask.Flask.preprocess_request` function " "might return a response object, in that case just ignore it." msgstr "" -"请记住,:meth:`~flask.Flask.preprocess_request` 函数可能会返回一个响应对象," -"但在这种情况下,忽略这个返回值就好了。" +"请记住,:meth:`~flask.Flask.preprocess_request` " +"函数可能会返回一个响应对象,但在这种情况下,忽略这个返回值就好了。" -#: ../../shell.rst:77 +#: ../../shell.rst:76 msgid "" "To shutdown a request, you need to trick a bit before the after request " -"functions (triggered by :meth:`~flask.Flask.process_response`) operate on a " -"response object:" +"functions (triggered by :meth:`~flask.Flask.process_response`) operate on" +" a response object:" msgstr "" -"如果要关闭一个请求,你需要在请求后钩子函数(由 :meth:`~flask.Flask." -"process_response` 触发)作用于响应对象前将它关闭:" +"如果要关闭一个请求,你需要在请求后钩子函数(由 :meth:`~flask.Flask.process_response` " +"触发)作用于响应对象前将它关闭:" -#: ../../shell.rst:85 +#: ../../shell.rst:84 msgid "" "The functions registered as :meth:`~flask.Flask.teardown_request` are " "automatically called when the context is popped. So this is the perfect " -"place to automatically tear down resources that were needed by the request " -"context (such as database connections)." +"place to automatically tear down resources that were needed by the " +"request context (such as database connections)." msgstr "" -"注册为 :meth:`~flask.Flask.teardown_request` 的函数会在请求上下文弹出后自动" -"执行。所以,在这里释放之前由请求上下文申请的资源(比如数据库连接)就相当合适" -"了。" +"注册为 :meth:`~flask.Flask.teardown_request` " +"的函数会在请求上下文弹出后自动执行。所以,在这里释放之前由请求上下文申请的资源(比如数据库连接)就相当合适了。" -#: ../../shell.rst:92 +#: ../../shell.rst:91 msgid "Further Improving the Shell Experience" msgstr "提升 Shell 使用体验" -#: ../../shell.rst:94 +#: ../../shell.rst:93 msgid "" -"If you like the idea of experimenting in a shell, create yourself a module " -"with stuff you want to star import into your interactive session. There " -"you could also define some more helper methods for common things such as " -"initializing the database, dropping tables etc." +"If you like the idea of experimenting in a shell, create yourself a " +"module with stuff you want to star import into your interactive session." +" There you could also define some more helper methods for common things " +"such as initializing the database, dropping tables etc." msgstr "" -"如果你喜欢使用 shell 的感觉,你还可以为你自己创建一个包含你想要全部导入内容" -"的模块。你可以在那里定义一些操纵常见资源的辅助方法,比如初始化数据库,删除表" -"等等。" +"如果你喜欢使用 shell " +"的感觉,你还可以为你自己创建一个包含你想要全部导入内容的模块。你可以在那里定义一些操纵常见资源的辅助方法,比如初始化数据库,删除表等等。" -#: ../../shell.rst:99 +#: ../../shell.rst:98 msgid "Just put them into a module (like `shelltools`) and import from there:" msgstr "你只需将它们放入一个模块(比如 `shelltools`)并将其导入即可:" diff --git a/docs/locales/zh_CN/LC_MESSAGES/templating.po b/docs/locales/zh_CN/LC_MESSAGES/templating.po index c93ab258a..f187877d0 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/templating.po +++ b/docs/locales/zh_CN/LC_MESSAGES/templating.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_CN \n" @@ -81,7 +81,7 @@ msgid "" msgstr "" #: ../../templating.rst:40 -msgid "The current configuration object (:data:`flask.config`)" +msgid "The current configuration object (:data:`flask.Flask.config`)" msgstr "" #: ../../templating.rst:44 @@ -271,3 +271,6 @@ msgid "" ":`registering-filters`), but this demonstrates how to pass functions in a" " context processor." msgstr "" + +#~ msgid "The current configuration object (:data:`flask.config`)" +#~ msgstr "" diff --git a/docs/locales/zh_CN/LC_MESSAGES/testing.po b/docs/locales/zh_CN/LC_MESSAGES/testing.po index c5a2c0f9e..1e0914b18 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/testing.po +++ b/docs/locales/zh_CN/LC_MESSAGES/testing.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_CN \n" @@ -22,361 +22,679 @@ msgid "Testing Flask Applications" msgstr "" #: ../../testing.rst:4 -msgid "**Something that is untested is broken.**" -msgstr "" - -#: ../../testing.rst:6 msgid "" -"The origin of this quote is unknown and while it is not entirely correct," -" it is also not far from the truth. Untested applications make it hard " -"to improve existing code and developers of untested applications tend to " -"become pretty paranoid. If an application has automated tests, you can " -"safely make changes and instantly know if anything breaks." +"Flask provides utilities for testing an application. This documentation " +"goes over techniques for working with different parts of the application " +"in tests." msgstr "" -#: ../../testing.rst:12 -msgid "" -"Flask provides a way to test your application by exposing the Werkzeug " -"test :class:`~werkzeug.test.Client` and handling the context locals for " -"you. You can then use that with your favourite testing solution." +#: ../../testing.rst:8 +msgid "We will use the `pytest`_ framework to set up and run our tests." msgstr "" #: ../../testing.rst:16 +#, python-format msgid "" -"In this documentation we will use the `pytest`_ package as the base " -"framework for our tests. You can install it with ``pip``, like so::" +"The :doc:`tutorial ` goes over how to write tests for " +"100% coverage of the sample Flaskr blog application. See :doc:`the " +"tutorial on tests ` for a detailed explanation of " +"specific tests for an application." msgstr "" -#: ../../testing.rst:24 -msgid "The Application" +#: ../../testing.rst:23 +msgid "Identifying Tests" msgstr "" -#: ../../testing.rst:26 +#: ../../testing.rst:25 msgid "" -"First, we need an application to test; we will use the application from " -"the :doc:`tutorial/index`. If you don't have that application yet, get " -"the source code from :gh:`the examples `." +"Tests are typically located in the ``tests`` folder. Tests are functions " +"that start with ``test_``, in Python modules that start with ``test_``. " +"Tests can also be further grouped in classes that start with ``Test``." msgstr "" -#: ../../testing.rst:30 +#: ../../testing.rst:29 msgid "" -"So that we can import the module ``flaskr`` correctly, we need to run " -"``pip install -e .`` in the folder ``tutorial``." -msgstr "" - -#: ../../testing.rst:34 -msgid "The Testing Skeleton" +"It can be difficult to know what to test. Generally, try to test the code" +" that you write, not the code of libraries that you use, since they are " +"already tested. Try to extract complex behaviors as separate functions to" +" test individually." msgstr "" #: ../../testing.rst:36 -msgid "" -"We begin by adding a tests directory under the application root. Then " -"create a Python file to store our tests (:file:`test_flaskr.py`). When we" -" format the filename like ``test_*.py``, it will be auto-discoverable by " -"pytest." -msgstr "" - -#: ../../testing.rst:41 -msgid "" -"Next, we create a `pytest fixture`_ called :func:`client` that configures" -" the application for testing and initializes a new database::" +msgid "Fixtures" msgstr "" -#: ../../testing.rst:66 +#: ../../testing.rst:38 msgid "" -"This client fixture will be called by each individual test. It gives us " -"a simple interface to the application, where we can trigger test requests" -" to the application. The client will also keep track of cookies for us." +"Pytest *fixtures* allow writing pieces of code that are reusable across " +"tests. A simple fixture returns a value, but a fixture can also do setup," +" yield a value, then do teardown. Fixtures for the application, test " +"client, and CLI runner are shown below, they can be placed in " +"``tests/conftest.py``." msgstr "" -#: ../../testing.rst:70 +#: ../../testing.rst:44 msgid "" -"During setup, the ``TESTING`` config flag is activated. What this does " -"is disable error catching during request handling, so that you get better" -" error reports when performing test requests against the application." +"If you're using an :doc:`application factory `, " +"define an ``app`` fixture to create and configure an app instance. You " +"can add code before and after the ``yield`` to set up and tear down other" +" resources, such as creating and clearing a database." msgstr "" -#: ../../testing.rst:75 +#: ../../testing.rst:50 msgid "" -"Because SQLite3 is filesystem-based, we can easily use the " -":mod:`tempfile` module to create a temporary database and initialize it. " -"The :func:`~tempfile.mkstemp` function does two things for us: it returns" -" a low-level file handle and a random file name, the latter we use as " -"database name. We just have to keep the `db_fd` around so that we can " -"use the :func:`os.close` function to close the file." +"If you're not using a factory, you already have an app object you can " +"import and configure directly. You can still use an ``app`` fixture to " +"set up and tear down resources." msgstr "" -#: ../../testing.rst:82 -msgid "" -"To delete the database after the test, the fixture closes the file and " -"removes it from the filesystem." -msgstr "" - -#: ../../testing.rst:85 -msgid "If we now run the test suite, we should see the following output::" +#: ../../testing.rst:84 +msgid "Sending Requests with the Test Client" msgstr "" -#: ../../testing.rst:95 +#: ../../testing.rst:86 msgid "" -"Even though it did not run any actual tests, we already know that our " -"``flaskr`` application is syntactically valid, otherwise the import would" -" have died with an exception." -msgstr "" - -#: ../../testing.rst:103 -msgid "The First Test" +"The test client makes requests to the application without running a live " +"server. Flask's client extends :doc:`Werkzeug's client `, " +"see those docs for additional information." msgstr "" -#: ../../testing.rst:105 +#: ../../testing.rst:91 msgid "" -"Now it's time to start testing the functionality of the application. " -"Let's check that the application shows \"No entries here so far\" if we " -"access the root of the application (``/``). To do this, we add a new " -"test function to :file:`test_flaskr.py`, like this::" +"The ``client`` has methods that match the common HTTP request methods, " +"such as ``client.get()`` and ``client.post()``. They take many arguments " +"for building the request; you can find the full documentation in " +":class:`~werkzeug.test.EnvironBuilder`. Typically you'll use ``path``, " +"``query_string``, ``headers``, and ``data`` or ``json``." msgstr "" -#: ../../testing.rst:116 +#: ../../testing.rst:97 msgid "" -"Notice that our test functions begin with the word `test`; this allows " -"`pytest`_ to automatically identify the function as a test to run." +"To make a request, call the method the request should use with the path " +"to the route to test. A :class:`~werkzeug.test.TestResponse` is returned " +"to examine the response data. It has all the usual properties of a " +"response object. You'll usually look at ``response.data``, which is the " +"bytes returned by the view. If you want to use text, Werkzeug 2.1 " +"provides ``response.text``, or use ``response.get_data(as_text=True)``." msgstr "" -#: ../../testing.rst:119 +#: ../../testing.rst:111 msgid "" -"By using ``client.get`` we can send an HTTP ``GET`` request to the " -"application with the given path. The return value will be a " -":class:`~flask.Flask.response_class` object. We can now use the " -":attr:`~werkzeug.wrappers.Response.data` attribute to inspect the return " -"value (as string) from the application. In this case, we ensure that " -"``'No entries here so far'`` is part of the output." +"Pass a dict ``query_string={\"key\": \"value\", ...}`` to set arguments " +"in the query string (after the ``?`` in the URL). You can also pass a " +"string if you want to set a specific value directly." msgstr "" -#: ../../testing.rst:127 -msgid "Run it again and you should see one passing test::" +#: ../../testing.rst:115 +msgid "Pass a dict to ``headers={}`` to set request headers." msgstr "" -#: ../../testing.rst:140 -msgid "Logging In and Out" -msgstr "" - -#: ../../testing.rst:142 +#: ../../testing.rst:117 msgid "" -"The majority of the functionality of our application is only available " -"for the administrative user, so we need a way to log our test client in " -"and out of the application. To do this, we fire some requests to the " -"login and logout pages with the required form data (username and " -"password). And because the login and logout pages redirect, we tell the " -"client to `follow_redirects`." +"To send a request body in a POST or PUT request, pass a value to " +"``data``. If raw bytes are passed, that exact body is used. Usually, " +"you'll pass a dict to set form data." msgstr "" -#: ../../testing.rst:148 -msgid "Add the following two functions to your :file:`test_flaskr.py` file::" +#: ../../testing.rst:123 +msgid "Form Data" msgstr "" -#: ../../testing.rst:160 +#: ../../testing.rst:125 msgid "" -"Now we can easily test that logging in and out works and that it fails " -"with invalid credentials. Add this new test function::" +"To send form data, pass a dict to ``data``. The ``Content-Type`` header " +"will be set to ``multipart/form-data`` or ``application/x-www-form-" +"urlencoded`` automatically." msgstr "" -#: ../../testing.rst:182 -msgid "Test Adding Messages" -msgstr "" - -#: ../../testing.rst:184 +#: ../../testing.rst:129 msgid "" -"We should also test that adding messages works. Add a new test function " -"like this::" +"If a value is a file object opened for reading bytes (``\"rb\"`` mode), " +"it will be treated as an uploaded file. To change the detected filename " +"and content type, pass a ``(file, filename, content_type)`` tuple. File " +"objects will be closed after making the request, so they do not need to " +"use the usual ``with open() as f:`` pattern." msgstr "" -#: ../../testing.rst:199 +#: ../../testing.rst:135 msgid "" -"Here we check that HTML is allowed in the text but not in the title, " -"which is the intended behavior." -msgstr "" - -#: ../../testing.rst:202 -msgid "Running that should now give us three passing tests::" +"It can be useful to store files in a ``tests/resources`` folder, then use" +" ``pathlib.Path`` to get files relative to the current test file." msgstr "" -#: ../../testing.rst:218 -msgid "Other Testing Tricks" +#: ../../testing.rst:155 +msgid "JSON Data" msgstr "" -#: ../../testing.rst:220 -msgid "" -"Besides using the test client as shown above, there is also the " -":meth:`~flask.Flask.test_request_context` method that can be used in " -"combination with the ``with`` statement to activate a request context " -"temporarily. With this you can access the :class:`~flask.request`, " -":class:`~flask.g` and :class:`~flask.session` objects like in view " -"functions. Here is a full example that demonstrates this approach::" -msgstr "" - -#: ../../testing.rst:235 -msgid "All the other objects that are context bound can be used in the same way." -msgstr "" - -#: ../../testing.rst:238 -msgid "" -"If you want to test your application with different configurations and " -"there does not seem to be a good way to do that, consider switching to " -"application factories (see :doc:`patterns/appfactories`)." -msgstr "" - -#: ../../testing.rst:242 -msgid "" -"Note however that if you are using a test request context, the " -":meth:`~flask.Flask.before_request` and " -":meth:`~flask.Flask.after_request` functions are not called " -"automatically. However :meth:`~flask.Flask.teardown_request` functions " -"are indeed executed when the test request context leaves the ``with`` " -"block. If you do want the :meth:`~flask.Flask.before_request` functions " -"to be called as well, you need to call " -":meth:`~flask.Flask.preprocess_request` yourself::" -msgstr "" - -#: ../../testing.rst:256 +#: ../../testing.rst:157 msgid "" -"This can be necessary to open database connections or something similar " -"depending on how your application was designed." +"To send JSON data, pass an object to ``json``. The ``Content-Type`` " +"header will be set to ``application/json`` automatically." msgstr "" -#: ../../testing.rst:259 -msgid "" -"If you want to call the :meth:`~flask.Flask.after_request` functions you " -"need to call into :meth:`~flask.Flask.process_response` which however " -"requires that you pass it a response object::" -msgstr "" - -#: ../../testing.rst:270 -msgid "" -"This in general is less useful because at that point you can directly " -"start using the test client." -msgstr "" - -#: ../../testing.rst:276 -msgid "Faking Resources and Context" -msgstr "" - -#: ../../testing.rst:280 -msgid "" -"A very common pattern is to store user authorization information and " -"database connections on the application context or the :attr:`flask.g` " -"object. The general pattern for this is to put the object on there on " -"first usage and then to remove it on a teardown. Imagine for instance " -"this code to get the current user::" -msgstr "" - -#: ../../testing.rst:293 -msgid "" -"For a test it would be nice to override this user from the outside " -"without having to change some code. This can be accomplished with " -"hooking the :data:`flask.appcontext_pushed` signal::" -msgstr "" - -#: ../../testing.rst:307 -msgid "And then to use it::" -msgstr "" - -#: ../../testing.rst:323 -msgid "Keeping the Context Around" -msgstr "" - -#: ../../testing.rst:327 -msgid "" -"Sometimes it is helpful to trigger a regular request but still keep the " -"context around for a little longer so that additional introspection can " -"happen. With Flask 0.4 this is possible by using the " -":meth:`~flask.Flask.test_client` with a ``with`` block::" -msgstr "" - -#: ../../testing.rst:338 +#: ../../testing.rst:160 msgid "" -"If you were to use just the :meth:`~flask.Flask.test_client` without the " -"``with`` block, the ``assert`` would fail with an error because `request`" -" is no longer available (because you are trying to use it outside of the " -"actual request)." -msgstr "" - -#: ../../testing.rst:345 -msgid "Accessing and Modifying Sessions" +"Similarly, if the response contains JSON data, the ``response.json`` " +"attribute will contain the deserialized object." msgstr "" -#: ../../testing.rst:349 -msgid "" -"Sometimes it can be very helpful to access or modify the sessions from " -"the test client. Generally there are two ways for this. If you just " -"want to ensure that a session has certain keys set to certain values you " -"can just keep the context around and access :data:`flask.session`::" +#: ../../testing.rst:182 +msgid "Following Redirects" msgstr "" -#: ../../testing.rst:358 +#: ../../testing.rst:184 msgid "" -"This however does not make it possible to also modify the session or to " -"access the session before a request was fired. Starting with Flask 0.8 " -"we provide a so called “session transaction” which simulates the " -"appropriate calls to open a session in the context of the test client and" -" to modify it. At the end of the transaction the session is stored and " -"ready to be used by the test client. This works independently of the " -"session backend used::" +"By default, the client does not make additional requests if the response " +"is a redirect. By passing ``follow_redirects=True`` to a request method, " +"the client will continue to make requests until a non-redirect response " +"is returned." msgstr "" -#: ../../testing.rst:372 +#: ../../testing.rst:189 msgid "" -"Note that in this case you have to use the ``sess`` object instead of the" -" :data:`flask.session` proxy. The object however itself will provide the" -" same interface." +":attr:`TestResponse.history ` is a " +"tuple of the responses that led up to the final response. Each response " +"has a :attr:`~werkzeug.test.TestResponse.request` attribute which records" +" the request that produced that response." msgstr "" -#: ../../testing.rst:378 -msgid "Testing JSON APIs" +#: ../../testing.rst:205 +msgid "Accessing and Modifying the Session" msgstr "" -#: ../../testing.rst:382 +#: ../../testing.rst:207 msgid "" -"Flask has great support for JSON, and is a popular choice for building " -"JSON APIs. Making requests with JSON data and examining JSON data in " -"responses is very convenient::" +"To access Flask's context variables, mainly :data:`~flask.session`, use " +"the client in a ``with`` statement. The app and request context will " +"remain active *after* making a request, until the ``with`` block ends." msgstr "" -#: ../../testing.rst:402 +#: ../../testing.rst:224 msgid "" -"Passing the ``json`` argument in the test client methods sets the request" -" data to the JSON-serialized object and sets the content type to " -"``application/json``. You can get the JSON data from the request or " -"response with ``get_json``." +"If you want to access or set a value in the session *before* making a " +"request, use the client's " +":meth:`~flask.testing.FlaskClient.session_transaction` method in a " +"``with`` statement. It returns a session object, and will save the " +"session once the block ends." msgstr "" -#: ../../testing.rst:411 -msgid "Testing CLI Commands" +#: ../../testing.rst:248 +msgid "Running Commands with the CLI Runner" msgstr "" -#: ../../testing.rst:413 +#: ../../testing.rst:250 msgid "" -"Click comes with `utilities for testing`_ your CLI commands. A " -":class:`~click.testing.CliRunner` runs commands in isolation and captures" -" the output in a :class:`~click.testing.Result` object." +"Flask provides :meth:`~flask.Flask.test_cli_runner` to create a " +":class:`~flask.testing.FlaskCliRunner`, which runs CLI commands in " +"isolation and captures the output in a :class:`~click.testing.Result` " +"object. Flask's runner extends :doc:`Click's runner `, see" +" those docs for additional information." msgstr "" -#: ../../testing.rst:417 +#: ../../testing.rst:256 msgid "" -"Flask provides :meth:`~flask.Flask.test_cli_runner` to create a " -":class:`~flask.testing.FlaskCliRunner` that passes the Flask app to the " -"CLI automatically. Use its :meth:`~flask.testing.FlaskCliRunner.invoke` " -"method to call commands in the same way they would be called from the " -"command line. ::" +"Use the runner's :meth:`~flask.testing.FlaskCliRunner.invoke` method to " +"call commands in the same way they would be called with the ``flask`` " +"command from the command line." msgstr "" -#: ../../testing.rst:441 -msgid "" -"In the example above, invoking the command by name is useful because it " -"verifies that the command was correctly registered with the app." +#: ../../testing.rst:278 +msgid "Tests that depend on an Active Context" msgstr "" -#: ../../testing.rst:444 +#: ../../testing.rst:280 msgid "" -"If you want to test how your command parses parameters, without running " -"the command, use its :meth:`~click.BaseCommand.make_context` method. This" -" is useful for testing complex validation rules and custom types. ::" -msgstr "" +"You may have functions that are called from views or commands, that " +"expect an active :doc:`application context ` or " +":doc:`request context ` because they access ``request``, " +"``session``, or ``current_app``. Rather than testing them by making a " +"request or invoking the command, you can create and activate a context " +"directly." +msgstr "" + +#: ../../testing.rst:287 +msgid "" +"Use ``with app.app_context()`` to push an application context. For " +"example, database extensions usually require an active app context to " +"make queries." +msgstr "" + +#: ../../testing.rst:297 +msgid "" +"Use ``with app.test_request_context()`` to push a request context. It " +"takes the same arguments as the test client's request methods." +msgstr "" + +#: ../../testing.rst:311 +msgid "" +"Creating a test request context doesn't run any of the Flask dispatching " +"code, so ``before_request`` functions are not called. If you need to call" +" these, usually it's better to make a full request instead. However, it's" +" possible to call them manually." +msgstr "" + +#~ msgid "**Something that is untested is broken.**" +#~ msgstr "" + +#~ msgid "" +#~ "The origin of this quote is " +#~ "unknown and while it is not " +#~ "entirely correct, it is also not " +#~ "far from the truth. Untested " +#~ "applications make it hard to improve " +#~ "existing code and developers of untested" +#~ " applications tend to become pretty " +#~ "paranoid. If an application has " +#~ "automated tests, you can safely make " +#~ "changes and instantly know if anything" +#~ " breaks." +#~ msgstr "" + +#~ msgid "" +#~ "Flask provides a way to test your" +#~ " application by exposing the Werkzeug " +#~ "test :class:`~werkzeug.test.Client` and handling " +#~ "the context locals for you. You " +#~ "can then use that with your " +#~ "favourite testing solution." +#~ msgstr "" + +#~ msgid "" +#~ "In this documentation we will use " +#~ "the `pytest`_ package as the base " +#~ "framework for our tests. You can " +#~ "install it with ``pip``, like so::" +#~ msgstr "" + +#~ msgid "The Application" +#~ msgstr "" + +#~ msgid "" +#~ "First, we need an application to " +#~ "test; we will use the application " +#~ "from the :doc:`tutorial/index`. If you " +#~ "don't have that application yet, get " +#~ "the source code from :gh:`the examples" +#~ " `." +#~ msgstr "" + +#~ msgid "" +#~ "So that we can import the module" +#~ " ``flaskr`` correctly, we need to run" +#~ " ``pip install -e .`` in the " +#~ "folder ``tutorial``." +#~ msgstr "" + +#~ msgid "The Testing Skeleton" +#~ msgstr "" + +#~ msgid "" +#~ "We begin by adding a tests " +#~ "directory under the application root. " +#~ "Then create a Python file to store" +#~ " our tests (:file:`test_flaskr.py`). When " +#~ "we format the filename like " +#~ "``test_*.py``, it will be auto-" +#~ "discoverable by pytest." +#~ msgstr "" + +#~ msgid "" +#~ "Next, we create a `pytest fixture`_ " +#~ "called :func:`client` that configures the " +#~ "application for testing and initializes " +#~ "a new database::" +#~ msgstr "" + +#~ msgid "" +#~ "This client fixture will be called " +#~ "by each individual test. It gives " +#~ "us a simple interface to the " +#~ "application, where we can trigger test" +#~ " requests to the application. The " +#~ "client will also keep track of " +#~ "cookies for us." +#~ msgstr "" + +#~ msgid "" +#~ "During setup, the ``TESTING`` config " +#~ "flag is activated. What this does " +#~ "is disable error catching during request" +#~ " handling, so that you get better " +#~ "error reports when performing test " +#~ "requests against the application." +#~ msgstr "" + +#~ msgid "" +#~ "Because SQLite3 is filesystem-based, we" +#~ " can easily use the :mod:`tempfile` " +#~ "module to create a temporary database" +#~ " and initialize it. The " +#~ ":func:`~tempfile.mkstemp` function does two " +#~ "things for us: it returns a " +#~ "low-level file handle and a random" +#~ " file name, the latter we use " +#~ "as database name. We just have to" +#~ " keep the `db_fd` around so that " +#~ "we can use the :func:`os.close` function" +#~ " to close the file." +#~ msgstr "" + +#~ msgid "" +#~ "To delete the database after the " +#~ "test, the fixture closes the file " +#~ "and removes it from the filesystem." +#~ msgstr "" + +#~ msgid "If we now run the test suite, we should see the following output::" +#~ msgstr "" + +#~ msgid "" +#~ "Even though it did not run any " +#~ "actual tests, we already know that " +#~ "our ``flaskr`` application is syntactically" +#~ " valid, otherwise the import would " +#~ "have died with an exception." +#~ msgstr "" + +#~ msgid "The First Test" +#~ msgstr "" + +#~ msgid "" +#~ "Now it's time to start testing the" +#~ " functionality of the application. Let's" +#~ " check that the application shows " +#~ "\"No entries here so far\" if we" +#~ " access the root of the application" +#~ " (``/``). To do this, we add a" +#~ " new test function to " +#~ ":file:`test_flaskr.py`, like this::" +#~ msgstr "" + +#~ msgid "" +#~ "Notice that our test functions begin " +#~ "with the word `test`; this allows " +#~ "`pytest`_ to automatically identify the " +#~ "function as a test to run." +#~ msgstr "" + +#~ msgid "" +#~ "By using ``client.get`` we can send " +#~ "an HTTP ``GET`` request to the " +#~ "application with the given path. The" +#~ " return value will be a " +#~ ":class:`~flask.Flask.response_class` object. We can" +#~ " now use the " +#~ ":attr:`~werkzeug.wrappers.Response.data` attribute to " +#~ "inspect the return value (as string) " +#~ "from the application. In this case, " +#~ "we ensure that ``'No entries here " +#~ "so far'`` is part of the output." +#~ msgstr "" + +#~ msgid "Run it again and you should see one passing test::" +#~ msgstr "" + +#~ msgid "Logging In and Out" +#~ msgstr "" + +#~ msgid "" +#~ "The majority of the functionality of " +#~ "our application is only available for" +#~ " the administrative user, so we need" +#~ " a way to log our test client" +#~ " in and out of the application. " +#~ "To do this, we fire some requests" +#~ " to the login and logout pages " +#~ "with the required form data (username" +#~ " and password). And because the " +#~ "login and logout pages redirect, we " +#~ "tell the client to `follow_redirects`." +#~ msgstr "" + +#~ msgid "Add the following two functions to your :file:`test_flaskr.py` file::" +#~ msgstr "" + +#~ msgid "" +#~ "Now we can easily test that " +#~ "logging in and out works and that" +#~ " it fails with invalid credentials. " +#~ "Add this new test function::" +#~ msgstr "" + +#~ msgid "Test Adding Messages" +#~ msgstr "" + +#~ msgid "" +#~ "We should also test that adding " +#~ "messages works. Add a new test " +#~ "function like this::" +#~ msgstr "" + +#~ msgid "" +#~ "Here we check that HTML is allowed" +#~ " in the text but not in the " +#~ "title, which is the intended behavior." +#~ msgstr "" + +#~ msgid "Running that should now give us three passing tests::" +#~ msgstr "" + +#~ msgid "Other Testing Tricks" +#~ msgstr "" + +#~ msgid "" +#~ "Besides using the test client as " +#~ "shown above, there is also the " +#~ ":meth:`~flask.Flask.test_request_context` method that " +#~ "can be used in combination with " +#~ "the ``with`` statement to activate a " +#~ "request context temporarily. With this " +#~ "you can access the :class:`~flask.request`," +#~ " :class:`~flask.g` and :class:`~flask.session` " +#~ "objects like in view functions. Here" +#~ " is a full example that demonstrates" +#~ " this approach::" +#~ msgstr "" + +#~ msgid "" +#~ "All the other objects that are " +#~ "context bound can be used in the" +#~ " same way." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to test your " +#~ "application with different configurations and" +#~ " there does not seem to be a" +#~ " good way to do that, consider " +#~ "switching to application factories (see " +#~ ":doc:`patterns/appfactories`)." +#~ msgstr "" + +#~ msgid "" +#~ "Note however that if you are using" +#~ " a test request context, the " +#~ ":meth:`~flask.Flask.before_request` and " +#~ ":meth:`~flask.Flask.after_request` functions are not" +#~ " called automatically. However " +#~ ":meth:`~flask.Flask.teardown_request` functions are " +#~ "indeed executed when the test request" +#~ " context leaves the ``with`` block. " +#~ "If you do want the " +#~ ":meth:`~flask.Flask.before_request` functions to be" +#~ " called as well, you need to " +#~ "call :meth:`~flask.Flask.preprocess_request` yourself::" +#~ msgstr "" + +#~ msgid "" +#~ "This can be necessary to open " +#~ "database connections or something similar " +#~ "depending on how your application was" +#~ " designed." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to call the " +#~ ":meth:`~flask.Flask.after_request` functions you " +#~ "need to call into " +#~ ":meth:`~flask.Flask.process_response` which however " +#~ "requires that you pass it a " +#~ "response object::" +#~ msgstr "" + +#~ msgid "" +#~ "This in general is less useful " +#~ "because at that point you can " +#~ "directly start using the test client." +#~ msgstr "" + +#~ msgid "Faking Resources and Context" +#~ msgstr "" + +#~ msgid "" +#~ "A very common pattern is to store" +#~ " user authorization information and " +#~ "database connections on the application " +#~ "context or the :attr:`flask.g` object. " +#~ "The general pattern for this is to" +#~ " put the object on there on " +#~ "first usage and then to remove it" +#~ " on a teardown. Imagine for instance" +#~ " this code to get the current " +#~ "user::" +#~ msgstr "" + +#~ msgid "" +#~ "For a test it would be nice " +#~ "to override this user from the " +#~ "outside without having to change some" +#~ " code. This can be accomplished with" +#~ " hooking the :data:`flask.appcontext_pushed` " +#~ "signal::" +#~ msgstr "" + +#~ msgid "And then to use it::" +#~ msgstr "" + +#~ msgid "Keeping the Context Around" +#~ msgstr "" + +#~ msgid "" +#~ "Sometimes it is helpful to trigger " +#~ "a regular request but still keep " +#~ "the context around for a little " +#~ "longer so that additional introspection " +#~ "can happen. With Flask 0.4 this " +#~ "is possible by using the " +#~ ":meth:`~flask.Flask.test_client` with a ``with`` " +#~ "block::" +#~ msgstr "" + +#~ msgid "" +#~ "If you were to use just the " +#~ ":meth:`~flask.Flask.test_client` without the " +#~ "``with`` block, the ``assert`` would " +#~ "fail with an error because `request` " +#~ "is no longer available (because you " +#~ "are trying to use it outside of" +#~ " the actual request)." +#~ msgstr "" + +#~ msgid "Accessing and Modifying Sessions" +#~ msgstr "" + +#~ msgid "" +#~ "Sometimes it can be very helpful " +#~ "to access or modify the sessions " +#~ "from the test client. Generally there" +#~ " are two ways for this. If you" +#~ " just want to ensure that a " +#~ "session has certain keys set to " +#~ "certain values you can just keep " +#~ "the context around and access " +#~ ":data:`flask.session`::" +#~ msgstr "" + +#~ msgid "" +#~ "This however does not make it " +#~ "possible to also modify the session " +#~ "or to access the session before a" +#~ " request was fired. Starting with " +#~ "Flask 0.8 we provide a so called" +#~ " “session transaction” which simulates the" +#~ " appropriate calls to open a session" +#~ " in the context of the test " +#~ "client and to modify it. At the" +#~ " end of the transaction the session" +#~ " is stored and ready to be used" +#~ " by the test client. This works " +#~ "independently of the session backend " +#~ "used::" +#~ msgstr "" + +#~ msgid "" +#~ "Note that in this case you have" +#~ " to use the ``sess`` object instead" +#~ " of the :data:`flask.session` proxy. The" +#~ " object however itself will provide " +#~ "the same interface." +#~ msgstr "" + +#~ msgid "Testing JSON APIs" +#~ msgstr "" + +#~ msgid "" +#~ "Flask has great support for JSON, " +#~ "and is a popular choice for " +#~ "building JSON APIs. Making requests with" +#~ " JSON data and examining JSON data" +#~ " in responses is very convenient::" +#~ msgstr "" + +#~ msgid "" +#~ "Passing the ``json`` argument in the " +#~ "test client methods sets the request " +#~ "data to the JSON-serialized object " +#~ "and sets the content type to " +#~ "``application/json``. You can get the " +#~ "JSON data from the request or " +#~ "response with ``get_json``." +#~ msgstr "" + +#~ msgid "Testing CLI Commands" +#~ msgstr "" + +#~ msgid "" +#~ "Click comes with `utilities for " +#~ "testing`_ your CLI commands. A " +#~ ":class:`~click.testing.CliRunner` runs commands in" +#~ " isolation and captures the output in" +#~ " a :class:`~click.testing.Result` object." +#~ msgstr "" + +#~ msgid "" +#~ "Flask provides :meth:`~flask.Flask.test_cli_runner` " +#~ "to create a :class:`~flask.testing.FlaskCliRunner`" +#~ " that passes the Flask app to " +#~ "the CLI automatically. Use its " +#~ ":meth:`~flask.testing.FlaskCliRunner.invoke` method to " +#~ "call commands in the same way they" +#~ " would be called from the command " +#~ "line. ::" +#~ msgstr "" + +#~ msgid "" +#~ "In the example above, invoking the " +#~ "command by name is useful because " +#~ "it verifies that the command was " +#~ "correctly registered with the app." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to test how your " +#~ "command parses parameters, without running " +#~ "the command, use its " +#~ ":meth:`~click.BaseCommand.make_context` method. This " +#~ "is useful for testing complex validation" +#~ " rules and custom types. ::" +#~ msgstr "" diff --git a/docs/locales/zh_CN/LC_MESSAGES/tutorial/deploy.po b/docs/locales/zh_CN/LC_MESSAGES/tutorial/deploy.po index 1389dc8fb..7e81bd132 100755 --- a/docs/locales/zh_CN/LC_MESSAGES/tutorial/deploy.po +++ b/docs/locales/zh_CN/LC_MESSAGES/tutorial/deploy.po @@ -1,193 +1,187 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2010 Pallets -# This file is distributed under the same license as the Flask package. -# Grey Li , 2021. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: Flask 2.1.x\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Grey Li \n" -"Language-Team: zh_CN \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.1\n" - -#: ../../tutorial/deploy.rst:2 -msgid "Deploy to Production" -msgstr "部署到生产环境" - -#: ../../tutorial/deploy.rst:4 -msgid "" -"This part of the tutorial assumes you have a server that you want to " -"deploy your application to. It gives an overview of how to create the " -"distribution file and install it, but won't go into specifics about what " -"server or software to use. You can set up a new environment on your " -"development computer to try out the instructions below, but probably " -"shouldn't use it for hosting a real public application. See " -":doc:`/deploying/index` for a list of many different ways to host your " -"application." -msgstr "" -"这部分教程假设你有一台服务器,你想把程序部署上去。这一章会概括如何创建分发文件并安装它," -"但是不会涉及具体使用哪一种服务器或软件。你可以在你的开发电脑上设置一个新环境并尝试下面的" -"操作说明,但可能不应该用它来托管一个真正的公开应用。参阅 :doc:`/deploying/index` " -"了解托管你的应用的多种不同方式。" - -#: ../../tutorial/deploy.rst:15 -msgid "Build and Install" -msgstr "构建和安装" - -#: ../../tutorial/deploy.rst:17 -msgid "" -"When you want to deploy your application elsewhere, you build a " -"distribution file. The current standard for Python distribution is the " -"*wheel* format, with the ``.whl`` extension. Make sure the wheel library " -"is installed first:" -msgstr "" -"当你想要在其他地方部署你的应用时,你要创建一个分发文件。目前 Python 分发的标准是 *wheel* " -"格式,它使用 ``.whl`` 后缀。首先确保 wheel 库已经被安装:" - -#: ../../tutorial/deploy.rst:26 -msgid "" -"Running ``setup.py`` with Python gives you a command line tool to issue " -"build-related commands. The ``bdist_wheel`` command will build a wheel " -"distribution file." -msgstr "" -"使用 Python 运行 ``setup.py`` 给你提供了一个包含构建相关命令的命令行工具。其中 " -"``bdist_wheel`` 命令将会构建一个 wheel 分发文件。" - -#: ../../tutorial/deploy.rst:34 -msgid "" -"You can find the file in ``dist/flaskr-1.0.0-py3-none-any.whl``. The file" -" name is in the format of {project name}-{version}-{python tag} -{abi " -"tag}-{platform tag}." -msgstr "" -"你可以在 ``dist/flaskr-1.0.0-py3-none-any.whl`` 找到这个文件。文件名的格式为:" -"{项目名称}-{版本}-{python 标签} -{abi 标签}-{平台标签}。" - -#: ../../tutorial/deploy.rst:38 -msgid "" -"Copy this file to another machine, :ref:`set up a new virtualenv " -"`, then install the file with ``pip``." -msgstr "" -"把这个文件复制到另一台机器,:ref:`设置一个新的虚拟环境 `,然后使用 " -"``pip`` 安装它。" - -#: ../../tutorial/deploy.rst:46 -msgid "Pip will install your project along with its dependencies." -msgstr "pip 会安装你的项目及其依赖。" - -#: ../../tutorial/deploy.rst:48 -msgid "" -"Since this is a different machine, you need to run ``init-db`` again to " -"create the database in the instance folder." -msgstr "由于这是一台不同的机器,你需要再次运行 ``init-db`` 命令在实例文件夹内创建数据库。" - -#: ../../tutorial/deploy.rst:53 -msgid "Bash" -msgstr "Bash" - -#: ../../tutorial/deploy.rst:60 -msgid "CMD" -msgstr "CMD" - -#: ../../tutorial/deploy.rst:67 -msgid "Powershell" -msgstr "Powershell" - -#: ../../tutorial/deploy.rst:74 -msgid "" -"When Flask detects that it's installed (not in editable mode), it uses a " -"different directory for the instance folder. You can find it at " -"``venv/var/flaskr-instance`` instead." -msgstr "" -"当 Flask 检测到它已经被安装(不在可编辑模式下),它会使用一个不同的目录作为实例文件夹。你可以在 " -"``venv/var/flaskr-instance`` 找到它。" - -#: ../../tutorial/deploy.rst:80 -msgid "Configure the Secret Key" -msgstr "配置密钥" - -#: ../../tutorial/deploy.rst:82 -msgid "" -"In the beginning of the tutorial that you gave a default value for " -":data:`SECRET_KEY`. This should be changed to some random bytes in " -"production. Otherwise, attackers could use the public ``'dev'`` key to " -"modify the session cookie, or anything else that uses the secret key." -msgstr "" -"在这个教程的一开始,你为 :data:`SECRET_KEY` 设置了一个默认值。在生产环境中,它" -"应该被更换为一个随机字节串。否则,攻击者可以使用常用的 ``'dev'`` 密钥去修改会话 " - -"cookie,或是其他任何使用密钥的数据。" - -#: ../../tutorial/deploy.rst:87 -msgid "You can use the following command to output a random secret key:" -msgstr "你可以使用下面的命令生成一个随机密钥:" - -#: ../../tutorial/deploy.rst:95 -msgid "" -"Create the ``config.py`` file in the instance folder, which the factory " -"will read from if it exists. Copy the generated value into it." -msgstr "" -"在实例文件夹中创建 ``config.py`` 文件,如果这个文件存在,程序工厂将会从它读取配置。" -"把生成的值复制进去:" - -#: ../../tutorial/deploy.rst:98 -msgid "``venv/var/flaskr-instance/config.py``" -msgstr "``venv/var/flaskr-instance/config.py``" - -#: ../../tutorial/deploy.rst:103 -msgid "" -"You can also set any other necessary configuration here, although " -"``SECRET_KEY`` is the only one needed for Flaskr." -msgstr "" -"你也可以在这里设置任意其他必要的配置,尽管对于 Flaskr 来说 ``SECRET_KEY`` 是唯一需要的配置。" - -#: ../../tutorial/deploy.rst:108 -msgid "Run with a Production Server" -msgstr "使用生产服务器运行应用" - -#: ../../tutorial/deploy.rst:110 -msgid "" -"When running publicly rather than in development, you should not use the " -"built-in development server (``flask run``). The development server is " -"provided by Werkzeug for convenience, but is not designed to be " -"particularly efficient, stable, or secure." -msgstr "" -"当在生产环境下运行时,你不应该使用内置的开发服务器(``flask run``)。开发服务器由 " -"Werkzeug 提供,它被设计用来让你在开发时更加方便,因此并不是特别高效、稳定或安全。" - -#: ../../tutorial/deploy.rst:115 -msgid "" -"Instead, use a production WSGI server. For example, to use `Waitress`_, " -"first install it in the virtual environment:" -msgstr "" -"相反,请使用一个生产 WSGI 服务器。举例来说,要使用 `Waitress`_,首先在虚拟环境下安装它:" - -#: ../../tutorial/deploy.rst:122 -msgid "" -"You need to tell Waitress about your application, but it doesn't use " -"``FLASK_APP`` like ``flask run`` does. You need to tell it to import and " -"call the application factory to get an application object." -msgstr "" -"你需要告诉 Waitress 你的应用在哪里,但是它并不像 ``flask run`` 那样读取 ``FLASK_APP``。" -"你需要告诉它去导入并调用应用工厂来获取一个应用对象。" - -#: ../../tutorial/deploy.rst:132 -msgid "" -"See :doc:`/deploying/index` for a list of many different ways to host " -"your application. Waitress is just an example, chosen for the tutorial " -"because it supports both Windows and Linux. There are many more WSGI " -"servers and deployment options that you may choose for your project." -msgstr "" -"阅读 :doc:`/deploying/index` 了解托管应用的多种不同方式。Waitress 只是一个" -"示例,在这个教程里选择它是因为它同时支持 Windows 和 Linux。还有很多 WSGI 服务器" -"和部署选项可以供你的项目选择。" - -#: ../../tutorial/deploy.rst:139 -msgid "Continue to :doc:`next`." -msgstr "继续阅读 :doc:`next`。" +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2010 Pallets +# This file is distributed under the same license as the Flask package. +# Grey Li , 2021. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Flask 2.1.x\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Grey Li \n" +"Language-Team: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.9.1\n" + +#: ../../tutorial/deploy.rst:2 +msgid "Deploy to Production" +msgstr "部署到生产环境" + +#: ../../tutorial/deploy.rst:4 +msgid "" +"This part of the tutorial assumes you have a server that you want to " +"deploy your application to. It gives an overview of how to create the " +"distribution file and install it, but won't go into specifics about what " +"server or software to use. You can set up a new environment on your " +"development computer to try out the instructions below, but probably " +"shouldn't use it for hosting a real public application. See " +":doc:`/deploying/index` for a list of many different ways to host your " +"application." +msgstr "" +"这部分教程假设你有一台服务器,你想把程序部署上去。这一章会概括如何创建分发文件并安装它,但是不会涉及具体使用哪一种服务器或软件。你可以在你的开发电脑上设置一个新环境并尝试下面的操作说明,但可能不应该用它来托管一个真正的公开应用。参阅" +" :doc:`/deploying/index` 了解托管你的应用的多种不同方式。" + +#: ../../tutorial/deploy.rst:15 +msgid "Build and Install" +msgstr "构建和安装" + +#: ../../tutorial/deploy.rst:17 +msgid "" +"When you want to deploy your application elsewhere, you build a " +"distribution file. The current standard for Python distribution is the " +"*wheel* format, with the ``.whl`` extension. Make sure the wheel library " +"is installed first:" +msgstr "" +"当你想要在其他地方部署你的应用时,你要创建一个分发文件。目前 Python 分发的标准是 *wheel* 格式,它使用 ``.whl`` " +"后缀。首先确保 wheel 库已经被安装:" + +#: ../../tutorial/deploy.rst:26 +msgid "" +"Running ``setup.py`` with Python gives you a command line tool to issue " +"build-related commands. The ``bdist_wheel`` command will build a wheel " +"distribution file." +msgstr "" +"使用 Python 运行 ``setup.py`` 给你提供了一个包含构建相关命令的命令行工具。其中 ``bdist_wheel`` " +"命令将会构建一个 wheel 分发文件。" + +#: ../../tutorial/deploy.rst:34 +msgid "" +"You can find the file in ``dist/flaskr-1.0.0-py3-none-any.whl``. The file" +" name is in the format of {project name}-{version}-{python tag} -{abi " +"tag}-{platform tag}." +msgstr "" +"你可以在 ``dist/flaskr-1.0.0-py3-none-any.whl`` " +"找到这个文件。文件名的格式为:{项目名称}-{版本}-{python 标签} -{abi 标签}-{平台标签}。" + +#: ../../tutorial/deploy.rst:38 +msgid "" +"Copy this file to another machine, :ref:`set up a new virtualenv " +"`, then install the file with ``pip``." +msgstr "把这个文件复制到另一台机器,:ref:`设置一个新的虚拟环境 `,然后使用 ``pip`` 安装它。" + +#: ../../tutorial/deploy.rst:46 +msgid "Pip will install your project along with its dependencies." +msgstr "pip 会安装你的项目及其依赖。" + +#: ../../tutorial/deploy.rst:48 +msgid "" +"Since this is a different machine, you need to run ``init-db`` again to " +"create the database in the instance folder." +msgstr "由于这是一台不同的机器,你需要再次运行 ``init-db`` 命令在实例文件夹内创建数据库。" + +#: ../../tutorial/deploy.rst:53 +msgid "Bash" +msgstr "Bash" + +#: ../../tutorial/deploy.rst:60 +msgid "Fish" +msgstr "" + +#: ../../tutorial/deploy.rst:67 +msgid "CMD" +msgstr "CMD" + +#: ../../tutorial/deploy.rst:74 +msgid "Powershell" +msgstr "Powershell" + +#: ../../tutorial/deploy.rst:81 +msgid "" +"When Flask detects that it's installed (not in editable mode), it uses a " +"different directory for the instance folder. You can find it at " +"``venv/var/flaskr-instance`` instead." +msgstr "" +"当 Flask 检测到它已经被安装(不在可编辑模式下),它会使用一个不同的目录作为实例文件夹。你可以在 ``venv/var/flaskr-" +"instance`` 找到它。" + +#: ../../tutorial/deploy.rst:87 +msgid "Configure the Secret Key" +msgstr "配置密钥" + +#: ../../tutorial/deploy.rst:89 +msgid "" +"In the beginning of the tutorial that you gave a default value for " +":data:`SECRET_KEY`. This should be changed to some random bytes in " +"production. Otherwise, attackers could use the public ``'dev'`` key to " +"modify the session cookie, or anything else that uses the secret key." +msgstr "" +"在这个教程的一开始,你为 :data:`SECRET_KEY` " +"设置了一个默认值。在生产环境中,它应该被更换为一个随机字节串。否则,攻击者可以使用常用的 ``'dev'`` 密钥去修改会话 " +"cookie,或是其他任何使用密钥的数据。" + +#: ../../tutorial/deploy.rst:94 +msgid "You can use the following command to output a random secret key:" +msgstr "你可以使用下面的命令生成一个随机密钥:" + +#: ../../tutorial/deploy.rst:102 +msgid "" +"Create the ``config.py`` file in the instance folder, which the factory " +"will read from if it exists. Copy the generated value into it." +msgstr "在实例文件夹中创建 ``config.py`` 文件,如果这个文件存在,程序工厂将会从它读取配置。把生成的值复制进去:" + +#: ../../tutorial/deploy.rst:105 +msgid "``venv/var/flaskr-instance/config.py``" +msgstr "``venv/var/flaskr-instance/config.py``" + +#: ../../tutorial/deploy.rst:110 +msgid "" +"You can also set any other necessary configuration here, although " +"``SECRET_KEY`` is the only one needed for Flaskr." +msgstr "你也可以在这里设置任意其他必要的配置,尽管对于 Flaskr 来说 ``SECRET_KEY`` 是唯一需要的配置。" + +#: ../../tutorial/deploy.rst:115 +msgid "Run with a Production Server" +msgstr "使用生产服务器运行应用" + +#: ../../tutorial/deploy.rst:117 +msgid "" +"When running publicly rather than in development, you should not use the " +"built-in development server (``flask run``). The development server is " +"provided by Werkzeug for convenience, but is not designed to be " +"particularly efficient, stable, or secure." +msgstr "" +"当在生产环境下运行时,你不应该使用内置的开发服务器(``flask run``)。开发服务器由 Werkzeug " +"提供,它被设计用来让你在开发时更加方便,因此并不是特别高效、稳定或安全。" + +#: ../../tutorial/deploy.rst:122 +msgid "" +"Instead, use a production WSGI server. For example, to use `Waitress`_, " +"first install it in the virtual environment:" +msgstr "相反,请使用一个生产 WSGI 服务器。举例来说,要使用 `Waitress`_,首先在虚拟环境下安装它:" + +#: ../../tutorial/deploy.rst:129 +msgid "" +"You need to tell Waitress about your application, but it doesn't use " +"``FLASK_APP`` like ``flask run`` does. You need to tell it to import and " +"call the application factory to get an application object." +msgstr "" +"你需要告诉 Waitress 你的应用在哪里,但是它并不像 ``flask run`` 那样读取 " +"``FLASK_APP``。你需要告诉它去导入并调用应用工厂来获取一个应用对象。" + +#: ../../tutorial/deploy.rst:139 +msgid "" +"See :doc:`/deploying/index` for a list of many different ways to host " +"your application. Waitress is just an example, chosen for the tutorial " +"because it supports both Windows and Linux. There are many more WSGI " +"servers and deployment options that you may choose for your project." +msgstr "" +"阅读 :doc:`/deploying/index` 了解托管应用的多种不同方式。Waitress " +"只是一个示例,在这个教程里选择它是因为它同时支持 Windows 和 Linux。还有很多 WSGI 服务器和部署选项可以供你的项目选择。" + +#: ../../tutorial/deploy.rst:146 +msgid "Continue to :doc:`next`." +msgstr "继续阅读 :doc:`next`。" diff --git a/docs/locales/zh_CN/LC_MESSAGES/tutorial/factory.po b/docs/locales/zh_CN/LC_MESSAGES/tutorial/factory.po index b557ea545..0219744b0 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/tutorial/factory.po +++ b/docs/locales/zh_CN/LC_MESSAGES/tutorial/factory.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Grey Li \n" "Language-Team: zh_CN \n" @@ -26,9 +26,7 @@ msgid "" "A Flask application is an instance of the :class:`Flask` class. " "Everything about the application, such as configuration and URLs, will be" " registered with this class." -msgstr "" -"Flask 应用是 :class:`Flask` 类的实例。关于这个应用的一切,比如配置和 URL," -"都会使用这个类注册。" +msgstr "Flask 应用是 :class:`Flask` 类的实例。关于这个应用的一切,比如配置和 URL,都会使用这个类注册。" #: ../../tutorial/factory.rst:10 msgid "" @@ -38,9 +36,8 @@ msgid "" " simple and useful in some cases, it can cause some tricky issues as the " "project grows." msgstr "" -"创建一个 Flask 应用最直接的方式是直接在你的代码顶部创建一个全局的 :class:`Flask` " -"实例,就像上一页的“Hello, World!”示例做的那样。虽然这在某些情况下很简单也很有用," -"但它在项目变大时会带来一些棘手的问题。" +"创建一个 Flask 应用最直接的方式是直接在你的代码顶部创建一个全局的 :class:`Flask` 实例,就像上一页的“Hello, " +"World!”示例做的那样。虽然这在某些情况下很简单也很有用,但它在项目变大时会带来一些棘手的问题。" #: ../../tutorial/factory.rst:16 msgid "" @@ -51,8 +48,7 @@ msgid "" "will be returned." msgstr "" "与其全局创建一个 :class:`Flask` 类实例,不如在一个函数里创建它。这个函数被称为 " -"*应用工厂*。应用所需要的任何配置、注册和其他设置都将在这个函数里进行,然后应用" -"会被返回。" +"*应用工厂*。应用所需要的任何配置、注册和其他设置都将在这个函数里进行,然后应用会被返回。" #: ../../tutorial/factory.rst:24 msgid "The Application Factory" @@ -67,7 +63,6 @@ msgid "" msgstr "" "是时候开始写代码了!创建 ``flaskr`` 目录并添加 ``__init__.py`` 文件。``__init__.py`` " "有两个作用:它将包含应用工厂,而且告诉 Python,``flaskr`` 目录应该被看做一个包。" -"" #: ../../tutorial/factory.rst:35 msgid "``flaskr/__init__.py``" @@ -77,9 +72,7 @@ msgstr "``flaskr/__init__.py``" msgid "" "``create_app`` is the application factory function. You'll add to it " "later in the tutorial, but it already does a lot." -msgstr "" -"``create_app`` 是应用工厂函数。你会在教程后面对它进行补充,不过它已经" -"做了很多事情。" +msgstr "``create_app`` 是应用工厂函数。你会在教程后面对它进行补充,不过它已经做了很多事情。" #: ../../tutorial/factory.rst:74 msgid "" @@ -95,8 +88,8 @@ msgid "" "know where it's located to set up some paths, and ``__name__`` is a " "convenient way to tell it that." msgstr "" -"``__name__`` 是当前 Python 模块的名称。为了设置一些路径,应用需要知道它的位置,而 " -"``__name__`` 是告诉它当前位置的一个便捷方式。" +"``__name__`` 是当前 Python 模块的名称。为了设置一些路径,应用需要知道它的位置,而 ``__name__`` " +"是告诉它当前位置的一个便捷方式。" #: ../../tutorial/factory.rst:81 msgid "" @@ -106,17 +99,15 @@ msgid "" "local data that shouldn't be committed to version control, such as " "configuration secrets and the database file." msgstr "" -"``instance_relative_config=True`` 用来告诉应用,配置文件的位置相对于 " -":ref:`实例文件夹 `。实例文件夹位于 ``flaskr`` 包的外层,它" -"用来存放不应该提交到版本控制软件的本地数据,比如包含私密信息的配置和数据库文件。" +"``instance_relative_config=True`` 用来告诉应用,配置文件的位置相对于 :ref:`实例文件夹 " +"`。实例文件夹位于 ``flaskr`` " +"包的外层,它用来存放不应该提交到版本控制软件的本地数据,比如包含私密信息的配置和数据库文件。" #: ../../tutorial/factory.rst:88 msgid "" ":meth:`app.config.from_mapping() ` sets some default" " configuration that the app will use:" -msgstr "" -":meth:`app.config.from_mapping() ` 设置一些应用将会使用的" -"默认配置:" +msgstr ":meth:`app.config.from_mapping() ` 设置一些应用将会使用的默认配置:" #: ../../tutorial/factory.rst:91 msgid "" @@ -124,8 +115,8 @@ msgid "" "It's set to ``'dev'`` to provide a convenient value during development, " "but it should be overridden with a random value when deploying." msgstr "" -":data:`SECRET_KEY` 被 Flask 和扩展用来保持数据安全。为了方便,在开发时可以将它" -"设为 ``'dev'``,但是它在部署时应该被一个随机值覆写。" +":data:`SECRET_KEY` 被 Flask 和扩展用来保持数据安全。为了方便,在开发时可以将它设为 " +"``'dev'``,但是它在部署时应该被一个随机值覆写。" #: ../../tutorial/factory.rst:96 msgid "" @@ -134,9 +125,8 @@ msgid "" "path that Flask has chosen for the instance folder. You'll learn more " "about the database in the next section." msgstr "" -"``DATABASE`` 是保存 SQLite 数据库文件的路径。它在 " -":attr:`app.instance_path ` 路径下,这是 Flask 为实例" -"文件夹选择的路径。你会在下一节了解到更多关于数据库的内容。" +"``DATABASE`` 是保存 SQLite 数据库文件的路径。它在 :attr:`app.instance_path " +"` 路径下,这是 Flask 为实例文件夹选择的路径。你会在下一节了解到更多关于数据库的内容。" #: ../../tutorial/factory.rst:102 msgid "" @@ -145,9 +135,8 @@ msgid "" "the instance folder if it exists. For example, when deploying, this can " "be used to set a real ``SECRET_KEY``." msgstr "" -"如果实例文件夹里存在 ``config.py`` 文件," -":meth:`app.config.from_pyfile() ` 会使用从这个文件中" -"获取到的值来覆写默认配置。例如,当部署时,这可以被用来设置一个真正的 " +"如果实例文件夹里存在 ``config.py`` 文件,:meth:`app.config.from_pyfile() " +"` 会使用从这个文件中获取到的值来覆写默认配置。例如,当部署时,这可以被用来设置一个真正的 " "``SECRET_KEY`` 配置值。" #: ../../tutorial/factory.rst:107 @@ -157,9 +146,8 @@ msgid "" "later in the tutorial can be configured independently of any development " "values you have configured." msgstr "" -"``test_config`` 也可以传递给工厂函数,这时传入的测试配置会被使用,而不是" -"实例文件夹内的配置。这样可以让你在稍后的教程中会编写的测试被独立配置,以区别" -"于任何开发时使用的值。" +"``test_config`` " +"也可以传递给工厂函数,这时传入的测试配置会被使用,而不是实例文件夹内的配置。这样可以让你在稍后的教程中会编写的测试被独立配置,以区别于任何开发时使用的值。" #: ../../tutorial/factory.rst:112 msgid "" @@ -169,8 +157,7 @@ msgid "" "create the SQLite database file there." msgstr "" ":func:`os.makedirs` 确保 :attr:`app.instance_path ` " -"指向的路径存在。Flask 不会自动创建实例文件夹,但它需要被创建,因为你的项目将在" -"那里创建 SQLite 数据库文件。" +"指向的路径存在。Flask 不会自动创建实例文件夹,但它需要被创建,因为你的项目将在那里创建 SQLite 数据库文件。" #: ../../tutorial/factory.rst:118 msgid "" @@ -179,9 +166,9 @@ msgid "" "creates a connection between the URL ``/hello`` and a function that " "returns a response, the string ``'Hello, World!'`` in this case." msgstr "" -":meth:`@app.route() ` 创建了一个简单的路由,这样在开始下面的教程" -"之前你可以看到应用能够正常工作。它在 URL ``/hello`` 和一个函数之间创建了一个" -"连接,这个函数会返回一个响应,在这里即 ``'Hello, World!'`` 字符串。" +":meth:`@app.route() ` " +"创建了一个简单的路由,这样在开始下面的教程之前你可以看到应用能够正常工作。它在 URL ``/hello`` " +"和一个函数之间创建了一个连接,这个函数会返回一个响应,在这里即 ``'Hello, World!'`` 字符串。" #: ../../tutorial/factory.rst:126 msgid "Run The Application" @@ -194,9 +181,8 @@ msgid "" "development mode. Remember, you should still be in the top-level ``flask-" "tutorial`` directory, not the ``flaskr`` package." msgstr "" -"现在你可以用 ``flask`` 命令运行应用。在终端里告诉 Flask 要去哪里找到你的应用,然后" -"以开发模式运行它。请记住,你应该仍然在顶层的 ``flask-tutorial`` 目录下,而不是 " -"``flaskr`` 包内。" +"现在你可以用 ``flask`` 命令运行应用。在终端里告诉 Flask 要去哪里找到你的应用,然后以开发模式运行它。请记住,你应该仍然在顶层的 " +"``flask-tutorial`` 目录下,而不是 ``flaskr`` 包内。" #: ../../tutorial/factory.rst:133 msgid "" @@ -204,36 +190,44 @@ msgid "" "exception, and restarts the server whenever you make changes to the code." " You can leave it running and just reload the browser page as you follow " "the tutorial." -msgstr "" -"在开发模式下,每当页面抛出一个异常时,就会显示一个交互式的调试器(debugger);每当" -"你对代码进行修改,就会重启服务器。在接下来的教程中,你可以让它保持运行,只需要重载" -"浏览器页面。" +msgstr "在开发模式下,每当页面抛出一个异常时,就会显示一个交互式的调试器(debugger);每当你对代码进行修改,就会重启服务器。在接下来的教程中,你可以让它保持运行,只需要重载浏览器页面。" #: ../../tutorial/factory.rst:140 msgid "Bash" msgstr "Bash" #: ../../tutorial/factory.rst:148 +msgid "Fish" +msgstr "" + +#: ../../tutorial/factory.rst:156 msgid "CMD" msgstr "CMD" -#: ../../tutorial/factory.rst:156 +#: ../../tutorial/factory.rst:164 msgid "Powershell" msgstr "Powershell" -#: ../../tutorial/factory.rst:164 +#: ../../tutorial/factory.rst:172 msgid "You'll see output similar to this:" msgstr "你会看到类似下面的输出:" -#: ../../tutorial/factory.rst:176 +#: ../../tutorial/factory.rst:184 msgid "" "Visit http://127.0.0.1:5000/hello in a browser and you should see the " "\"Hello, World!\" message. Congratulations, you're now running your Flask" " web application!" msgstr "" -"在浏览器中访问 http://127.0.0.1:5000/hello,你应该会看到“Hello, World!”信息。" -"恭喜,你现在正在运行你的 Flask web 应用!" +"在浏览器中访问 http://127.0.0.1:5000/hello,你应该会看到“Hello, World!”信息。恭喜,你现在正在运行你的 " +"Flask web 应用!" + +#: ../../tutorial/factory.rst:188 +msgid "" +"If another program is already using port 5000, you'll see ``OSError: " +"[Errno 98]`` or ``OSError: [WinError 10013]`` when the server tries to " +"start. See :ref:`address-already-in-use` for how to handle that." +msgstr "" -#: ../../tutorial/factory.rst:180 +#: ../../tutorial/factory.rst:193 msgid "Continue to :doc:`database`." msgstr "继续阅读 :doc:`database`。" diff --git a/docs/locales/zh_CN/LC_MESSAGES/tutorial/index.po b/docs/locales/zh_CN/LC_MESSAGES/tutorial/index.po index f76f5e6d0..43ff9e515 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/tutorial/index.po +++ b/docs/locales/zh_CN/LC_MESSAGES/tutorial/index.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-30 19:27+0000\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Grey Li \n" "Language-Team: zh_CN \n" @@ -35,8 +35,8 @@ msgstr "" "这个教程会一步步带你创建一个基础的博客程序,它叫做 " "Flaskr。在这个程序里,用户将可以注册、登录、创建文章、编辑或删除文章。你还将会学习打包程序,这样就可以在其他电脑上安装这个程序。" -msgid "screenshot of index page" -msgstr "首页截图" +msgid "首页截图" +msgstr "" #: ../../tutorial/index.rst:30 msgid "" @@ -57,8 +57,8 @@ msgstr "" "Flask 可以做什么建立一个全局认识,然后深入其他文档了解更多内容。这个教程只使用了 Flask 和 Python " "提供的功能。在你开发的另一个项目里,你也许会想要使用 :doc:`/extensions` 或其他库让某些功能实现起来更简单。" -msgid "screenshot of login page" -msgstr "登录页截图" +msgid "登录页截图" +msgstr "" #: ../../tutorial/index.rst:47 msgid "" @@ -90,3 +90,9 @@ msgstr "" #: ../../tutorial/index.rst:64 msgid "Continue to :doc:`layout`." msgstr "下一节是 :doc:`layout`。" + +#~ msgid "screenshot of index page" +#~ msgstr "首页截图" + +#~ msgid "screenshot of login page" +#~ msgstr "登录页截图" diff --git a/docs/locales/zh_CN/LC_MESSAGES/tutorial/views.po b/docs/locales/zh_CN/LC_MESSAGES/tutorial/views.po index c67fc1651..800857f1f 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/tutorial/views.po +++ b/docs/locales/zh_CN/LC_MESSAGES/tutorial/views.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Grey Li \n" "Language-Team: zh_CN \n" @@ -29,9 +29,8 @@ msgid "" "an outgoing response. Flask can also go the other direction and generate " "a URL to a view based on its name and arguments." msgstr "" -"视图函数是你编写用来回应发送到应用的请求的代码。Flask 使用模式来匹配传入的请求 URL 到应该" -"处理它的视图。视图返回的数据会被 Flask 转换为发出的响应。Flask 也可以重定向到其他视图并" -"根据视图名称和参数生成到某一个视图的 URL。" +"视图函数是你编写用来回应发送到应用的请求的代码。Flask 使用模式来匹配传入的请求 URL 到应该处理它的视图。视图返回的数据会被 Flask " +"转换为发出的响应。Flask 也可以重定向到其他视图并根据视图名称和参数生成到某一个视图的 URL。" #: ../../tutorial/views.rst:14 msgid "Create a Blueprint" @@ -44,9 +43,7 @@ msgid "" " application, they are registered with a blueprint. Then the blueprint is" " registered with the application when it is available in the factory " "function." -msgstr "" -"蓝图(:class:`Blueprint`)是一种组织一组相关视图和其他代码的方式。视图和其他代码注册到" -"蓝图,而不是直接注册到应用上。然后,在工厂函数中应用可用时,蓝图会被注册到应用。" +msgstr "蓝图(:class:`Blueprint`)是一种组织一组相关视图和其他代码的方式。视图和其他代码注册到蓝图,而不是直接注册到应用上。然后,在工厂函数中应用可用时,蓝图会被注册到应用。" #: ../../tutorial/views.rst:22 msgid "" @@ -55,12 +52,12 @@ msgid "" "separate module. Since the blog needs to know about authentication, " "you'll write the authentication one first." msgstr "" -"Flaskr 将会有两个蓝图,一个用于认证相关的函数,一个用于博客帖子相关的函数。每一个蓝图的代码" -"将存放在单独的模块中。因为博客需要使用认证功能,所以你要先编写认证蓝图。" +"Flaskr " +"将会有两个蓝图,一个用于认证相关的函数,一个用于博客帖子相关的函数。每一个蓝图的代码将存放在单独的模块中。因为博客需要使用认证功能,所以你要先编写认证蓝图。" #: ../../tutorial/views.rst:27 ../../tutorial/views.rst:79 -#: ../../tutorial/views.rst:171 ../../tutorial/views.rst:218 -#: ../../tutorial/views.rst:247 ../../tutorial/views.rst:263 +#: ../../tutorial/views.rst:170 ../../tutorial/views.rst:222 +#: ../../tutorial/views.rst:251 ../../tutorial/views.rst:267 msgid "``flaskr/auth.py``" msgstr "``flaskr/auth.py``" @@ -71,9 +68,8 @@ msgid "" "is passed as the second argument. The ``url_prefix`` will be prepended to" " all the URLs associated with the blueprint." msgstr "" -"这会创建一个名为 ``'auth'`` 的 :class:`Blueprint`。和应用对象类似,蓝图需要知道它在" -"哪里被定义,所以 ``__name__`` 作为第二个参数传入。``url_prefix`` 将会被添加到所有和" -"这个蓝图相关的 URL 前。" +"这会创建一个名为 ``'auth'`` 的 :class:`Blueprint`。和应用对象类似,蓝图需要知道它在哪里被定义,所以 " +"``__name__`` 作为第二个参数传入。``url_prefix`` 将会被添加到所有和这个蓝图相关的 URL 前。" #: ../../tutorial/views.rst:46 msgid "" @@ -105,9 +101,8 @@ msgid "" "the form, it will validate their input and either show the form again " "with an error message or create the new user and go to the login page." msgstr "" -"当用户访问 URL ``/auth/register`` 时,``register`` 视图会返回 `HTML`_,其中包含" -"一个让他们填写的表单。当他们提交表单时,它会验证他们的输入,并且要么再次显示表单和" -"一个错误消息,要么创建新用户并跳转到登录页面。" +"当用户访问 URL ``/auth/register`` 时,``register`` 视图会返回 " +"`HTML`_,其中包含一个让他们填写的表单。当他们提交表单时,它会验证他们的输入,并且要么再次显示表单和一个错误消息,要么创建新用户并跳转到登录页面。" #: ../../tutorial/views.rst:76 msgid "" @@ -135,8 +130,8 @@ msgid "" "If the user submitted the form, :attr:`request.method ` " "will be ``'POST'``. In this case, start validating the input." msgstr "" -"如果用户提交了表单,:attr:`request.method ` 会是 ``'POST'``。" -"在这种情况下,视图开始验证输入的数据。" +"如果用户提交了表单,:attr:`request.method ` 会是 " +"``'POST'``。在这种情况下,视图开始验证输入的数据。" #: ../../tutorial/views.rst:122 msgid "" @@ -144,52 +139,49 @@ msgid "" "mapping submitted form keys and values. The user will input their " "``username`` and ``password``." msgstr "" -":attr:`request.form ` 是一个特殊类型的 :class:`dict`,它映射提交的" -"表单键到相应的值。用户将会输入他们的 ``username`` 和 ``password``。" +":attr:`request.form ` 是一个特殊类型的 " +":class:`dict`,它映射提交的表单键到相应的值。用户将会输入他们的 ``username`` 和 ``password``。" #: ../../tutorial/views.rst:126 msgid "Validate that ``username`` and ``password`` are not empty." msgstr "验证 ``username`` 和 ``password`` 不为空。" #: ../../tutorial/views.rst:128 -msgid "" -"Validate that ``username`` is not already registered by querying the " -"database and checking if a result is returned. :meth:`db.execute " -"` takes a SQL query with ``?`` placeholders " -"for any user input, and a tuple of values to replace the placeholders " -"with. The database library will take care of escaping the values so you " -"are not vulnerable to a *SQL injection attack*." +msgid "If validation succeeds, insert the new user data into the database." msgstr "" -"通过查询数据库并检查是否有结果返回,验证 ``username`` 是否已经被注册。" -":meth:`db.execute ` 接受一个 SQL 查询,其中包含" -"代表任意用户输入的 ``?`` 占位符,以及一个用来替换占位符的数据元组。数据库相关的库" -"将负责转义值,使得你不易受到 *SQL 注入攻击*。 -#: ../../tutorial/views.rst:136 +#: ../../tutorial/views.rst:130 +#, fuzzy msgid "" -":meth:`~sqlite3.Cursor.fetchone` returns one row from the query. If the " -"query returned no results, it returns ``None``. Later, " -":meth:`~sqlite3.Cursor.fetchall` is used, which returns a list of all " -"results." +":meth:`db.execute ` takes a SQL query with " +"``?`` placeholders for any user input, and a tuple of values to replace " +"the placeholders with. The database library will take care of escaping " +"the values so you are not vulnerable to a *SQL injection attack*." msgstr "" -":meth:`~sqlite3.Cursor.fetchone` 从查询返回一行。如果查询没有返回结果,它返回 ``None``。" -"接着,:meth:`~sqlite3.Cursor.fetchall` 被使用,它返回一个包含所有结果的列表。" +"通过查询数据库并检查是否有结果返回,验证 ``username`` 是否已经被注册。:meth:`db.execute " +"` 接受一个 SQL 查询,其中包含代表任意用户输入的 ``?`` " +"占位符,以及一个用来替换占位符的数据元组。数据库相关的库将负责转义值,使得你不易受到 *SQL 注入攻击*" -#: ../../tutorial/views.rst:141 +#: ../../tutorial/views.rst:136 +#, fuzzy msgid "" -"If validation succeeds, insert the new user data into the database. For " -"security, passwords should never be stored in the database directly. " +"For security, passwords should never be stored in the database directly. " "Instead, :func:`~werkzeug.security.generate_password_hash` is used to " "securely hash the password, and that hash is stored. Since this query " "modifies data, :meth:`db.commit() ` needs to " "be called afterwards to save the changes." msgstr "" -"如果验证成功,插入新的用户数据到数据库。为了安全起见,密码绝对不应该直接存储到数据库中。" -"相反,:func:`~werkzeug.security.generate_password_hash` 被用来安全地计算出密码散列值," -"并存储该散列值。因为这个查询修改了数据,为了保存变动,:meth:`db.commit() ` " -"需要在之后被调用。" +"如果验证成功,插入新的用户数据到数据库。为了安全起见,密码绝对不应该直接存储到数据库中。相反,:func:`~werkzeug.security.generate_password_hash`" +" 被用来安全地计算出密码散列值,并存储该散列值。因为这个查询修改了数据,为了保存变动,:meth:`db.commit() " +"` 需要在之后被调用。" + +#: ../../tutorial/views.rst:144 +msgid "" +"An :exc:`sqlite3.IntegrityError` will occur if the username already " +"exists, which should be shown to the user as another validation error." +msgstr "" -#: ../../tutorial/views.rst:149 +#: ../../tutorial/views.rst:148 msgid "" "After storing the user, they are redirected to the login page. " ":func:`url_for` generates the URL for the login view based on its name. " @@ -197,55 +189,63 @@ msgid "" " the URL later without changing all code that links to it. " ":func:`redirect` generates a redirect response to the generated URL." msgstr "" -"保存用户后,他们被重定向到登录页面。:func:`url_for` 根据其名称生成到 ``login`` 视图的 URL。" -"和直接写出来 URL 相比,这是更推荐的做法,因为它允许你以后轻松更改 URL 而不用更新所有链接到它" -"的代码。:func:`redirect` 生成一个重定向响应到生成的 URL。" +"保存用户后,他们被重定向到登录页面。:func:`url_for` 根据其名称生成到 ``login`` 视图的 URL。和直接写出来 URL " +"相比,这是更推荐的做法,因为它允许你以后轻松更改 URL 而不用更新所有链接到它的代码。:func:`redirect` " +"生成一个重定向响应到生成的 URL。" -#: ../../tutorial/views.rst:156 +#: ../../tutorial/views.rst:155 msgid "" "If validation fails, the error is shown to the user. :func:`flash` stores" " messages that can be retrieved when rendering the template." -msgstr "" -"如果验证失败,错误会显示给用户。:func:`flash` 会存储消息,这些消息可以在渲染模板时被" -"获取。" +msgstr "如果验证失败,错误会显示给用户。:func:`flash` 会存储消息,这些消息可以在渲染模板时被获取。" -#: ../../tutorial/views.rst:159 +#: ../../tutorial/views.rst:158 msgid "" "When the user initially navigates to ``auth/register``, or there was a " "validation error, an HTML page with the registration form should be " "shown. :func:`render_template` will render a template containing the " "HTML, which you'll write in the next step of the tutorial." msgstr "" -"当用户最初导航到 ``auth/register`` 时,或是有验证错误时,应该显示一个带有注册表单的 " -"HTML 页面。:func:`render_template` 将渲染一个包含该 HTML 页面的模板,你将在教程" -"的下一章编写相关代码。" +"当用户最初导航到 ``auth/register`` 时,或是有验证错误时,应该显示一个带有注册表单的 HTML " +"页面。:func:`render_template` 将渲染一个包含该 HTML 页面的模板,你将在教程的下一章编写相关代码。" -#: ../../tutorial/views.rst:167 +#: ../../tutorial/views.rst:166 msgid "Login" msgstr "登录" -#: ../../tutorial/views.rst:169 +#: ../../tutorial/views.rst:168 msgid "This view follows the same pattern as the ``register`` view above." msgstr "这个视图和上面的 ``register`` 视图遵循相同的模式。" -#: ../../tutorial/views.rst:199 +#: ../../tutorial/views.rst:198 msgid "There are a few differences from the ``register`` view:" msgstr "和 ``register`` 视图有一些区别:" -#: ../../tutorial/views.rst:201 +#: ../../tutorial/views.rst:200 msgid "The user is queried first and stored in a variable for later use." msgstr "首先查询用户,并存储到一个变量供后面使用。" -#: ../../tutorial/views.rst:203 +#: ../../tutorial/views.rst:202 +#, fuzzy +msgid "" +":meth:`~sqlite3.Cursor.fetchone` returns one row from the query. If the " +"query returned no results, it returns ``None``. Later, " +":meth:`~sqlite3.Cursor.fetchall` will be used, which returns a list of " +"all results." +msgstr "" +":meth:`~sqlite3.Cursor.fetchone` 从查询返回一行。如果查询没有返回结果,它返回 " +"``None``。接着,:meth:`~sqlite3.Cursor.fetchall` 被使用,它返回一个包含所有结果的列表。" + +#: ../../tutorial/views.rst:207 msgid "" ":func:`~werkzeug.security.check_password_hash` hashes the submitted " "password in the same way as the stored hash and securely compares them. " "If they match, the password is valid." msgstr "" -":func:`~werkzeug.security.check_password_hash` 以存储散列值时相同的方式为提交的" -"密码计算散列值,并对它们进行安全对比。如果匹配,则密码是有效的。" +":func:`~werkzeug.security.check_password_hash` " +"以存储散列值时相同的方式为提交的密码计算散列值,并对它们进行安全对比。如果匹配,则密码是有效的。" -#: ../../tutorial/views.rst:207 +#: ../../tutorial/views.rst:211 msgid "" ":data:`session` is a :class:`dict` that stores data across requests. When" " validation succeeds, the user's ``id`` is stored in a new session. The " @@ -253,21 +253,21 @@ msgid "" " then sends it back with subsequent requests. Flask securely *signs* the " "data so that it can't be tampered with." msgstr "" -":data:`session` 是一个 :class:`dict`,用来存储跨请求的数据。当验证成功,用户的 ``id`` 被" -"存储到一个新的 session。数据被存储到一个发送给浏览器的 *cookie* 中,然后浏览器会在后续的请求中" -"把它发送回来。Flask 对数据进行安全 *签名*,使其无法被篡改。" +":data:`session` 是一个 :class:`dict`,用来存储跨请求的数据。当验证成功,用户的 ``id`` 被存储到一个新的 " +"session。数据被存储到一个发送给浏览器的 *cookie* 中,然后浏览器会在后续的请求中把它发送回来。Flask 对数据进行安全 " +"*签名*,使其无法被篡改。" -#: ../../tutorial/views.rst:213 +#: ../../tutorial/views.rst:217 msgid "" "Now that the user's ``id`` is stored in the :data:`session`, it will be " "available on subsequent requests. At the beginning of each request, if a " "user is logged in their information should be loaded and made available " "to other views." msgstr "" -"现在,用户的 ``id`` 被存储到 :data:`session` 中,它将会在后续的请求中可用。在每一个" -"请求开始时,如果用户已经登录,他们的信息应该被加载并提供给其他视图。" +"现在,用户的 ``id`` 被存储到 :data:`session` " +"中,它将会在后续的请求中可用。在每一个请求开始时,如果用户已经登录,他们的信息应该被加载并提供给其他视图。" -#: ../../tutorial/views.rst:232 +#: ../../tutorial/views.rst:236 msgid "" ":meth:`bp.before_app_request() ` registers " "a function that runs before the view function, no matter what URL is " @@ -277,54 +277,48 @@ msgid "" "there is no user id, or if the id doesn't exist, ``g.user`` will be " "``None``." msgstr "" -":meth:`bp.before_app_request() ` 注册一个函数并" -"让它在每一个视图函数之前运行,不管请求发到哪一个 URL。``load_logged_in_user`` 检查" -"用户的 ID 是否存储在 :data:`session` 中,并从数据库中获取对应用户的数据,将其存储到 " -":data:`g.user ` 上——它存在于单个请求的生命周期内。如果没有用户 ID,或是 ID 不存在," -"``g.user`` 将是 ``None``。" +":meth:`bp.before_app_request() ` " +"注册一个函数并让它在每一个视图函数之前运行,不管请求发到哪一个 URL。``load_logged_in_user`` 检查用户的 ID " +"是否存储在 :data:`session` 中,并从数据库中获取对应用户的数据,将其存储到 :data:`g.user ` " +"上——它存在于单个请求的生命周期内。如果没有用户 ID,或是 ID 不存在,``g.user`` 将是 ``None``。" -#: ../../tutorial/views.rst:242 +#: ../../tutorial/views.rst:246 msgid "Logout" msgstr "登出" -#: ../../tutorial/views.rst:244 +#: ../../tutorial/views.rst:248 msgid "" "To log out, you need to remove the user id from the :data:`session`. Then" " ``load_logged_in_user`` won't load a user on subsequent requests." msgstr "" -"若要登出,你需要从 :data:`session` 中移除用户 ID。这样 ``load_logged_in_user`` 就不会" -"在后续请求中加载用户。" +"若要登出,你需要从 :data:`session` 中移除用户 ID。这样 ``load_logged_in_user`` " +"就不会在后续请求中加载用户。" -#: ../../tutorial/views.rst:257 +#: ../../tutorial/views.rst:261 msgid "Require Authentication in Other Views" msgstr "在其他视图里要求认证" -#: ../../tutorial/views.rst:259 +#: ../../tutorial/views.rst:263 msgid "" "Creating, editing, and deleting blog posts will require a user to be " "logged in. A *decorator* can be used to check this for each view it's " "applied to." -msgstr "" -"创建、编辑和删除博客帖子将需要用户登录才能操作。可以使用一个 *装饰器* 来为每一个使用它的" -"视图检查登录状态。" +msgstr "创建、编辑和删除博客帖子将需要用户登录才能操作。可以使用一个 *装饰器* 来为每一个使用它的视图检查登录状态。" -#: ../../tutorial/views.rst:276 +#: ../../tutorial/views.rst:280 msgid "" "This decorator returns a new view function that wraps the original view " "it's applied to. The new function checks if a user is loaded and " "redirects to the login page otherwise. If a user is loaded the original " "view is called and continues normally. You'll use this decorator when " "writing the blog views." -msgstr "" -"这个装饰器返回一个新的视图函数,它包裹了被装饰的原始视图函数。新的函数会检查是否有用户被加载:" -"如果有用户被加载,则会调用原视图继续正常运行,否则会重定向到登录页面。你会在写博客视图时使用" -"这个装饰器。" +msgstr "这个装饰器返回一个新的视图函数,它包裹了被装饰的原始视图函数。新的函数会检查是否有用户被加载:如果有用户被加载,则会调用原视图继续正常运行,否则会重定向到登录页面。你会在写博客视图时使用这个装饰器。" -#: ../../tutorial/views.rst:283 +#: ../../tutorial/views.rst:287 msgid "Endpoints and URLs" msgstr "端点和 URL" -#: ../../tutorial/views.rst:285 +#: ../../tutorial/views.rst:289 msgid "" "The :func:`url_for` function generates the URL to a view based on a name " "and arguments. The name associated with a view is also called the " @@ -334,27 +328,27 @@ msgstr "" ":func:`url_for` 函数根据视图名称和参数生成到一个视图的 URL。视图的名称也被叫做 " "*端点(endpoint)*,默认情况下,它和视图函数的名称相同。" -#: ../../tutorial/views.rst:290 +#: ../../tutorial/views.rst:294 msgid "" "For example, the ``hello()`` view that was added to the app factory " "earlier in the tutorial has the name ``'hello'`` and can be linked to " "with ``url_for('hello')``. If it took an argument, which you'll see " "later, it would be linked to using ``url_for('hello', who='World')``." msgstr "" -"例如,在教程的前面部分,``hello()`` 视图被添加到应用工厂,这个视图的名称是 ``'hello'``," -"可以通过 ``url_for('hello')`` 生成指向它的 URL。如果它接受一个参数(后面你会看到),那" -"么生成 URL 的方式则会是 ``url_for('hello', who='World')``。" +"例如,在教程的前面部分,``hello()`` 视图被添加到应用工厂,这个视图的名称是 ``'hello'``,可以通过 " +"``url_for('hello')`` 生成指向它的 URL。如果它接受一个参数(后面你会看到),那么生成 URL 的方式则会是 " +"``url_for('hello', who='World')``。" -#: ../../tutorial/views.rst:296 +#: ../../tutorial/views.rst:300 msgid "" "When using a blueprint, the name of the blueprint is prepended to the " "name of the function, so the endpoint for the ``login`` function you " "wrote above is ``'auth.login'`` because you added it to the ``'auth'`` " "blueprint." msgstr "" -"当使用蓝图时,蓝图的名称会被插入到视图函数的名称前,所以你上面写的 ``login`` 函数" -"的端点是 ``'auth.login'``,因为你把它添加到了 ``'auth'`` 蓝图。" +"当使用蓝图时,蓝图的名称会被插入到视图函数的名称前,所以你上面写的 ``login`` 函数的端点是 " +"``'auth.login'``,因为你把它添加到了 ``'auth'`` 蓝图。" -#: ../../tutorial/views.rst:301 +#: ../../tutorial/views.rst:305 msgid "Continue to :doc:`templates`." msgstr "继续阅读 :doc:`templates`。" diff --git a/docs/locales/zh_CN/LC_MESSAGES/views.po b/docs/locales/zh_CN/LC_MESSAGES/views.po index d4a55ee86..a65bf53aa 100644 --- a/docs/locales/zh_CN/LC_MESSAGES/views.po +++ b/docs/locales/zh_CN/LC_MESSAGES/views.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flask 2.1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-25 19:31+0800\n" +"POT-Creation-Date: 2022-06-12 19:17+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: zh_CN \n" @@ -99,8 +99,8 @@ msgstr "" msgid "" "For RESTful APIs it's especially helpful to execute a different function " "for each HTTP method. With the :class:`flask.views.MethodView` you can " -"easily do that. Each HTTP method maps to a function with the same name " -"(just in lowercase)::" +"easily do that. Each HTTP method maps to a method of the class with the " +"same name (just in lowercase)::" msgstr "" #: ../../views.rst:133 @@ -227,3 +227,13 @@ msgid "" "If you have a lot of APIs that look similar you can refactor that " "registration code::" msgstr "" + +#~ msgid "" +#~ "For RESTful APIs it's especially helpful" +#~ " to execute a different function for" +#~ " each HTTP method. With the " +#~ ":class:`flask.views.MethodView` you can easily " +#~ "do that. Each HTTP method maps to" +#~ " a function with the same name " +#~ "(just in lowercase)::" +#~ msgstr ""