mirror of
https://github.com/django/django.git
synced 2025-08-04 02:48:35 +00:00
Fixed #30573 -- Rephrased documentation to avoid words that minimise the involved difficulty.
This patch does not remove all occurrences of the words in question. Rather, I went through all of the occurrences of the words listed below, and judged if they a) suggested the reader had some kind of knowledge/experience, and b) if they added anything of value (including tone of voice, etc). I left most of the words alone. I looked at the following words: - simply/simple - easy/easier/easiest - obvious - just - merely - straightforward - ridiculous Thanks to Carlton Gibson for guidance on how to approach this issue, and to Tim Bell for providing the idea. But the enormous lion's share of thanks go to Adam Johnson for his patient and helpful review.
This commit is contained in:
parent
addabc492b
commit
4a954cfd11
149 changed files with 1101 additions and 1157 deletions
|
@ -111,8 +111,8 @@ Using ``REMOTE_USER`` on login pages only
|
|||
|
||||
The ``RemoteUserMiddleware`` authentication middleware assumes that the HTTP
|
||||
request header ``REMOTE_USER`` is present with all authenticated requests. That
|
||||
might be expected and practical when Basic HTTP Auth with ``htpasswd`` or other
|
||||
simple mechanisms are used, but with Negotiate (GSSAPI/Kerberos) or other
|
||||
might be expected and practical when Basic HTTP Auth with ``htpasswd`` or
|
||||
similar mechanisms are used, but with Negotiate (GSSAPI/Kerberos) or other
|
||||
resource intensive authentication methods, the authentication in the front-end
|
||||
HTTP server is usually only set up for one or a few login URLs, and after
|
||||
successful authentication, the application is supposed to maintain the
|
||||
|
|
|
@ -9,10 +9,10 @@ filtering (for example, ``exact`` and ``icontains``). This documentation
|
|||
explains how to write custom lookups and how to alter the working of existing
|
||||
lookups. For the API references of lookups, see the :doc:`/ref/models/lookups`.
|
||||
|
||||
A simple lookup example
|
||||
=======================
|
||||
A lookup example
|
||||
================
|
||||
|
||||
Let's start with a simple custom lookup. We will write a custom lookup ``ne``
|
||||
Let's start with a small custom lookup. We will write a custom lookup ``ne``
|
||||
which works opposite to ``exact``. ``Author.objects.filter(name__ne='Jack')``
|
||||
will translate to the SQL:
|
||||
|
||||
|
@ -24,8 +24,7 @@ This SQL is backend independent, so we don't need to worry about different
|
|||
databases.
|
||||
|
||||
There are two steps to making this work. Firstly we need to implement the
|
||||
lookup, then we need to tell Django about it. The implementation is quite
|
||||
straightforward::
|
||||
lookup, then we need to tell Django about it::
|
||||
|
||||
from django.db.models import Lookup
|
||||
|
||||
|
@ -38,10 +37,10 @@ straightforward::
|
|||
params = lhs_params + rhs_params
|
||||
return '%s <> %s' % (lhs, rhs), params
|
||||
|
||||
To register the ``NotEqual`` lookup we will just need to call
|
||||
``register_lookup`` on the field class we want the lookup to be available. In
|
||||
this case, the lookup makes sense on all ``Field`` subclasses, so we register
|
||||
it with ``Field`` directly::
|
||||
To register the ``NotEqual`` lookup we will need to call ``register_lookup`` on
|
||||
the field class we want the lookup to be available for. In this case, the lookup
|
||||
makes sense on all ``Field`` subclasses, so we register it with ``Field``
|
||||
directly::
|
||||
|
||||
from django.db.models.fields import Field
|
||||
Field.register_lookup(NotEqual)
|
||||
|
@ -94,8 +93,8 @@ Finally we combine the parts into an SQL expression with ``<>``, and supply all
|
|||
the parameters for the query. We then return a tuple containing the generated
|
||||
SQL string and the parameters.
|
||||
|
||||
A simple transformer example
|
||||
============================
|
||||
A transformer example
|
||||
=====================
|
||||
|
||||
The custom lookup above is great, but in some cases you may want to be able to
|
||||
chain lookups together. For example, let's suppose we are building an
|
||||
|
@ -241,10 +240,10 @@ want the transformation to be applied to both the left-hand side and the
|
|||
right-hand side. For instance, if you want to filter a queryset based on the
|
||||
equality of the left and right-hand side insensitively to some SQL function.
|
||||
|
||||
Let's examine the simple example of case-insensitive transformation here. This
|
||||
transformation isn't very useful in practice as Django already comes with a bunch
|
||||
of built-in case-insensitive lookups, but it will be a nice demonstration of
|
||||
bilateral transformations in a database-agnostic way.
|
||||
Let's examine case-insensitive transformations here. This transformation isn't
|
||||
very useful in practice as Django already comes with a bunch of built-in
|
||||
case-insensitive lookups, but it will be a nice demonstration of bilateral
|
||||
transformations in a database-agnostic way.
|
||||
|
||||
We define an ``UpperCase`` transformer which uses the SQL function ``UPPER()`` to
|
||||
transform the values before comparison. We define
|
||||
|
|
|
@ -10,9 +10,9 @@ distributing. In this document, we will be building a custom ``closepoll``
|
|||
command for the ``polls`` application from the
|
||||
:doc:`tutorial</intro/tutorial01>`.
|
||||
|
||||
To do this, just add a ``management/commands`` directory to the application.
|
||||
Django will register a ``manage.py`` command for each Python module in that
|
||||
directory whose name doesn't begin with an underscore. For example::
|
||||
To do this, add a ``management/commands`` directory to the application. Django
|
||||
will register a ``manage.py`` command for each Python module in that directory
|
||||
whose name doesn't begin with an underscore. For example::
|
||||
|
||||
polls/
|
||||
__init__.py
|
||||
|
|
|
@ -50,7 +50,7 @@ something like this::
|
|||
|
||||
.. _Bridge: https://en.wikipedia.org/wiki/Contract_bridge
|
||||
|
||||
This is just an ordinary Python class, with nothing Django-specific about it.
|
||||
This is an ordinary Python class, with nothing Django-specific about it.
|
||||
We'd like to be able to do things like this in our models (we assume the
|
||||
``hand`` attribute on the model is an instance of ``Hand``)::
|
||||
|
||||
|
@ -81,11 +81,12 @@ Background theory
|
|||
Database storage
|
||||
----------------
|
||||
|
||||
The simplest way to think of a model field is that it provides a way to take a
|
||||
normal Python object -- string, boolean, ``datetime``, or something more
|
||||
complex like ``Hand`` -- and convert it to and from a format that is useful
|
||||
when dealing with the database (and serialization, but, as we'll see later,
|
||||
that falls out fairly naturally once you have the database side under control).
|
||||
Let's start with model fields. If you break it down, a model field provides a
|
||||
way to take a normal Python object -- string, boolean, ``datetime``, or
|
||||
something more complex like ``Hand`` -- and convert it to and from a format
|
||||
that is useful when dealing with the database. (Such a format is also useful
|
||||
for serialization, but as we'll see later, that is easier once you have the
|
||||
database side under control).
|
||||
|
||||
Fields in a model must somehow be converted to fit into an existing database
|
||||
column type. Different databases provide different sets of valid column types,
|
||||
|
@ -94,8 +95,7 @@ with. Anything you want to store in the database must fit into one of
|
|||
those types.
|
||||
|
||||
Normally, you're either writing a Django field to match a particular database
|
||||
column type, or there's a fairly straightforward way to convert your data to,
|
||||
say, a string.
|
||||
column type, or you will need a way to convert your data to, say, a string.
|
||||
|
||||
For our ``Hand`` example, we could convert the card data to a string of 104
|
||||
characters by concatenating all the cards together in a pre-determined order --
|
||||
|
@ -180,16 +180,16 @@ card values plus their suits; 104 characters in total.
|
|||
with. For example, you can pass both
|
||||
:attr:`~django.db.models.Field.editable` and
|
||||
:attr:`~django.db.models.DateField.auto_now` to a
|
||||
:class:`django.db.models.DateField` and it will simply ignore the
|
||||
:class:`django.db.models.DateField` and it will ignore the
|
||||
:attr:`~django.db.models.Field.editable` parameter
|
||||
(:attr:`~django.db.models.DateField.auto_now` being set implies
|
||||
``editable=False``). No error is raised in this case.
|
||||
|
||||
This behavior simplifies the field classes, because they don't need to
|
||||
check for options that aren't necessary. They just pass all the options to
|
||||
check for options that aren't necessary. They pass all the options to
|
||||
the parent class and then don't use them later on. It's up to you whether
|
||||
you want your fields to be more strict about the options they select, or to
|
||||
use the simpler, more permissive behavior of the current fields.
|
||||
use the more permissive behavior of the current fields.
|
||||
|
||||
The ``Field.__init__()`` method takes the following parameters:
|
||||
|
||||
|
@ -241,11 +241,11 @@ then there's no need to write a new ``deconstruct()`` method. If, however,
|
|||
you're changing the arguments passed in ``__init__()`` (like we are in
|
||||
``HandField``), you'll need to supplement the values being passed.
|
||||
|
||||
The contract of ``deconstruct()`` is simple; it returns a tuple of four items:
|
||||
the field's attribute name, the full import path of the field class, the
|
||||
positional arguments (as a list), and the keyword arguments (as a dict). Note
|
||||
this is different from the ``deconstruct()`` method :ref:`for custom classes
|
||||
<custom-deconstruct-method>` which returns a tuple of three things.
|
||||
``deconstruct()`` returns a tuple of four items: the field's attribute name,
|
||||
the full import path of the field class, the positional arguments (as a list),
|
||||
and the keyword arguments (as a dict). Note this is different from the
|
||||
``deconstruct()`` method :ref:`for custom classes <custom-deconstruct-method>`
|
||||
which returns a tuple of three things.
|
||||
|
||||
As a custom field author, you don't need to care about the first two values;
|
||||
the base ``Field`` class has all the code to work out the field's attribute
|
||||
|
@ -307,8 +307,8 @@ mind that people will be reconstructing your field from the serialized version
|
|||
for quite a while (possibly years), depending how long your migrations live for.
|
||||
|
||||
You can see the results of deconstruction by looking in migrations that include
|
||||
the field, and you can test deconstruction in unit tests by just deconstructing
|
||||
and reconstructing the field::
|
||||
the field, and you can test deconstruction in unit tests by deconstructing and
|
||||
reconstructing the field::
|
||||
|
||||
name, path, args, kwargs = my_field_instance.deconstruct()
|
||||
new_instance = MyField(*args, **kwargs)
|
||||
|
@ -349,10 +349,10 @@ As always, you should document your field type, so users will know what it is.
|
|||
In addition to providing a docstring for it, which is useful for developers,
|
||||
you can also allow users of the admin app to see a short description of the
|
||||
field type via the :doc:`django.contrib.admindocs
|
||||
</ref/contrib/admin/admindocs>` application. To do this simply provide
|
||||
descriptive text in a :attr:`~Field.description` class attribute of your custom
|
||||
field. In the above example, the description displayed by the ``admindocs``
|
||||
application for a ``HandField`` will be 'A hand of cards (bridge style)'.
|
||||
</ref/contrib/admin/admindocs>` application. To do this provide descriptive
|
||||
text in a :attr:`~Field.description` class attribute of your custom field. In
|
||||
the above example, the description displayed by the ``admindocs`` application
|
||||
for a ``HandField`` will be 'A hand of cards (bridge style)'.
|
||||
|
||||
In the :mod:`django.contrib.admindocs` display, the field description is
|
||||
interpolated with ``field.__dict__`` which allows the description to
|
||||
|
@ -393,8 +393,8 @@ Once you have ``MytypeField``, you can use it in any model, just like any other
|
|||
If you aim to build a database-agnostic application, you should account for
|
||||
differences in database column types. For example, the date/time column type
|
||||
in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
|
||||
``datetime``. The simplest way to handle this in a :meth:`~Field.db_type`
|
||||
method is to check the ``connection.settings_dict['ENGINE']`` attribute.
|
||||
``datetime``. You can handle this in a :meth:`~Field.db_type` method by
|
||||
checking the ``connection.settings_dict['ENGINE']`` attribute.
|
||||
|
||||
For example::
|
||||
|
||||
|
@ -431,7 +431,7 @@ sense to have a ``CharMaxlength25Field``, shown here::
|
|||
my_field = CharMaxlength25Field()
|
||||
|
||||
The better way of doing this would be to make the parameter specifiable at run
|
||||
time -- i.e., when the class is instantiated. To do that, just implement
|
||||
time -- i.e., when the class is instantiated. To do that, implement
|
||||
``Field.__init__()``, like so::
|
||||
|
||||
# This is a much more flexible example.
|
||||
|
@ -730,7 +730,7 @@ accessed, and what methods are available. It lives at
|
|||
:doc:`file documentation </ref/files/file>`.
|
||||
|
||||
Once a subclass of ``File`` is created, the new ``FileField`` subclass must be
|
||||
told to use it. To do so, simply assign the new ``File`` subclass to the special
|
||||
told to use it. To do so, assign the new ``File`` subclass to the special
|
||||
``attr_class`` attribute of the ``FileField`` subclass.
|
||||
|
||||
A few suggestions
|
||||
|
|
|
@ -89,7 +89,7 @@ an application.
|
|||
Writing custom template filters
|
||||
===============================
|
||||
|
||||
Custom filters are just Python functions that take one or two arguments:
|
||||
Custom filters are Python functions that take one or two arguments:
|
||||
|
||||
* The value of the variable (input) -- not necessarily a string.
|
||||
* The value of the argument -- this can have a default value, or be left
|
||||
|
@ -117,8 +117,8 @@ And here's an example of how that filter would be used:
|
|||
|
||||
{{ somevariable|cut:"0" }}
|
||||
|
||||
Most filters don't take arguments. In this case, just leave the argument out of
|
||||
your function. Example::
|
||||
Most filters don't take arguments. In this case, leave the argument out of your
|
||||
function::
|
||||
|
||||
def lower(value): # Only one argument.
|
||||
"""Converts a string into all lowercase"""
|
||||
|
@ -312,11 +312,11 @@ Template filter code falls into one of two situations:
|
|||
that our function will know whether automatic escaping is in effect when the
|
||||
filter is called. We use ``autoescape`` to decide whether the input data
|
||||
needs to be passed through ``django.utils.html.conditional_escape`` or not.
|
||||
(In the latter case, we just use the identity function as the "escape"
|
||||
function.) The ``conditional_escape()`` function is like ``escape()`` except
|
||||
it only escapes input that is **not** a ``SafeData`` instance. If a
|
||||
``SafeData`` instance is passed to ``conditional_escape()``, the data is
|
||||
returned unchanged.
|
||||
(In the latter case, we use the identity function as the "escape" function.)
|
||||
The ``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
|
@ -428,7 +428,7 @@ A few things to note about the ``simple_tag`` helper function:
|
|||
* Checking for the required number of arguments, etc., has already been
|
||||
done by the time our function is called, so we don't need to do that.
|
||||
* The quotes around the argument (if any) have already been stripped away,
|
||||
so we just receive a plain string.
|
||||
so we receive a plain string.
|
||||
* If the argument was a template variable, our function is passed the
|
||||
current value of the variable, not the variable itself.
|
||||
|
||||
|
@ -539,7 +539,7 @@ for the template fragment. Example::
|
|||
|
||||
Next, create the template used to render the tag's output. This template is a
|
||||
fixed feature of the tag: the tag writer specifies it, not the template
|
||||
designer. Following our example, the template is very simple:
|
||||
designer. Following our example, the template is very short:
|
||||
|
||||
.. code-block:: html+django
|
||||
|
||||
|
@ -645,10 +645,10 @@ the rendering works.
|
|||
|
||||
When Django compiles a template, it splits the raw template text into
|
||||
''nodes''. Each node is an instance of ``django.template.Node`` and has
|
||||
a ``render()`` method. A compiled template is, simply, a list of ``Node``
|
||||
objects. When you call ``render()`` on a compiled template object, the template
|
||||
calls ``render()`` on each ``Node`` in its node list, with the given context.
|
||||
The results are all concatenated together to form the output of the template.
|
||||
a ``render()`` method. A compiled template is a list of ``Node`` objects. When
|
||||
you call ``render()`` on a compiled template object, the template calls
|
||||
``render()`` on each ``Node`` in its node list, with the given context. The
|
||||
results are all concatenated together to form the output of the template.
|
||||
|
||||
Thus, to define a custom template tag, you specify how the raw template tag is
|
||||
converted into a ``Node`` (the compilation function), and what the node's
|
||||
|
@ -661,7 +661,7 @@ For each template tag the template parser encounters, it calls a Python
|
|||
function with the tag contents and the parser object itself. This function is
|
||||
responsible for returning a ``Node`` instance based on the contents of the tag.
|
||||
|
||||
For example, let's write a full implementation of our simple template tag,
|
||||
For example, let's write a full implementation of our template tag,
|
||||
``{% current_time %}``, that displays the current date/time, formatted according
|
||||
to a parameter given in the tag, in :func:`~time.strftime` syntax. It's a good
|
||||
idea to decide the tag syntax before anything else. In our case, let's say the
|
||||
|
@ -715,7 +715,7 @@ Notes:
|
|||
arguments.
|
||||
|
||||
* The function returns a ``CurrentTimeNode`` with everything the node needs
|
||||
to know about this tag. In this case, it just passes the argument --
|
||||
to know about this tag. In this case, it passes the argument --
|
||||
``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
|
||||
template tag are removed in ``format_string[1:-1]``.
|
||||
|
||||
|
@ -853,7 +853,7 @@ the same time:
|
|||
|
||||
The CycleNode is iterating, but it's iterating globally. As far as Thread 1
|
||||
and Thread 2 are concerned, it's always returning the same value. This is
|
||||
obviously not what we want!
|
||||
not what we want!
|
||||
|
||||
To address this problem, Django provides a ``render_context`` that's associated
|
||||
with the ``context`` of the template that is currently being rendered. The
|
||||
|
@ -965,9 +965,8 @@ You also have to change the renderer to retrieve the actual contents of the
|
|||
``date_updated`` property of the ``blog_entry`` object. This can be
|
||||
accomplished by using the ``Variable()`` class in ``django.template``.
|
||||
|
||||
To use the ``Variable`` class, simply instantiate it with the name of the
|
||||
variable to be resolved, and then call ``variable.resolve(context)``. So,
|
||||
for example::
|
||||
To use the ``Variable`` class, instantiate it with the name of the variable to
|
||||
be resolved, and then call ``variable.resolve(context)``. So, for example::
|
||||
|
||||
class FormatTimeNode(template.Node):
|
||||
def __init__(self, date_to_be_formatted, format_string):
|
||||
|
@ -987,11 +986,11 @@ cannot resolve the string passed to it in the current context of the page.
|
|||
Setting a variable in the context
|
||||
---------------------------------
|
||||
|
||||
The above examples simply output a value. Generally, it's more flexible if your
|
||||
The above examples output a value. Generally, it's more flexible if your
|
||||
template tags set template variables instead of outputting values. That way,
|
||||
template authors can reuse the values that your template tags create.
|
||||
|
||||
To set a variable in the context, just use dictionary assignment on the context
|
||||
To set a variable in the context, use dictionary assignment on the context
|
||||
object in the ``render()`` method. Here's an updated version of
|
||||
``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
|
||||
outputting it::
|
||||
|
@ -1116,7 +1115,7 @@ After ``parser.parse()`` is called, the parser hasn't yet "consumed" the
|
|||
``{% endcomment %}`` tag, so the code needs to explicitly call
|
||||
``parser.delete_first_token()``.
|
||||
|
||||
``CommentNode.render()`` simply returns an empty string. Anything between
|
||||
``CommentNode.render()`` returns an empty string. Anything between
|
||||
``{% comment %}`` and ``{% endcomment %}`` is ignored.
|
||||
|
||||
Parsing until another block tag, and saving contents
|
||||
|
|
|
@ -5,14 +5,14 @@ How to use Django with Gunicorn
|
|||
.. highlight:: bash
|
||||
|
||||
Gunicorn_ ('Green Unicorn') is a pure-Python WSGI server for UNIX. It has no
|
||||
dependencies and is easy to install and use.
|
||||
dependencies and can be installed using ``pip``.
|
||||
|
||||
.. _Gunicorn: https://gunicorn.org/
|
||||
|
||||
Installing Gunicorn
|
||||
===================
|
||||
|
||||
Installing gunicorn is as easy as ``python -m pip install gunicorn``. For more
|
||||
Install gunicorn by running ``python -m pip install gunicorn``. For more
|
||||
details, see the `gunicorn documentation`_.
|
||||
|
||||
.. _gunicorn documentation: https://docs.gunicorn.org/en/latest/install.html
|
||||
|
@ -21,10 +21,9 @@ Running Django in Gunicorn as a generic WSGI application
|
|||
========================================================
|
||||
|
||||
When Gunicorn is installed, a ``gunicorn`` command is available which starts
|
||||
the Gunicorn server process. At its simplest, gunicorn just needs to be called
|
||||
with the location of a module containing a WSGI application object named
|
||||
`application`. So for a typical Django project, invoking gunicorn would look
|
||||
like::
|
||||
the Gunicorn server process. The simplest invocation of gunicorn is to pass the
|
||||
location of a module containing a WSGI application object named
|
||||
``application``, which for a typical Django project would look like::
|
||||
|
||||
gunicorn myproject.wsgi
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ servers and applications.
|
|||
|
||||
.. _WSGI: https://wsgi.readthedocs.io/en/latest/
|
||||
|
||||
Django's :djadmin:`startproject` management command sets up a simple default
|
||||
Django's :djadmin:`startproject` management command sets up a minimal default
|
||||
WSGI configuration for you, which you can tweak as needed for your project,
|
||||
and direct any WSGI-compliant application server to use.
|
||||
|
||||
|
@ -70,8 +70,8 @@ If this variable isn't set, the default :file:`wsgi.py` sets it to
|
|||
Applying WSGI middleware
|
||||
========================
|
||||
|
||||
To apply `WSGI middleware`_ you can simply wrap the application object. For
|
||||
instance you could add these lines at the bottom of :file:`wsgi.py`::
|
||||
To apply `WSGI middleware`_ you can wrap the application object. For instance
|
||||
you could add these lines at the bottom of :file:`wsgi.py`::
|
||||
|
||||
from helloworld.wsgi import HelloWorldApplication
|
||||
application = HelloWorldApplication(application)
|
||||
|
|
|
@ -57,8 +57,8 @@ virtualenv guide`_ for more details.
|
|||
The ``WSGIPythonPath`` line ensures that your project package is available for
|
||||
import on the Python path; in other words, that ``import mysite`` works.
|
||||
|
||||
The ``<Directory>`` piece just ensures that Apache can access your
|
||||
:file:`wsgi.py` file.
|
||||
The ``<Directory>`` piece ensures that Apache can access your :file:`wsgi.py`
|
||||
file.
|
||||
|
||||
Next we'll need to ensure this :file:`wsgi.py` with a WSGI application object
|
||||
exists. As of Django version 1.4, :djadmin:`startproject` will have created one
|
||||
|
|
|
@ -8,9 +8,9 @@ also prevent malicious users from seeing details of your application that can be
|
|||
revealed by the error pages.
|
||||
|
||||
However, running with :setting:`DEBUG` set to ``False`` means you'll never see
|
||||
errors generated by your site -- everyone will just see your public error pages.
|
||||
You need to keep track of errors that occur in deployed sites, so Django can be
|
||||
configured to create reports with details about those errors.
|
||||
errors generated by your site -- everyone will instead see your public error
|
||||
pages. You need to keep track of errors that occur in deployed sites, so Django
|
||||
can be configured to create reports with details about those errors.
|
||||
|
||||
Email reports
|
||||
=============
|
||||
|
@ -63,7 +63,7 @@ not found" errors). Django sends emails about 404 errors when:
|
|||
If those conditions are met, Django will email the users listed in the
|
||||
:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
|
||||
a referer. It doesn't bother to email for 404s that don't have a referer --
|
||||
those are usually just people typing in broken URLs or broken Web bots. It also
|
||||
those are usually people typing in broken URLs or broken Web bots. It also
|
||||
ignores 404s when the referer is equal to the requested URL, since this
|
||||
behavior is from broken Web bots too.
|
||||
|
||||
|
|
|
@ -32,8 +32,8 @@ Or, you can write fixtures by hand; fixtures can be written as JSON, XML or YAML
|
|||
|
||||
.. _PyYAML: https://pyyaml.org/
|
||||
|
||||
As an example, though, here's what a fixture for a simple ``Person`` model might
|
||||
look like in JSON:
|
||||
As an example, though, here's what a fixture for a ``Person`` model might look
|
||||
like in JSON:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
|
@ -73,7 +73,7 @@ And here's that same fixture as YAML:
|
|||
|
||||
You'll store this data in a ``fixtures`` directory inside your app.
|
||||
|
||||
Loading data is easy: just call :djadmin:`manage.py loaddata <loaddata>`
|
||||
You can load data by calling :djadmin:`manage.py loaddata <loaddata>`
|
||||
``<fixturename>``, where ``<fixturename>`` is the name of the fixture file
|
||||
you've created. Each time you run :djadmin:`loaddata`, the data will be read
|
||||
from the fixture and re-loaded into the database. Note this means that if you
|
||||
|
|
|
@ -62,7 +62,7 @@ each table's creation, modification, and deletion::
|
|||
|
||||
If you do want to allow Django to manage the table's lifecycle, you'll need to
|
||||
change the :attr:`~django.db.models.Options.managed` option above to ``True``
|
||||
(or simply remove it because ``True`` is its default value).
|
||||
(or remove it because ``True`` is its default value).
|
||||
|
||||
Install the core Django tables
|
||||
==============================
|
||||
|
|
|
@ -41,17 +41,16 @@ mention:
|
|||
contains the name of the CSV file. This filename is arbitrary; call it
|
||||
whatever you want. It'll be used by browsers in the "Save as..." dialog, etc.
|
||||
|
||||
* Hooking into the CSV-generation API is easy: Just pass ``response`` as the
|
||||
first argument to ``csv.writer``. The ``csv.writer`` function expects a
|
||||
file-like object, and :class:`~django.http.HttpResponse` objects fit the
|
||||
bill.
|
||||
* You can hook into the CSV-generation API by passing ``response`` as the first
|
||||
argument to ``csv.writer``. The ``csv.writer`` function expects a file-like
|
||||
object, and :class:`~django.http.HttpResponse` objects fit the bill.
|
||||
|
||||
* For each row in your CSV file, call ``writer.writerow``, passing it an
|
||||
:term:`iterable`.
|
||||
|
||||
* The CSV module takes care of quoting for you, so you don't have to worry
|
||||
about escaping strings with quotes or commas in them. Just pass
|
||||
``writerow()`` your raw strings, and it'll do the right thing.
|
||||
about escaping strings with quotes or commas in them. Pass ``writerow()``
|
||||
your raw strings, and it'll do the right thing.
|
||||
|
||||
.. _streaming-csv-files:
|
||||
|
||||
|
@ -137,9 +136,9 @@ Then, create the template ``my_template_name.txt``, with this template code:
|
|||
{% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
|
||||
{% endfor %}
|
||||
|
||||
This template is quite basic. It just iterates over the given data and displays
|
||||
a line of CSV for each row. It uses the :tfilter:`addslashes` template filter to
|
||||
ensure there aren't any problems with quotes.
|
||||
This short template iterates over the given data and displays a line of CSV for
|
||||
each row. It uses the :tfilter:`addslashes` template filter to ensure there
|
||||
aren't any problems with quotes.
|
||||
|
||||
Other text-based formats
|
||||
========================
|
||||
|
|
|
@ -88,7 +88,7 @@ mention:
|
|||
* You can provide an arbitrary ``filename`` parameter. It'll be used by browsers
|
||||
in the "Save as..." dialog.
|
||||
|
||||
* Hooking into the ReportLab API is easy: The same buffer passed as the first
|
||||
* You can hook into the ReportLab API: The same buffer passed as the first
|
||||
argument to ``canvas.Canvas`` can be fed to the
|
||||
:class:`~django.http.FileResponse` class.
|
||||
|
||||
|
|
|
@ -12,13 +12,14 @@ Deploying static files
|
|||
Serving static files in production
|
||||
==================================
|
||||
|
||||
The basic outline of putting static files into production is simple: run the
|
||||
:djadmin:`collectstatic` command when static files change, then arrange for
|
||||
the collected static files directory (:setting:`STATIC_ROOT`) to be moved to
|
||||
the static file server and served. Depending on :setting:`STATICFILES_STORAGE`,
|
||||
files may need to be moved to a new location manually or the :func:`post_process
|
||||
<django.contrib.staticfiles.storage.StaticFilesStorage.post_process>` method
|
||||
of the ``Storage`` class might take care of that.
|
||||
The basic outline of putting static files into production consists of two
|
||||
steps: run the :djadmin:`collectstatic` command when static files change, then
|
||||
arrange for the collected static files directory (:setting:`STATIC_ROOT`) to be
|
||||
moved to the static file server and served. Depending on
|
||||
:setting:`STATICFILES_STORAGE`, files may need to be moved to a new location
|
||||
manually or the :func:`post_process
|
||||
<django.contrib.staticfiles.storage.StaticFilesStorage.post_process>` method of
|
||||
the ``Storage`` class might take care of that.
|
||||
|
||||
Of course, as with all deployment tasks, the devil's in the details. Every
|
||||
production setup will be a bit different, so you'll need to adapt the basic
|
||||
|
@ -80,11 +81,11 @@ When using these services, the basic workflow would look a bit like the above,
|
|||
except that instead of using ``rsync`` to transfer your static files to the
|
||||
server you'd need to transfer the static files to the storage provider or CDN.
|
||||
|
||||
There's any number of ways you might do this, but if the provider has an API a
|
||||
:doc:`custom file storage backend </howto/custom-file-storage>` will make the
|
||||
process incredibly simple. If you've written or are using a 3rd party custom
|
||||
storage backend, you can tell :djadmin:`collectstatic` to use it by setting
|
||||
:setting:`STATICFILES_STORAGE` to the storage engine.
|
||||
There's any number of ways you might do this, but if the provider has an API,
|
||||
you can use a :doc:`custom file storage backend </howto/custom-file-storage>`
|
||||
to integrate the CDN with your Django project. If you've written or are using a
|
||||
3rd party custom storage backend, you can tell :djadmin:`collectstatic` to use
|
||||
it by setting :setting:`STATICFILES_STORAGE` to the storage engine.
|
||||
|
||||
For example, if you've written an S3 storage backend in
|
||||
``myproject.storage.S3Storage`` you could use it with::
|
||||
|
@ -93,8 +94,8 @@ For example, if you've written an S3 storage backend in
|
|||
|
||||
Once that's done, all you have to do is run :djadmin:`collectstatic` and your
|
||||
static files would be pushed through your storage package up to S3. If you
|
||||
later needed to switch to a different storage provider, it could be as simple
|
||||
as changing your :setting:`STATICFILES_STORAGE` setting.
|
||||
later needed to switch to a different storage provider, you may only have to
|
||||
change your :setting:`STATICFILES_STORAGE` setting.
|
||||
|
||||
For details on how you'd write one of these backends, see
|
||||
:doc:`/howto/custom-file-storage`. There are 3rd party apps available that
|
||||
|
|
|
@ -67,7 +67,7 @@ details on how ``staticfiles`` finds your files.
|
|||
first static file it finds whose name matches, and if you had a static file
|
||||
with the same name in a *different* application, Django would be unable to
|
||||
distinguish between them. We need to be able to point Django at the right
|
||||
one, and the easiest way to ensure this is by *namespacing* them. That is,
|
||||
one, and the best way to ensure this is by *namespacing* them. That is,
|
||||
by putting those static files inside *another* directory named for the
|
||||
application itself.
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ Install ``virtualenv`` and ``virtualenvwrapper``
|
|||
`virtualenv`_ and `virtualenvwrapper`_ provide a dedicated environment for
|
||||
each Django project you create. While not mandatory, this is considered a best
|
||||
practice and will save you time in the future when you're ready to deploy your
|
||||
project. Simply type::
|
||||
project. To do this, run::
|
||||
|
||||
...\> py -m pip install virtualenvwrapper-win
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue