updated docs to match new Werkzeug docs
This commit is contained in:
parent
4c76607553
commit
10159e5464
7 changed files with 82 additions and 78 deletions
48
docs/api.rst
48
docs/api.rst
|
|
@ -46,19 +46,21 @@ Incoming Request Data
|
||||||
|
|
||||||
.. attribute:: form
|
.. attribute:: form
|
||||||
|
|
||||||
A :class:`~werkzeug.MultiDict` with the parsed form data from `POST`
|
A :class:`~werkzeug.datastructures.MultiDict` with the parsed form
|
||||||
or `PUT` requests. Please keep in mind that file uploads will not
|
data from `POST` or `PUT` requests. Please keep in mind that file
|
||||||
end up here, but instead in the :attr:`files` attribute.
|
uploads will not end up here, but instead in the :attr:`files`
|
||||||
|
attribute.
|
||||||
|
|
||||||
.. attribute:: args
|
.. attribute:: args
|
||||||
|
|
||||||
A :class:`~werkzeug.MultiDict` with the parsed contents of the query
|
A :class:`~werkzeug.datastructures.MultiDict` with the parsed
|
||||||
string. (The part in the URL after the question mark).
|
contents of the query string. (The part in the URL after the
|
||||||
|
question mark).
|
||||||
|
|
||||||
.. attribute:: values
|
.. attribute:: values
|
||||||
|
|
||||||
A :class:`~werkzeug.CombinedMultiDict` with the contents of both
|
A :class:`~werkzeug.datastructures.CombinedMultiDict` with the
|
||||||
:attr:`form` and :attr:`args`.
|
contents of both :attr:`form` and :attr:`args`.
|
||||||
|
|
||||||
.. attribute:: cookies
|
.. attribute:: cookies
|
||||||
|
|
||||||
|
|
@ -79,12 +81,13 @@ Incoming Request Data
|
||||||
|
|
||||||
.. attribute:: files
|
.. attribute:: files
|
||||||
|
|
||||||
A :class:`~werkzeug.MultiDict` with files uploaded as part of a
|
A :class:`~werkzeug.datastructures.MultiDict` with files
|
||||||
`POST` or `PUT` request. Each file is stored as
|
uploaded as part of a `POST` or `PUT` request. Each file
|
||||||
:class:`~werkzeug.FileStorage` object. It basically behaves like a
|
is stored as :class:`~werkzeug.datastructures.FileStorage`
|
||||||
standard file object you know from Python, with the difference that
|
object. It basically behaves like a standard file object
|
||||||
it also has a :meth:`~werkzeug.FileStorage.save` function that can
|
you know from Python, with the difference that it also has a
|
||||||
store the file on the filesystem.
|
:meth:`~werkzeug.datastructures.FileStorage.save` function that
|
||||||
|
can store the file on the filesystem.
|
||||||
|
|
||||||
.. attribute:: environ
|
.. attribute:: environ
|
||||||
|
|
||||||
|
|
@ -308,10 +311,10 @@ Useful Internals
|
||||||
|
|
||||||
.. data:: _request_ctx_stack
|
.. data:: _request_ctx_stack
|
||||||
|
|
||||||
The internal :class:`~werkzeug.LocalStack` that is used to implement
|
The internal :class:`~werkzeug.local.LocalStack` that is used to
|
||||||
all the context local objects used in Flask. This is a documented
|
implement all the context local objects used in Flask. This is a
|
||||||
instance and can be used by extensions and application code but the
|
documented instance and can be used by extensions and application
|
||||||
use is discouraged in general.
|
code but the use is discouraged in general.
|
||||||
|
|
||||||
The following attributes are always present on each layer of the
|
The following attributes are always present on each layer of the
|
||||||
stack:
|
stack:
|
||||||
|
|
@ -356,9 +359,9 @@ Useful Internals
|
||||||
deferred cleanup functionality.
|
deferred cleanup functionality.
|
||||||
|
|
||||||
You might find this helpful for unittests where you need the
|
You might find this helpful for unittests where you need the
|
||||||
information from the context local around for a little longer. Make
|
information from the context local around for a little longer.
|
||||||
sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in
|
Make sure to properly :meth:`~werkzeug.local.LocalStack.pop` the stack
|
||||||
that situation, otherwise your unittests will leak memory.
|
yourself in that situation, otherwise your unittests will leak memory.
|
||||||
|
|
||||||
Signals
|
Signals
|
||||||
-------
|
-------
|
||||||
|
|
@ -434,8 +437,9 @@ exceptions where it is good to know that this object is an actual proxy:
|
||||||
- if the object reference is important (so for example for sending
|
- if the object reference is important (so for example for sending
|
||||||
:ref:`signals`)
|
:ref:`signals`)
|
||||||
|
|
||||||
If you need to get access to the underlying object that is proxied, you
|
If you need to get access to the underlying object that is proxied,
|
||||||
can use the :meth:`~werkzeug.LocalProxy._get_current_object` method::
|
you can use the :meth:`~werkzeug.local.LocalProxy._get_current_object`
|
||||||
|
method::
|
||||||
|
|
||||||
app = current_app._get_current_object()
|
app = current_app._get_current_object()
|
||||||
my_signal.send(app)
|
my_signal.send(app)
|
||||||
|
|
|
||||||
|
|
@ -243,7 +243,7 @@ latex_additional_files = ['flaskstyle.sty', 'logo.pdf']
|
||||||
|
|
||||||
intersphinx_mapping = {
|
intersphinx_mapping = {
|
||||||
'http://docs.python.org/dev': None,
|
'http://docs.python.org/dev': None,
|
||||||
'http://werkzeug.pocoo.org/documentation/dev/': None,
|
'http://werkzeug.pocoo.org/docs/': None,
|
||||||
'http://www.sqlalchemy.org/docs/': None,
|
'http://www.sqlalchemy.org/docs/': None,
|
||||||
'http://wtforms.simplecodes.com/docs/0.5/': None,
|
'http://wtforms.simplecodes.com/docs/0.5/': None,
|
||||||
'http://discorporate.us/projects/Blinker/docs/1.1/': None
|
'http://discorporate.us/projects/Blinker/docs/1.1/': None
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ uploads is actually quite simple. It basically works like this:
|
||||||
and an ``<input type=file>`` is placed in that form.
|
and an ``<input type=file>`` is placed in that form.
|
||||||
2. The application accesses the file from the :attr:`~flask.request.files`
|
2. The application accesses the file from the :attr:`~flask.request.files`
|
||||||
dictionary on the request object.
|
dictionary on the request object.
|
||||||
3. use the :meth:`~werkzeug.FileStorage.save` method of the file to save
|
3. use the :meth:`~werkzeug.datastructures.FileStorage.save` method of
|
||||||
the file permanently somewhere on the filesystem.
|
the file to save the file permanently somewhere on the filesystem.
|
||||||
|
|
||||||
A Gentle Introduction
|
A Gentle Introduction
|
||||||
---------------------
|
---------------------
|
||||||
|
|
@ -22,21 +22,21 @@ bootstrapping code for our application::
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from flask import Flask, request, redirect, url_for
|
from flask import Flask, request, redirect, url_for
|
||||||
from werkzeug import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
UPLOAD_FOLDER = '/path/to/the/uploads'
|
UPLOAD_FOLDER = '/path/to/the/uploads'
|
||||||
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
|
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
So first we need a couple of imports. Most should be straightforward, the
|
So first we need a couple of imports. Most should be straightforward,
|
||||||
:func:`werkzeug.secure_filename` is explained a little bit later. The
|
the :func:`werkzeug.utils.secure_filename` is explained a little bit
|
||||||
`UPLOAD_FOLDER` is where we will store the uploaded files and the
|
later. The `UPLOAD_FOLDER` is where we will store the uploaded files
|
||||||
`ALLOWED_EXTENSIONS` is the set of allowed file extensions. Then we add a
|
and the `ALLOWED_EXTENSIONS` is the set of allowed file extensions.
|
||||||
URL rule by hand to the application. Now usually we're not doing that, so
|
Then we add a URL rule by hand to the application. Now usually we're
|
||||||
why here? The reasons is that we want the webserver (or our development
|
not doing that, so why here? The reasons is that we want the webserver
|
||||||
server) to serve these files for us and so we only need a rule to generate
|
(or our development server) to serve these files for us and so we only
|
||||||
the URL to these files.
|
need a rule to generate the URL to these files.
|
||||||
|
|
||||||
Why do we limit the extensions that are allowed? You probably don't want
|
Why do we limit the extensions that are allowed? You probably don't want
|
||||||
your users to be able to upload everything there if the server is directly
|
your users to be able to upload everything there if the server is directly
|
||||||
|
|
@ -71,12 +71,12 @@ the file and redirects the user to the URL for the uploaded file::
|
||||||
</form>
|
</form>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
So what does that :func:`~werkzeug.secure_filename` function actually do?
|
So what does that :func:`~werkzeug.utils.secure_filename` function
|
||||||
Now the problem is that there is that principle called "never trust user
|
actually do? Now the problem is that there is that principle called
|
||||||
input". This is also true for the filename of an uploaded file. All
|
"never trust user input". This is also true for the filename of an
|
||||||
submitted form data can be forged, and filenames can be dangerous. For
|
uploaded file. All submitted form data can be forged, and filenames can
|
||||||
the moment just remember: always use that function to secure a filename
|
be dangerous. For the moment just remember: always use that function
|
||||||
before storing it directly on the filesystem.
|
to secure a filename before storing it directly on the filesystem.
|
||||||
|
|
||||||
.. admonition:: Information for the Pros
|
.. admonition:: Information for the Pros
|
||||||
|
|
||||||
|
|
@ -109,10 +109,10 @@ Flask 0.5 we can use a function that does that for us::
|
||||||
filename)
|
filename)
|
||||||
|
|
||||||
Alternatively you can register `uploaded_file` as `build_only` rule and
|
Alternatively you can register `uploaded_file` as `build_only` rule and
|
||||||
use the :class:`~werkzeug.SharedDataMiddleware`. This also works with
|
use the :class:`~werkzeug.wsgi.SharedDataMiddleware`. This also works
|
||||||
older versions of Flask::
|
with older versions of Flask::
|
||||||
|
|
||||||
from werkzeug import SharedDataMiddleware
|
from werkzeug.wsgi import SharedDataMiddleware
|
||||||
app.add_url_rule('/uploads/<filename>', 'uploaded_file',
|
app.add_url_rule('/uploads/<filename>', 'uploaded_file',
|
||||||
build_only=True)
|
build_only=True)
|
||||||
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
|
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
|
||||||
|
|
|
||||||
|
|
@ -108,12 +108,12 @@ template. This template will load jQuery as above and have a little form
|
||||||
we can add two numbers and a link to trigger the function on the server
|
we can add two numbers and a link to trigger the function on the server
|
||||||
side.
|
side.
|
||||||
|
|
||||||
Note that we are using the :meth:`~werkzeug.MultiDict.get` method here
|
Note that we are using the :meth:`~werkzeug.datastructures.MultiDict.get`
|
||||||
which will never fail. If the key is missing a default value (here ``0``)
|
method here which will never fail. If the key is missing a default
|
||||||
is returned. Furthermore it can convert values to a specific type (like
|
value (here ``0``) is returned. Furthermore it can convert values to
|
||||||
in our case `int`). This is especially handy for code that is
|
a specific type (like in our case `int`). This is especially handy for
|
||||||
triggered by a script (APIs, JavaScript etc.) because you don't need
|
code that is triggered by a script (APIs, JavaScript etc.) because you
|
||||||
special error reporting in that case.
|
don't need special error reporting in that case.
|
||||||
|
|
||||||
The HTML
|
The HTML
|
||||||
--------
|
--------
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ loaded upfront. The trick to actually load the view function as needed.
|
||||||
This can be accomplished with a helper class that behaves just like a
|
This can be accomplished with a helper class that behaves just like a
|
||||||
function but internally imports the real function on first use::
|
function but internally imports the real function on first use::
|
||||||
|
|
||||||
from werkzeug import import_string, cached_property
|
from werkzeug.utils import import_string, cached_property
|
||||||
|
|
||||||
class LazyView(object):
|
class LazyView(object):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -543,14 +543,14 @@ 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
|
forget to set the ``enctype="multipart/form-data"`` attribute on your HTML
|
||||||
form, otherwise the browser will not transmit your files at all.
|
form, otherwise the browser will not transmit your files at all.
|
||||||
|
|
||||||
Uploaded files are stored in memory or at a temporary location on the
|
Uploaded files are stored in memory or at a temporary location
|
||||||
filesystem. You can access those files by looking at the
|
on the filesystem. You can access those files by looking at the
|
||||||
:attr:`~flask.request.files` attribute on the request object. Each
|
:attr:`~flask.request.files` attribute on the request object.
|
||||||
uploaded file is stored in that dictionary. It behaves just like a
|
Each uploaded file is stored in that dictionary. It behaves just
|
||||||
standard Python :class:`file` object, but it also has a
|
like a standard Python :class:`file` object, but it also has a
|
||||||
:meth:`~werkzeug.FileStorage.save` method that allows you to store that
|
:meth:`~werkzeug.datastructures.FileStorage.save` method that allows you
|
||||||
file on the filesystem of the server. Here is a simple example showing how
|
to store that file on the filesystem of the server. Here is a simple
|
||||||
that works::
|
example showing how that works::
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
|
@ -561,16 +561,16 @@ that works::
|
||||||
f.save('/var/www/uploads/uploaded_file.txt')
|
f.save('/var/www/uploads/uploaded_file.txt')
|
||||||
...
|
...
|
||||||
|
|
||||||
If you want to know how the file was named on the client before it was
|
If you want to know how the file was named on the client
|
||||||
uploaded to your application, you can access the
|
before it was uploaded to your application, you can access the
|
||||||
:attr:`~werkzeug.FileStorage.filename` attribute. However please keep in
|
:attr:`~werkzeug.datastructures.FileStorage.filename` attribute. However
|
||||||
mind that this value can be forged so never ever trust that value. If you
|
please keep in mind that this value can be forged so never ever trust that
|
||||||
want to use the filename of the client to store the file on the server,
|
value. If you want to use the filename of the client to store the file
|
||||||
pass it through the :func:`~werkzeug.secure_filename` function that
|
on the server, pass it through the :func:`~werkzeug.utils.secure_filename`
|
||||||
Werkzeug provides for you::
|
function that Werkzeug provides for you::
|
||||||
|
|
||||||
from flask import request
|
from flask import request
|
||||||
from werkzeug import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
@app.route('/upload', methods=['GET', 'POST'])
|
@app.route('/upload', methods=['GET', 'POST'])
|
||||||
def upload_file():
|
def upload_file():
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,11 @@ safely change things, and you will instantly know if your change broke
|
||||||
something.
|
something.
|
||||||
|
|
||||||
Flask gives you a couple of ways to test applications. It mainly does
|
Flask gives you a couple of ways to test applications. It mainly does
|
||||||
that by exposing the Werkzeug test :class:`~werkzeug.Client` class to your
|
that by exposing the Werkzeug test :class:`~werkzeug.test.Client` class
|
||||||
code and handling the context locals for you. You can then use that with
|
to your code and handling the context locals for you. You can then use
|
||||||
your favourite testing solution. In this documentation we will use the
|
that with your favourite testing solution. In this documentation we
|
||||||
:mod:`unittest` package that comes preinstalled with each Python
|
will use the :mod:`unittest` package that comes preinstalled with each
|
||||||
installation.
|
Python installation.
|
||||||
|
|
||||||
The Application
|
The Application
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -106,13 +106,13 @@ this::
|
||||||
rv = self.app.get('/')
|
rv = self.app.get('/')
|
||||||
assert 'No entries here so far' in rv.data
|
assert 'No entries here so far' in rv.data
|
||||||
|
|
||||||
Test functions begin with the word `test`. Every function named like that
|
Test functions begin with the word `test`. Every function named like
|
||||||
will be picked up automatically. By using `self.app.get` we can send an
|
that will be picked up automatically. By using `self.app.get` we can
|
||||||
HTTP `GET` request to the application with the given path. The return
|
send an HTTP `GET` request to the application with the given path.
|
||||||
value will be a :class:`~flask.Flask.response_class` object. We can now
|
The return value will be a :class:`~flask.Flask.response_class` object.
|
||||||
use the :attr:`~werkzeug.BaseResponse.data` attribute to inspect the
|
We can now use the :attr:`~werkzeug.wrappers.BaseResponse.data` attribute
|
||||||
return value (as string) from the application. In this case, we ensure
|
to inspect the return value (as string) from the application. In this
|
||||||
that ``'No entries here so far'`` is part of the output.
|
case, we ensure that ``'No entries here so far'`` is part of the output.
|
||||||
|
|
||||||
Run it again and you should see one passing test::
|
Run it again and you should see one passing test::
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue