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