Fixed a whole bunch of small docs typos, errors, and ommissions.
Fixes #8358, #8396, #8724, #9043, #9128, #9247, #9267, #9267, #9375, #9409, #9414, #9416, #9446, #9454, #9464, #9503, #9518, #9533, #9657, #9658, #9683, #9733, #9771, #9835, #9836, #9837, #9897, #9906, #9912, #9945, #9986, #9992, #10055, #10084, #10091, #10145, #10245, #10257, #10309, #10358, #10359, #10424, #10426, #10508, #10531, #10551, #10635, #10637, #10656, #10658, #10690, #10699, #19528. Thanks to all the respective authors of those tickets. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10371 bcc190cf-cafb-0310-a4f2-bffc1f526a37
|
@ -28,7 +28,9 @@ trailing_empty_content_re = re.compile(r'(?:<p>(?: |\s|<br \/>)*?</p>\s*)+\
|
|||
del x # Temporary variable
|
||||
|
||||
def escape(html):
|
||||
"""Returns the given HTML with ampersands, quotes and carets encoded."""
|
||||
"""
|
||||
Returns the given HTML with ampersands, quotes and angle brackets encoded.
|
||||
"""
|
||||
return mark_safe(force_unicode(html).replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", '''))
|
||||
escape = allow_lazy(escape, unicode)
|
||||
|
||||
|
|
|
@ -103,9 +103,9 @@ dt .literal, table .literal { background:none; }
|
|||
.note, .admonition { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; }
|
||||
.admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;}
|
||||
.admonition .last { margin-bottom:0 !important; }
|
||||
.note, .admonition { padding-left:65px; background:url(docicons-note.gif) .8em .8em no-repeat;}
|
||||
div.admonition-philosophy { padding-left:65px; background:url(docicons-philosophy.gif) .8em .8em no-repeat;}
|
||||
div.admonition-behind-the-scenes { padding-left:65px; background:url(docicons-behindscenes.gif) .8em .8em no-repeat;}
|
||||
.note, .admonition { padding-left:65px; background:url(docicons-note.png) .8em .8em no-repeat;}
|
||||
div.admonition-philosophy { padding-left:65px; background:url(docicons-philosophy.png) .8em .8em no-repeat;}
|
||||
div.admonition-behind-the-scenes { padding-left:65px; background:url(docicons-behindscenes.png) .8em .8em no-repeat;}
|
||||
|
||||
/*** versoinadded/changes ***/
|
||||
div.versionadded, div.versionchanged { }
|
||||
|
|
Before Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 632 B |
After Width: | Height: | Size: 1013 B |
Before Width: | Height: | Size: 799 B |
After Width: | Height: | Size: 1.5 KiB |
|
@ -63,7 +63,11 @@ backend storage system.
|
|||
|
||||
Called by ``Storage.save()``. The ``name`` will already have gone through
|
||||
``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
|
||||
``File`` object itself. No return value is expected.
|
||||
``File`` object itself.
|
||||
|
||||
Should return the actual name of name of the file saved (usually the ``name``
|
||||
passed in, but if the storage needs to change the file name return the new name
|
||||
instead).
|
||||
|
||||
``get_valid_name(name)``
|
||||
------------------------
|
||||
|
|
|
@ -17,14 +17,22 @@ performance gains over other server arrangements.
|
|||
Django requires Apache 2.x and mod_python 3.x, and you should use Apache's
|
||||
`prefork MPM`_, as opposed to the `worker MPM`_.
|
||||
|
||||
You may also be interested in :ref:`How to use Django with FastCGI, SCGI, or
|
||||
AJP <howto-deployment-fastcgi>`.
|
||||
.. seealso::
|
||||
|
||||
* Apache is a big, complex animal, and this document only scratches the
|
||||
surface of what Apache can do. If you need more advanced information about
|
||||
Apache, there's no better source than `Apache's own official
|
||||
documentation`_
|
||||
|
||||
* You may also be interested in :ref:`How to use Django with FastCGI, SCGI,
|
||||
or AJP <howto-deployment-fastcgi>`.
|
||||
|
||||
.. _Apache: http://httpd.apache.org/
|
||||
.. _mod_python: http://www.modpython.org/
|
||||
.. _mod_perl: http://perl.apache.org/
|
||||
.. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html
|
||||
.. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html
|
||||
.. _apache's own official documentation: http://httpd.apache.org/docs/
|
||||
|
||||
Basic configuration
|
||||
===================
|
||||
|
@ -52,15 +60,15 @@ Django mod_python handler." It passes the value of :ref:`DJANGO_SETTINGS_MODULE
|
|||
.. versionadded:: 1.0
|
||||
The ``PythonOption django.root ...`` is new in this version.
|
||||
|
||||
Because mod_python does not know we are
|
||||
serving this site from underneath the ``/mysite/`` prefix, this value needs to
|
||||
be passed through to the mod_python handler in Django, via the ``PythonOption
|
||||
django.root ...`` line. The value set on that line (the last item) should
|
||||
match the string given in the ``<Location ...>`` directive. The effect of this
|
||||
is that Django will automatically strip the ``/mysite`` string from the front
|
||||
of any URLs before matching them against your URLconf patterns. If you later
|
||||
move your site to live under ``/mysite2``, you will not have to change anything
|
||||
except the ``django.root`` option in the config file.
|
||||
Because mod_python does not know we are serving this site from underneath the
|
||||
``/mysite/`` prefix, this value needs to be passed through to the mod_python
|
||||
handler in Django, via the ``PythonOption django.root ...`` line. The value set
|
||||
on that line (the last item) should match the string given in the ``<Location
|
||||
...>`` directive. The effect of this is that Django will automatically strip the
|
||||
``/mysite`` string from the front of any URLs before matching them against your
|
||||
URLconf patterns. If you later move your site to live under ``/mysite2``, you
|
||||
will not have to change anything except the ``django.root`` option in the config
|
||||
file.
|
||||
|
||||
When using ``django.root`` you should make sure that what's left, after the
|
||||
prefix has been removed, begins with a slash. Your URLconf patterns that are
|
||||
|
@ -97,6 +105,10 @@ setting the Python path for interactive usage. Whenever you try to import
|
|||
something, Python will run through all the directories in ``sys.path`` in turn,
|
||||
from first to last, and try to import from each directory until one succeeds.
|
||||
|
||||
Make sure that your Python source files' permissions are set such that the
|
||||
Apache user (usually named ``apache`` or ``httpd`` on most systems) will have
|
||||
read access to the files.
|
||||
|
||||
An example might make this clearer. Suppose you have some applications under
|
||||
``/usr/local/django-apps/`` (for example, ``/usr/local/django-apps/weblog/`` and
|
||||
so forth), your settings file is at ``/var/www/mysite/settings.py`` and you have
|
||||
|
|
|
@ -47,7 +47,7 @@ look like in JSON:
|
|||
"first_name": "Paul",
|
||||
"last_name": "McCartney"
|
||||
}
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
And here's that same fixture as YAML:
|
||||
|
|
|
@ -10,9 +10,9 @@ How to serve static files
|
|||
Django itself doesn't serve static (media) files, such as images, style sheets,
|
||||
or video. It leaves that job to whichever Web server you choose.
|
||||
|
||||
The reasoning here is that standard Web servers, such as Apache_, lighttpd_ and Cherokee_,
|
||||
are much more fine-tuned at serving static files than a Web application
|
||||
framework.
|
||||
The reasoning here is that standard Web servers, such as Apache_, lighttpd_ and
|
||||
Cherokee_, are much more fine-tuned at serving static files than a Web
|
||||
application framework.
|
||||
|
||||
With that said, Django does support static files **during development**. You can
|
||||
use the :func:`django.views.static.serve` view to serve media files.
|
||||
|
@ -21,6 +21,11 @@ use the :func:`django.views.static.serve` view to serve media files.
|
|||
.. _lighttpd: http://www.lighttpd.net/
|
||||
.. _Cherokee: http://www.cherokee-project.com/
|
||||
|
||||
.. seealso::
|
||||
|
||||
If you just need to serve the admin media from a nonstandard location, see
|
||||
the :djadminopt:`--adminmedia` parameter to :djadmin:`runserver`.
|
||||
|
||||
The big, fat disclaimer
|
||||
=======================
|
||||
|
||||
|
|
|
@ -134,18 +134,27 @@ It worked!
|
|||
.. admonition:: Changing the port
|
||||
|
||||
By default, the :djadmin:`runserver` command starts the development server
|
||||
on port 8000. If you want to change the server's port, pass it as a
|
||||
command-line argument. For instance, this command starts the server on port
|
||||
8080:
|
||||
on the internal IP at port 8000.
|
||||
|
||||
If you want to change the server's port, pass
|
||||
it as a command-line argument. For instance, this command starts the server
|
||||
on port 8080:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python manage.py runserver 8080
|
||||
|
||||
If you want to change the server's IP, pass it along with the port. So to
|
||||
listen on all public IPs (useful if you want to show off your work on other
|
||||
computers), use:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python manage.py runserver 0.0.0.0:8000
|
||||
|
||||
Full docs for the development server can be found in the
|
||||
:djadmin:`runserver` reference.
|
||||
|
||||
|
||||
Database setup
|
||||
--------------
|
||||
|
||||
|
|
|
@ -302,6 +302,13 @@ for a given poll. Here's the view::
|
|||
The new concept here: The view raises the :exc:`~django.http.Http404` exception
|
||||
if a poll with the requested ID doesn't exist.
|
||||
|
||||
We'll discuss what you could put in that ``polls/detail.html`` template a bit
|
||||
later, but if you'd like to quickly get the above example working, just::
|
||||
|
||||
{{ poll }}
|
||||
|
||||
will get you started for now.
|
||||
|
||||
A shortcut: get_object_or_404()
|
||||
-------------------------------
|
||||
|
||||
|
@ -357,6 +364,10 @@ in ``django/conf/urls/defaults.py``, ``handler404`` is set to
|
|||
|
||||
Three more things to note about 404 views:
|
||||
|
||||
* If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
|
||||
404 view will never be used (and thus the ``404.html`` template will never
|
||||
be rendered) because the traceback will be displayed instead.
|
||||
|
||||
* The 404 view is also called if Django doesn't find a match after checking
|
||||
every regular expression in the URLconf.
|
||||
|
||||
|
@ -365,8 +376,9 @@ Three more things to note about 404 views:
|
|||
template in the root of your template directory. The default 404 view will
|
||||
use that template for all 404 errors.
|
||||
|
||||
* If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
|
||||
404 view will never be used, and the traceback will be displayed instead.
|
||||
* If :setting:`DEBUG` is set to ``False`` (in your settings module) and if
|
||||
you didn't create a ``404.html`` file, an ``Http500`` is raised instead.
|
||||
So remember to create a ``404.html``.
|
||||
|
||||
Write a 500 (server error) view
|
||||
===============================
|
||||
|
|
|
@ -20,7 +20,7 @@ tutorial, so that the template contains an HTML ``<form>`` element:
|
|||
|
||||
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
|
||||
|
||||
<form action="/polls/{{ poll.id }}/vote/" method="post">
|
||||
<form action="vote/" method="post">
|
||||
{% for choice in poll.choice_set.all %}
|
||||
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
|
||||
<label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
|
||||
|
@ -36,12 +36,12 @@ A quick rundown:
|
|||
selects one of the radio buttons and submits the form, it'll send the
|
||||
POST data ``choice=3``. This is HTML Forms 101.
|
||||
|
||||
* We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
|
||||
set ``method="post"``. Using ``method="post"`` (as opposed to
|
||||
``method="get"``) is very important, because the act of submitting this
|
||||
form will alter data server-side. Whenever you create a form that alters
|
||||
data server-side, use ``method="post"``. This tip isn't specific to
|
||||
Django; it's just good Web development practice.
|
||||
* We set the form's ``action`` to ``vote/``, and we set ``method="post"``.
|
||||
Using ``method="post"`` (as opposed to ``method="get"``) is very
|
||||
important, because the act of submitting this form will alter data
|
||||
server-side. Whenever you create a form that alters data server-side, use
|
||||
``method="post"``. This tip isn't specific to Django; it's just good Web
|
||||
development practice.
|
||||
|
||||
* ``forloop.counter`` indicates how many times the :ttag:`for` tag has gone
|
||||
through its loop
|
||||
|
@ -170,7 +170,17 @@ to write Python code to write an app.
|
|||
|
||||
Let's convert our poll app to use the generic views system, so we can delete a
|
||||
bunch of our own code. We'll just have to take a few steps to make the
|
||||
conversion.
|
||||
conversion. We will:
|
||||
|
||||
1. Convert the URLconf.
|
||||
|
||||
2. Rename a few templates.
|
||||
|
||||
3. Delete some the old, now unneeded views.
|
||||
|
||||
4. Fix up URL handling for the new views.
|
||||
|
||||
Read on for details.
|
||||
|
||||
.. admonition:: Why the code-shuffle?
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Third-party distributions of Django
|
||||
===================================
|
||||
|
||||
Several third-party distributors are now providing versions of Django integrated
|
||||
Many third-party distributors are now providing versions of Django integrated
|
||||
with their package-management systems. These can make installation and upgrading
|
||||
much easier for users of Django since the integration includes the ability to
|
||||
automatically install dependencies (like database adapters) that Django
|
||||
|
@ -15,81 +15,14 @@ if you want to use the development version of Django you'll need to follow the
|
|||
instructions for :ref:`installing the development version
|
||||
<installing-development-version>` from our Subversion repository.
|
||||
|
||||
FreeBSD
|
||||
=======
|
||||
If you're using Linux or a Unix installation, such as OpenSolaris,
|
||||
check with your distributor to see if they already package Django. If
|
||||
you're using a Linux distro and don't know how to find out if a package
|
||||
is available, then now is a good time to learn. The Django Wiki contains
|
||||
a list of `Third Party Distributions`_ to help you out.
|
||||
|
||||
The `FreeBSD`_ ports system offers both Django 0.96 (`py-django`_) and a more
|
||||
recent, but not current, version based on Django's trunk (`py-django-devel`_).
|
||||
These are installed in the normal FreeBSD way; for Django 0.96, for example, type:
|
||||
``cd /usr/ports/www/py-django && sudo make install clean``.
|
||||
.. _`Third Party Distributions`: http://code.djangoproject.com/wiki/Distributions
|
||||
|
||||
.. _FreeBSD: http://www.freebsd.org/
|
||||
.. _py-django: http://www.freebsd.org/cgi/cvsweb.cgi/ports/www/py-django/
|
||||
.. _py-django-devel: http://www.freebsd.org/cgi/cvsweb.cgi/ports/www/py-django-devel/
|
||||
|
||||
Linux distributions
|
||||
===================
|
||||
|
||||
Debian
|
||||
------
|
||||
|
||||
A `packaged version of Django`_ is available for `Debian GNU/Linux`_. Version
|
||||
0.95.1 is available in the "stable" repository; Version 0.96 is available in
|
||||
the "testing" and "unstable" repositories. Regardless of your chosen repository,
|
||||
you can install Django by typing ``apt-get install python-django``.
|
||||
|
||||
When you install this package, ``apt`` will recommend installing a database
|
||||
adapter; you should select and install the adapter for whichever database you
|
||||
plan to use with Django.
|
||||
|
||||
.. _Debian GNU/Linux: http://www.debian.org/
|
||||
.. _packaged version of Django: http://packages.debian.org/stable/python/python-django
|
||||
|
||||
Fedora
|
||||
------
|
||||
|
||||
A Django package is available for `Fedora Linux`_, in the "Fedora Extras"
|
||||
repository. The `current Fedora package`_ is based on Django 0.96, and can be
|
||||
installed by typing ``yum install Django``. The previous link is for the i386
|
||||
binary. Users of other architectures should be able to use that as a starting
|
||||
point to find their preferred version.
|
||||
|
||||
.. _Fedora Linux: http://fedora.redhat.com/
|
||||
.. _current Fedora package: http://download.fedora.redhat.com/pub/fedora/linux/extras/6/i386/repoview/Django.html
|
||||
|
||||
Gentoo
|
||||
------
|
||||
|
||||
A Django package is available for `Gentoo Linux`_, and is based on Django 0.96.1.
|
||||
The `current Gentoo package`_ can be installed by typing ``emerge django``.
|
||||
|
||||
.. _Gentoo Linux: http://www.gentoo.org/
|
||||
.. _current Gentoo package: http://packages.gentoo.org/package/django
|
||||
|
||||
Ubuntu
|
||||
------
|
||||
|
||||
The Debian ``python-django`` package is also available for `Ubuntu Linux`_, in
|
||||
the "universe" repository for Ubuntu 7.10 ("Gutsy Gibbon"). The `current Ubuntu
|
||||
package`_ is based on Django 0.96.1 and can be installed in the same fashion as
|
||||
for Debian.
|
||||
|
||||
.. _Ubuntu Linux: http://www.ubuntu.com/
|
||||
.. _current Ubuntu package: http://packages.ubuntu.com/gutsy/python/python-django
|
||||
|
||||
|
||||
Mac OS X
|
||||
========
|
||||
|
||||
MacPorts
|
||||
--------
|
||||
|
||||
Django 0.96 can be installed via the `MacPorts`_ system. If you're using Python 2.4,
|
||||
type ``sudo port install py-django-devel``. For Python 2.5, type ``sudo port
|
||||
install py25-django-devel``. MacPorts can also be used to install a database,
|
||||
and the Python interface to your chosen database.
|
||||
|
||||
.. _MacPorts: http://www.macports.org/
|
||||
|
||||
For distributors
|
||||
================
|
||||
|
|
Before Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.2 KiB |
|
@ -29,7 +29,7 @@ group in a box and applies certain styles to the elements within. An ``h2``
|
|||
within a ``div.module`` will align to the top of the ``div`` as a header for the
|
||||
whole group.
|
||||
|
||||
.. image:: _images/module.gif
|
||||
.. image:: _images/module.png
|
||||
:alt: Example use of module class on admin homepage
|
||||
|
||||
Column Types
|
||||
|
@ -134,7 +134,7 @@ Example from a changelist page:
|
|||
<li><a href="/stories/add/" class="addlink">Add redirect</a></li>
|
||||
</ul>
|
||||
|
||||
.. image:: _images/objecttools_01.gif
|
||||
.. image:: _images/objecttools_01.png
|
||||
:alt: Object tools on a changelist page
|
||||
|
||||
and from a form page:
|
||||
|
@ -146,7 +146,7 @@ and from a form page:
|
|||
<li><a href="/r/303/152383/" class="viewsitelink">View on site</a></li>
|
||||
</ul>
|
||||
|
||||
.. image:: _images/objecttools_02.gif
|
||||
.. image:: _images/objecttools_02.png
|
||||
:alt: Object tools on a form page
|
||||
|
||||
Form Styles
|
||||
|
@ -176,7 +176,7 @@ Each row of the form (within the ``fieldset``) should be enclosed in a ``div``
|
|||
with class ``form-row``. If the field in the row is required, a class of
|
||||
``required`` should also be added to the ``div.form-row``.
|
||||
|
||||
.. image:: _images/formrow.gif
|
||||
.. image:: _images/formrow.png
|
||||
:alt: Example use of form-row class
|
||||
|
||||
Labels
|
||||
|
|
|
@ -46,6 +46,11 @@ Other topics
|
|||
:maxdepth: 1
|
||||
|
||||
actions
|
||||
|
||||
.. seealso::
|
||||
|
||||
For information about serving the media files (images, JavaScript, and CSS)
|
||||
associated with the admin in production, see :ref:`serving-media-files`.
|
||||
|
||||
``ModelAdmin`` objects
|
||||
======================
|
||||
|
@ -425,8 +430,8 @@ edit and save multiple rows at once.
|
|||
``list_editable`` interacts with a couple of other options in particular
|
||||
ways; you should note the following rules:
|
||||
|
||||
* To use ``list_editable`` you must have defined ``ordering`` on
|
||||
either your model or your ``ModelAdmin``.
|
||||
* To use ``list_editable`` you must have defined ``ordering`` on either
|
||||
your model's or your ``ModelAdmin``'s inner ``Meta``.
|
||||
|
||||
* Any field in ``list_editable`` must also be in ``list_display``. You
|
||||
can't edit a field that's not displayed!
|
||||
|
@ -1155,6 +1160,37 @@ If you wish to change the index or login templates, you are better off creating
|
|||
your own ``AdminSite`` instance (see below), and changing the ``index_template``
|
||||
or ``login_template`` properties.
|
||||
|
||||
Linking to admin views
|
||||
======================
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
All the admin views use :ref:`named URL patterns <naming-url-patterns>` so it's
|
||||
easy to link to admin views with ``urlresolvers.reverse`` or the :ttag:`url`
|
||||
template tag.
|
||||
|
||||
Each model gets its own set of views and its own name using the model's app name
|
||||
and model name. For example, the "add" view for a ``Choice`` model in a
|
||||
``polls`` app would be named ``"admin_polls_choice_add"``.
|
||||
|
||||
All the available views and their names are:
|
||||
|
||||
============== ====================================== ===================
|
||||
View View name Parameters
|
||||
============== ====================================== ===================
|
||||
Change list ``"admin_<app>_<model>_changelist"`` None
|
||||
Add object ``"admin_<app>_<model>_add"`` None
|
||||
Change object ``"admin_<app>_<model>_change"`` ``object_id``
|
||||
Delete object ``"admin_<app>_<model>_delete"`` ``object_id``
|
||||
Object history ``"admin_<app>_<model>_history"`` ``object_id``
|
||||
============== ====================================== ===================
|
||||
|
||||
For example, to get the change URL for a particular ``Choice`` object::
|
||||
|
||||
>>> from django.core import urlresolvers
|
||||
>>> c = Choice.objects.get(...)
|
||||
>>> change_url = urlresolvers.reverse('admin_polls_choice_change', (c.id,))
|
||||
|
||||
``AdminSite`` objects
|
||||
=====================
|
||||
|
||||
|
|
|
@ -99,6 +99,10 @@ For example::
|
|||
{% for comment in comment_list %}
|
||||
...
|
||||
{% endfor %}
|
||||
|
||||
This returns a list of :class:`~django.contrib.comments.models.Comment` objects;
|
||||
see :ref:`the comment model documentation <ref-contrib-comments-models>` for
|
||||
details.
|
||||
|
||||
.. templatetag:: get_comment_count
|
||||
|
||||
|
@ -212,6 +216,7 @@ More information
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
models
|
||||
settings
|
||||
signals
|
||||
upgrade
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
.. _ref-contrib-comments-models:
|
||||
|
||||
===========================
|
||||
The built-in comment models
|
||||
===========================
|
||||
|
||||
.. module:: django.contrib.comments.models
|
||||
:synopsis: The built-in comment models
|
||||
|
||||
.. class:: Comment
|
||||
|
||||
Django's built-in comment model. Has the following fields:
|
||||
|
||||
.. attribute:: content_object
|
||||
|
||||
A :class:`~django.contrib.contettypes.generic.GenericForeignKey`
|
||||
attribute pointing to the object the comment is attached to. You can use
|
||||
this to get at the related object (i.e. ``my_comment.content_object``).
|
||||
|
||||
Since this field is a
|
||||
:class:`~django.contrib.contettypes.generic.GenericForeignKey`, it's
|
||||
actually syntactic sugar on top of two underlying attributes, described
|
||||
below.
|
||||
|
||||
.. attribute:: content_type
|
||||
|
||||
A :class:`~django.db.models.ForeignKey` to
|
||||
:class:`~django.contrib.contenttypes.models.ContentType`; this is the
|
||||
type of the object the comment is attached to.
|
||||
|
||||
.. attribute:: object_pk
|
||||
|
||||
A :class:`~django.db.models.TextField` containing the primary
|
||||
key of the object the comment is attached to.
|
||||
|
||||
.. attribute:: site
|
||||
|
||||
A :class:`~django.db.models.ForeignKey` to the
|
||||
:class:`~django.contrib.sites.models.Site` on which the comment was
|
||||
posted.
|
||||
|
||||
.. attribute:: user
|
||||
|
||||
A :class:`~django.db.models.ForeignKey` to the
|
||||
:class:`~django.contrib.auth.models.User` who posted the comment.
|
||||
May be blank if the comment was posted by an unauthenticated user.
|
||||
|
||||
.. attribute:: user_name
|
||||
|
||||
The name of the user who posted the comment.
|
||||
|
||||
.. attribute:: user_email
|
||||
|
||||
The email of the user who posteed the comment.
|
||||
|
||||
.. attribute:: user_url
|
||||
|
||||
The URL entered by the person who posted the comment.
|
||||
|
||||
.. attribute:: comment
|
||||
|
||||
The actual content of the comment itself.
|
||||
|
||||
.. attribute:: submit_date
|
||||
|
||||
The date the comment was submitted.
|
||||
|
||||
.. attribute:: ip_address
|
||||
|
||||
The IP address of the user posting the comment.
|
||||
|
||||
.. attribute:: is_public
|
||||
|
||||
``False`` if the comment is in moderation (see
|
||||
:ref:`ref-contrib-comments-moderation`); If ``True``, the comment will
|
||||
be displayed on the site.
|
||||
|
||||
.. attribute:: is_removed
|
||||
|
||||
``True`` if the comment was removed. Used to keep track of removed
|
||||
comments instead of just deleting them.
|
||||
|
|
@ -39,6 +39,11 @@ To install the flatpages app, follow these steps:
|
|||
``'django.contrib.sites'`` to your :setting:`INSTALLED_APPS` setting,
|
||||
if it's not already in there.
|
||||
|
||||
Also make sure you've correctly set :setting:`SITE_ID` to the ID of the
|
||||
site the settings file represents. This will usually be ``1`` (i.e.
|
||||
``SITE_ID = 1``, but if you're not using the sites framework to manage
|
||||
multiple sites, it could be the ID of a different site.
|
||||
|
||||
2. Add ``'django.contrib.flatpages'`` to your :setting:`INSTALLED_APPS`
|
||||
setting.
|
||||
|
||||
|
|
|
@ -160,11 +160,11 @@ into those elements.
|
|||
:class:`~django.contrib.syndication.feeds.Feed` class.
|
||||
|
||||
* To specify the contents of ``<link>``, you have two options. For each item
|
||||
in :meth:`items()`, Django first tries executing a ``get_absolute_url()``
|
||||
method on that object. If that method doesn't exist, it tries calling a
|
||||
method :meth:`item_link()` in the
|
||||
:class:`~django.contrib.syndication.feeds.Feed` class, passing it a single
|
||||
parameter, :attr:`item`, which is the object itself. Both
|
||||
in :meth:`items()`, Django first tries calling a method
|
||||
:meth:`item_link()` in the :class:`~django.contrib.syndication.feeds.Feed`
|
||||
class, passing it a single parameter, :attr:`item`, which is the object
|
||||
itself. If that method doesn't exist, Django tries executing a
|
||||
``get_absolute_url()`` method on that object. . Both
|
||||
``get_absolute_url()`` and :meth:`item_link()` should return the item's
|
||||
URL as a normal Python string. As with ``get_absolute_url()``, the result
|
||||
of :meth:`item_link()` will be included directly in the URL, so you are
|
||||
|
@ -644,9 +644,8 @@ This example illustrates all possible attributes and methods for a
|
|||
Returns the URL for every item in the feed.
|
||||
"""
|
||||
|
||||
# ITEM_GUID -- The following method is optional. This property is
|
||||
# only used for Atom feeds (it is the ID element for an item in an
|
||||
# Atom feed). If not provided, the item's link is used by default.
|
||||
# ITEM_GUID -- The following method is optional. If not provided, the
|
||||
# item's link is used by default.
|
||||
|
||||
def item_guid(self, obj):
|
||||
"""
|
||||
|
|
|
@ -80,7 +80,6 @@ You should also audit your existing code for any instances of this behavior
|
|||
before enabling this feature. It's faster, but it provides less automatic
|
||||
protection for multi-call operations.
|
||||
|
||||
|
||||
.. _mysql-notes:
|
||||
|
||||
MySQL notes
|
||||
|
@ -247,18 +246,18 @@ anything in a `MySQL option file`_.
|
|||
|
||||
Here's a sample configuration which uses a MySQL option file::
|
||||
|
||||
# settings.py
|
||||
DATABASE_ENGINE = "mysql"
|
||||
DATABASE_OPTIONS = {
|
||||
'read_default_file': '/path/to/my.cnf',
|
||||
}
|
||||
|
||||
# my.cnf
|
||||
[client]
|
||||
database = DATABASE_NAME
|
||||
user = DATABASE_USER
|
||||
password = DATABASE_PASSWORD
|
||||
default-character-set = utf8
|
||||
# settings.py
|
||||
DATABASE_ENGINE = "mysql"
|
||||
DATABASE_OPTIONS = {
|
||||
'read_default_file': '/path/to/my.cnf',
|
||||
}
|
||||
|
||||
# my.cnf
|
||||
[client]
|
||||
database = DATABASE_NAME
|
||||
user = DATABASE_USER
|
||||
password = DATABASE_PASSWORD
|
||||
default-character-set = utf8
|
||||
|
||||
Several other MySQLdb connection options may be useful, such as ``ssl``,
|
||||
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
|
||||
|
@ -426,6 +425,42 @@ This provides the ability to upgrade both the DB-API 2.0 interface or SQLite 3
|
|||
itself to versions newer than the ones included with your particular Python
|
||||
binary distribution, if needed.
|
||||
|
||||
"Database is locked" errors
|
||||
-----------------------------------------------
|
||||
|
||||
SQLite is meant to be a lightweight database, and thus can't support a high
|
||||
level of concurrency. ``OperationalError: database is locked`` errors indicate
|
||||
that your application is experiencing more concurrency than ``sqlite`` can
|
||||
handle in default configuration. This error means that one thread or process has
|
||||
an exclusive lock on the database connection and another thread timed out
|
||||
waiting for the lock the be released.
|
||||
|
||||
Python's SQLite wrapper has
|
||||
a default timeout value that determines how long the second thread is allowed to
|
||||
wait on the lock before it times out and raises the ``OperationalError: database
|
||||
is locked`` error.
|
||||
|
||||
If you're getting this error, you can solve it by:
|
||||
|
||||
* Switching to another database backend. At a certain point SQLite becomes
|
||||
too "lite" for real-world applications, and these sorts of concurrency
|
||||
errors indicate you've reached that point.
|
||||
|
||||
* Rewriting your code to reduce concurrency and ensure that database
|
||||
transactions are short-lived.
|
||||
|
||||
* Increase the default timeout value by setting the ``timeout`` database
|
||||
option option::
|
||||
|
||||
DATABASE_OPTIONS = {
|
||||
# ...
|
||||
"timeout": 20,
|
||||
# ...
|
||||
}
|
||||
|
||||
This will simply make SQLite wait a bit longer before throwing "database
|
||||
is locked" errors; it won't really do anything to solve them.
|
||||
|
||||
.. _oracle-notes:
|
||||
|
||||
Oracle notes
|
||||
|
|
|
@ -458,8 +458,10 @@ supports the FastCGI protocol. See the :ref:`FastCGI deployment documentation
|
|||
|
||||
.. _flup: http://www.saddi.com/software/flup/
|
||||
|
||||
runserver [optional port number, or ipaddr:port]
|
||||
------------------------------------------------
|
||||
runserver
|
||||
---------
|
||||
|
||||
.. django-admin:: runserver [port or ipaddr:port]
|
||||
|
||||
Starts a lightweight development Web server on the local machine. By default,
|
||||
the server runs on port 8000 on the IP address 127.0.0.1. You can pass in an
|
||||
|
@ -491,8 +493,7 @@ machines on your network. To make your development server viewable to other
|
|||
machines on the network, use its own IP address (e.g. ``192.168.2.1``) or
|
||||
``0.0.0.0``.
|
||||
|
||||
--adminmedia
|
||||
~~~~~~~~~~~~
|
||||
.. django-admin-option:: --adminmedia
|
||||
|
||||
Use the ``--adminmedia`` option to tell Django where to find the various CSS
|
||||
and JavaScript files for the Django admin interface. Normally, the development
|
||||
|
@ -503,8 +504,7 @@ Example usage::
|
|||
|
||||
django-admin.py runserver --adminmedia=/tmp/new-admin-style/
|
||||
|
||||
--noreload
|
||||
~~~~~~~~~~
|
||||
.. django-admin-option:: --noreload
|
||||
|
||||
Use the ``--noreload`` option to disable the use of the auto-reloader. This
|
||||
means any Python code changes you make while the server is running will *not*
|
||||
|
@ -541,14 +541,6 @@ By default, the development server doesn't serve any static files for your site
|
|||
(such as CSS files, images, things under ``MEDIA_URL`` and so forth). If
|
||||
you want to configure Django to serve static media, read :ref:`howto-static-files`.
|
||||
|
||||
Turning off auto-reload
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To disable auto-reloading of code while the development server is running, use the
|
||||
``--noreload`` option, like so::
|
||||
|
||||
django-admin.py runserver --noreload
|
||||
|
||||
shell
|
||||
-----
|
||||
|
||||
|
|
|
@ -129,6 +129,40 @@ what happens with unbound forms::
|
|||
>>> f.errors
|
||||
{}
|
||||
|
||||
Dynamic initial values
|
||||
----------------------
|
||||
|
||||
.. attribute:: Form.initial
|
||||
|
||||
Use ``initial`` to declare the initial value of form fields at runtime. For
|
||||
example, you might want to fill in a ``username`` field with the username of the
|
||||
current session.
|
||||
|
||||
To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
|
||||
if given, should be a dictionary mapping field names to initial values. Only
|
||||
include the fields for which you're specifying an initial value; it's not
|
||||
necessary to include every field in your form. For example::
|
||||
|
||||
>>> f = ContactForm(initial={'subject': 'Hi there!'})
|
||||
|
||||
These values are only displayed for unbound forms, and they're not used as
|
||||
fallback values if a particular value isn't provided.
|
||||
|
||||
Note that if a ``Field`` defines ``initial`` *and* you include ``initial`` when
|
||||
instantiating the ``Form``, then the latter ``initial`` will have precedence. In
|
||||
this example, ``initial`` is provided both at the field level and at the form
|
||||
instance level, and the latter gets precedence::
|
||||
|
||||
>>> class CommentForm(forms.Form):
|
||||
... name = forms.CharField(initial='class')
|
||||
... url = forms.URLField()
|
||||
... comment = forms.CharField()
|
||||
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
|
||||
>>> print f
|
||||
<tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
|
||||
Accessing "clean" data
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -127,6 +127,8 @@ We've specified ``auto_id=False`` to simplify the output::
|
|||
The ``initial`` argument lets you specify the initial value to use when
|
||||
rendering this ``Field`` in an unbound ``Form``.
|
||||
|
||||
To specify dynamic initial data, see the :attr:`Form.initial` parameter.
|
||||
|
||||
The use-case for this is when you want to display an "empty" form in which a
|
||||
field is initialized to a particular value. For example::
|
||||
|
||||
|
@ -234,7 +236,6 @@ fields. We've specified ``auto_id=False`` to simplify the output::
|
|||
|
||||
.. attribute:: Field.error_messages
|
||||
|
||||
|
||||
The ``error_messages`` argument lets you override the default messages that the
|
||||
field will raise. Pass in a dictionary with keys matching the error messages you
|
||||
want to override. For example, here is the default error message::
|
||||
|
@ -256,54 +257,6 @@ And here is a custom error message::
|
|||
In the `built-in Field classes`_ section below, each ``Field`` defines the
|
||||
error message keys it uses.
|
||||
|
||||
Dynamic initial values
|
||||
----------------------
|
||||
|
||||
The ``initial`` argument to ``Field`` (explained above) lets you hard-code the
|
||||
initial value for a ``Field`` -- but what if you want to declare the initial
|
||||
value at runtime? For example, you might want to fill in a ``username`` field
|
||||
with the username of the current session.
|
||||
|
||||
To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
|
||||
if given, should be a dictionary mapping field names to initial values. Only
|
||||
include the fields for which you're specifying an initial value; it's not
|
||||
necessary to include every field in your form. For example::
|
||||
|
||||
>>> class CommentForm(forms.Form):
|
||||
... name = forms.CharField()
|
||||
... url = forms.URLField()
|
||||
... comment = forms.CharField()
|
||||
>>> f = CommentForm(initial={'name': 'your username'}, auto_id=False)
|
||||
>>> print f
|
||||
<tr><th>Name:</th><td><input type="text" name="name" value="your username" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
>>> f = CommentForm(initial={'name': 'another username'}, auto_id=False)
|
||||
>>> print f
|
||||
<tr><th>Name:</th><td><input type="text" name="name" value="another username" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
|
||||
Just like the ``initial`` parameter to ``Field``, these values are only
|
||||
displayed for unbound forms, and they're not used as fallback values if a
|
||||
particular value isn't provided.
|
||||
|
||||
Finally, note that if a ``Field`` defines ``initial`` *and* you include
|
||||
``initial`` when instantiating the ``Form``, then the latter ``initial`` will
|
||||
have precedence. In this example, ``initial`` is provided both at the field
|
||||
level and at the form instance level, and the latter gets precedence::
|
||||
|
||||
>>> class CommentForm(forms.Form):
|
||||
... name = forms.CharField(initial='class')
|
||||
... url = forms.URLField()
|
||||
... comment = forms.CharField()
|
||||
>>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
|
||||
>>> print f
|
||||
<tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
|
||||
|
||||
Built-in ``Field`` classes
|
||||
--------------------------
|
||||
|
||||
|
@ -819,6 +772,20 @@ example::
|
|||
def label_from_instance(self, obj):
|
||||
return "My Object #%i" % obj.id
|
||||
|
||||
.. attribute:: ModelChoiceField.empty_label
|
||||
|
||||
By default the ``<select>`` widget used by ``ModelChoiceField`` will have a
|
||||
an empty choice at the top of the list. You can change the text of this label
|
||||
(which is ``"---------"`` by default) with the ``empty_label`` attribute, or
|
||||
you can disable the empty label entirely by setting ``empty_label`` to
|
||||
``None``::
|
||||
|
||||
# A custom empty label
|
||||
field1 = forms.ModelChoiceField(queryset=..., empty_label="(Nothing)")
|
||||
|
||||
# No empty label
|
||||
field2 = forms.ModelChoiceField(queryset=..., empty_label=None)
|
||||
|
||||
``ModelMultipleChoiceField``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -62,7 +62,8 @@ commonly used groups of widgets:
|
|||
|
||||
The format in which this field's initial value will be displayed.
|
||||
|
||||
If no ``format`` argument is provided, the default format is ``'%Y-%m-%d %H:%M:%S'``.
|
||||
If no ``format`` argument is provided, the default format is ``'%Y-%m-%d
|
||||
%H:%M:%S'``.
|
||||
|
||||
.. class:: TimeInput
|
||||
|
||||
|
@ -90,6 +91,8 @@ commonly used groups of widgets:
|
|||
.. class:: Select
|
||||
|
||||
Select widget: ``<select><option ...>...</select>``
|
||||
|
||||
Requires that your field provides :attr:`~Field.choices`.
|
||||
|
||||
.. class:: NullBooleanSelect
|
||||
|
||||
|
@ -100,6 +103,8 @@ commonly used groups of widgets:
|
|||
Select widget allowing multiple selection: ``<select
|
||||
multiple='multiple'>...</select>``
|
||||
|
||||
Requires that your field provides :attr:`~Field.choices`.
|
||||
|
||||
.. class:: RadioSelect
|
||||
|
||||
A list of radio buttons:
|
||||
|
@ -110,6 +115,8 @@ commonly used groups of widgets:
|
|||
<li><input type='radio' ...></li>
|
||||
...
|
||||
</ul>
|
||||
|
||||
Requires that your field provides :attr:`~Field.choices`.
|
||||
|
||||
.. class:: CheckboxSelectMultiple
|
||||
|
||||
|
|
|
@ -870,11 +870,11 @@ the model is related. This works exactly the same as it does for
|
|||
Behind the scenes, Django creates an intermediary join table to represent the
|
||||
many-to-many relationship. By default, this table name is generated using the
|
||||
names of the two tables being joined. Since some databases don't support table
|
||||
names above a certain length (often 32 characters), these table names will be
|
||||
automatically truncated to 32 characters and a uniqueness hash will be used.
|
||||
This means you might see table names like ``author_books_9cdf4``; this is
|
||||
perfectly normal. You can manually provide the name of the join table using
|
||||
the :attr:`~ManyToManyField.db_table` option.
|
||||
names above a certain length, these table names will be automatically
|
||||
truncated to 64 characters and a uniqueness hash will be used. This means you
|
||||
might see table names like ``author_books_9cdf4``; this is perfectly normal.
|
||||
You can manually provide the name of the join table using the
|
||||
:attr:`~ManyToManyField.db_table` option.
|
||||
|
||||
.. _manytomany-arguments:
|
||||
|
||||
|
@ -889,8 +889,9 @@ that control how the relationship functions.
|
|||
|
||||
Same as :attr:`ForeignKey.limit_choices_to`.
|
||||
|
||||
``limit_choices_to`` has no effect when used on a ``ManyToManyField`` with
|
||||
an intermediate table.
|
||||
``limit_choices_to`` has no effect when used on a ``ManyToManyField`` with a
|
||||
custom intermediate table specified using the
|
||||
:attr:`~ManyToManyField.through` paramter.
|
||||
|
||||
.. attribute:: ManyToManyField.symmetrical
|
||||
|
||||
|
@ -920,7 +921,8 @@ that control how the relationship functions.
|
|||
use.
|
||||
|
||||
The most common use for this option is when you want to associate
|
||||
:ref:`extra data with a many-to-many relationship <intermediary-manytomany>`.
|
||||
:ref:`extra data with a many-to-many relationship
|
||||
<intermediary-manytomany>`.
|
||||
|
||||
.. attribute:: ManyToManyField.db_table
|
||||
|
||||
|
|
|
@ -188,6 +188,18 @@ almost always do the right thing and trying to override that will lead to
|
|||
errors that are difficult to track down. This feature is for advanced use
|
||||
only.
|
||||
|
||||
Deleting objects
|
||||
================
|
||||
|
||||
.. method:: Model.delete()
|
||||
|
||||
Issues a SQL ``DELETE`` for the object. This only deletes the object in the
|
||||
database; the Python instance will still be around, and will still have data
|
||||
in its fields.
|
||||
|
||||
For more details, including how to delete objects in bulk, see
|
||||
:ref:`topics-db-queries-delete`.
|
||||
|
||||
.. _model-instance-methods:
|
||||
|
||||
Other model instance methods
|
||||
|
|
|
@ -4,11 +4,32 @@
|
|||
Related objects reference
|
||||
=========================
|
||||
|
||||
Extra methods on managers when used in a ForeignKey context
|
||||
===========================================================
|
||||
|
||||
.. currentmodule:: django.db.models
|
||||
|
||||
This document describes extra methods available on managers when used in a one-to-many or many-to-many related context. This happens in two cases:
|
||||
|
||||
* The "other side" of a ``ForeignKey`` relation. That is::
|
||||
|
||||
class Reporter(models.Model):
|
||||
...
|
||||
|
||||
class Article(models.Model):
|
||||
reporter = models.ForeignKey(Reporter)
|
||||
|
||||
In the above example, the methods below will be available on
|
||||
the manager ``reporter.article_set``.
|
||||
|
||||
* Both sides of a ``ManyToManyField`` relation::
|
||||
|
||||
class Topping(models.Model):
|
||||
...
|
||||
|
||||
class Pizza(models.Model):
|
||||
toppings = models.ManyToManyField(Topping)
|
||||
|
||||
In this example, the methods below will be available both on
|
||||
``topping.pizza_set`` and on ``pizza.toppings``.
|
||||
|
||||
.. method:: QuerySet.add(obj1, [obj2, ...])
|
||||
|
||||
Adds the specified model objects to the related object set.
|
||||
|
|
|
@ -323,7 +323,7 @@ optional, third positional argument, ``processors``. In this example, the
|
|||
c = RequestContext(request, {
|
||||
'foo': 'bar',
|
||||
}, [ip_address_processor])
|
||||
return t.render(c)
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
.. note::
|
||||
If you're using Django's ``render_to_response()`` shortcut to populate a
|
||||
|
@ -519,18 +519,19 @@ By default, Django uses a filesystem-based template loader, but Django comes
|
|||
with a few other template loaders, which know how to load templates from other
|
||||
sources.
|
||||
|
||||
These other loaders are disabled by default, but you can activate them by
|
||||
editing your :setting:`TEMPLATE_LOADERS` setting. :setting:`TEMPLATE_LOADERS`
|
||||
Some of these other loaders are disabled by default, but you can activate them
|
||||
by editing your :setting:`TEMPLATE_LOADERS` setting. :setting:`TEMPLATE_LOADERS`
|
||||
should be a tuple of strings, where each string represents a template loader.
|
||||
Here are the template loaders that come with Django:
|
||||
|
||||
``django.template.loaders.filesystem.load_template_source``
|
||||
Loads templates from the filesystem, according to :setting:`TEMPLATE_DIRS`.
|
||||
This loader is enabled by default.
|
||||
|
||||
``django.template.loaders.app_directories.load_template_source``
|
||||
Loads templates from Django apps on the filesystem. For each app in
|
||||
:setting:`INSTALLED_APPS`, the loader looks for a ``templates`` subdirectory. If
|
||||
the directory exists, Django looks for templates in there.
|
||||
:setting:`INSTALLED_APPS`, the loader looks for a ``templates``
|
||||
subdirectory. If the directory exists, Django looks for templates in there.
|
||||
|
||||
This means you can store templates with your individual apps. This also
|
||||
makes it easy to distribute Django apps with default templates.
|
||||
|
@ -545,16 +546,21 @@ Here are the template loaders that come with Django:
|
|||
* ``/path/to/myproject/polls/templates/foo.html``
|
||||
* ``/path/to/myproject/music/templates/foo.html``
|
||||
|
||||
Note that the loader performs an optimization when it is first imported:
|
||||
It caches a list of which :setting:`INSTALLED_APPS` packages have a ``templates``
|
||||
subdirectory.
|
||||
Note that the loader performs an optimization when it is first imported: It
|
||||
caches a list of which :setting:`INSTALLED_APPS` packages have a
|
||||
``templates`` subdirectory.
|
||||
|
||||
This loader is enabled by default.
|
||||
|
||||
``django.template.loaders.eggs.load_template_source``
|
||||
Just like ``app_directories`` above, but it loads templates from Python
|
||||
eggs rather than from the filesystem.
|
||||
|
||||
This loader is disabled by default.
|
||||
|
||||
Django uses the template loaders in order according to the :setting:`TEMPLATE_LOADERS`
|
||||
setting. It uses each loader until a loader finds a match.
|
||||
Django uses the template loaders in order according to the
|
||||
:setting:`TEMPLATE_LOADERS` setting. It uses each loader until a loader finds a
|
||||
match.
|
||||
|
||||
The ``render_to_string()`` shortcut
|
||||
===================================
|
||||
|
|
|
@ -273,7 +273,7 @@ You can pass either Unicode strings or UTF-8 bytestrings as arguments to
|
|||
querysets are identical::
|
||||
|
||||
qs = People.objects.filter(name__contains=u'Å')
|
||||
qs = People.objects.filter(name__contains='\xc3\85') # UTF-8 encoding of Å
|
||||
qs = People.objects.filter(name__contains='\xc3\x85') # UTF-8 encoding of Å
|
||||
|
||||
Templates
|
||||
=========
|
||||
|
|
|
@ -74,6 +74,14 @@ break anything if you leave them, but they also won't do anything. To register
|
|||
apps with the admin you'll move those declarations to an ``admin.py`` file;
|
||||
see `the admin`_ below for more details.
|
||||
|
||||
.. seealso::
|
||||
|
||||
A contributor to djangosnippets__ has written a script that'll `scan your
|
||||
models.py and generate a corresponding admin.py`__.
|
||||
|
||||
__ http://www.djangosnippets.org/
|
||||
__ http://www.djangosnippets.org/snippets/603/
|
||||
|
||||
Example
|
||||
~~~~~~~
|
||||
|
||||
|
@ -121,7 +129,7 @@ The Admin
|
|||
One of the biggest changes in 1.0 is the new admin. The Django administrative
|
||||
interface (``django.contrib.admin``) has been completely refactored; admin
|
||||
definitions are now completely decoupled from model definitions, the framework
|
||||
as been rewritten to use Django's new form-handling library and redesigned with
|
||||
has been rewritten to use Django's new form-handling library and redesigned with
|
||||
extensibility and customization in mind.
|
||||
|
||||
Practically, this means you'll need to rewrite all of your ``class Admin``
|
||||
|
@ -130,14 +138,6 @@ Admin`` with a ``admin.site.register()`` call in an ``admin.py`` file. Below are
|
|||
some more details on how to rewrite that ``Admin`` declaration into the new
|
||||
syntax.
|
||||
|
||||
.. seealso::
|
||||
|
||||
A contributor to djangosnippets__ has written a script that'll `scan your
|
||||
models.py and generate a corresponding admin.py`__.
|
||||
|
||||
__ http://www.djangosnippets.org/
|
||||
__ http://www.djangosnippets.org/snippets/603/
|
||||
|
||||
Use new inline syntax
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -320,6 +320,11 @@ Note that the ``width`` and ``height`` attributes only make sense for
|
|||
:class:`~django.db.models.ImageField` fields. More details can be found in the
|
||||
:ref:`model API <ref-models-fields>` documentation.
|
||||
|
||||
Use ``Paginator`` instead of ``ObjectPaginator``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``ObjectPaginator`` in 0.96 has been removed and replaced with an improved
|
||||
version, :class:`django.core.paginator.Paginator`.
|
||||
|
||||
Templates
|
||||
---------
|
||||
|
|
|
@ -208,9 +208,9 @@ Methods
|
|||
|
||||
.. method:: models.User.has_perm(perm)
|
||||
|
||||
Returns ``True`` if the user has the specified permission, where perm
|
||||
is in the format ``"package.codename"``. If the user is inactive, this
|
||||
method will always return ``False``.
|
||||
Returns ``True`` if the user has the specified permission, where perm is
|
||||
in the format ``"<application name>.<lowercased model name>"``. If the
|
||||
user is inactive, this method will always return ``False``.
|
||||
|
||||
.. method:: models.User.has_perms(perm_list)
|
||||
|
||||
|
@ -444,18 +444,18 @@ To indicate that this model is the user profile model for a given site, fill in
|
|||
the setting :setting:`AUTH_PROFILE_MODULE` with a string consisting of the
|
||||
following items, separated by a dot:
|
||||
|
||||
1. The (normalized to lower-case) name of the application in which the user
|
||||
profile model is defined (in other words, an all-lowercase version of the
|
||||
1. The name of the application (case sensitive) in which the user
|
||||
profile model is defined (in other words, the
|
||||
name which was passed to :djadmin:`manage.py startapp <startapp>` to create
|
||||
the application).
|
||||
|
||||
2. The (normalized to lower-case) name of the model class.
|
||||
2. The name of the model (not case sensitive) class.
|
||||
|
||||
For example, if the profile model was a class named ``UserProfile`` and was
|
||||
defined inside an application named ``accounts``, the appropriate setting would
|
||||
be::
|
||||
|
||||
AUTH_PROFILE_MODULE = 'accounts.userprofile'
|
||||
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
|
||||
|
||||
When a user profile model has been defined and specified in this manner, each
|
||||
:class:`~django.contrib.auth.models.User` object will have a method --
|
||||
|
@ -779,7 +779,7 @@ In addition to the :func:`~views.login` view, the authentication system
|
|||
includes a few other useful built-in views located in
|
||||
:mod:`django.contrib.auth.views`:
|
||||
|
||||
.. function:: views.logout(request, [next_page, template_name])
|
||||
.. function:: views.logout(request, [next_page, template_name, redirect_field_name])
|
||||
|
||||
Logs a user out.
|
||||
|
||||
|
@ -790,6 +790,10 @@ includes a few other useful built-in views located in
|
|||
* ``template_name``: The full name of a template to display after
|
||||
logging the user out. This will default to
|
||||
:file:`registration/logged_out.html` if no argument is supplied.
|
||||
|
||||
* ``redirect_field_name``: The name of a ``GET`` field containing the
|
||||
URL to redirect to after log out. Overrides ``next_page`` if the given
|
||||
``GET`` parameter is passed.
|
||||
|
||||
**Template context:**
|
||||
|
||||
|
@ -1017,6 +1021,10 @@ The permission_required decorator
|
|||
# ...
|
||||
my_view = permission_required('polls.can_vote')(my_view)
|
||||
|
||||
As for the :meth:`User.has_perm` method, permission names take the form
|
||||
``"<application name>.<lowercased model name>"`` (i.e. ``polls.choice`` for
|
||||
a ``Choice`` model in the ``polls`` application).
|
||||
|
||||
Note that :func:`~django.contrib.auth.decorators.permission_required()`
|
||||
also takes an optional ``login_url`` parameter. Example::
|
||||
|
||||
|
@ -1332,6 +1340,16 @@ The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same
|
|||
username and password is valid in multiple backends, Django will stop
|
||||
processing at the first positive match.
|
||||
|
||||
.. note::
|
||||
|
||||
Once a user has authenticated, Django stores which backend was used to
|
||||
authenticate the user in the user's session, and re-uses the same backend
|
||||
for subsequent authentication attempts for that user. This effectively means
|
||||
that authentication sources are cached, so if you change
|
||||
:setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
|
||||
you need to force users to re-authenticate using different methods. A simple
|
||||
way to do that is simply to execute ``Session.objects.all().delete()``.
|
||||
|
||||
Writing an authentication backend
|
||||
---------------------------------
|
||||
|
||||
|
|
|
@ -234,12 +234,12 @@ the ``CACHE_BACKEND`` setting. Valid arguments are as follows:
|
|||
backends, the maximum number of entries allowed in the cache before old
|
||||
values are deleted. This argument defaults to 300.
|
||||
|
||||
* ``cull_percentage``: The percentage of entries that are culled when
|
||||
``max_entries`` is reached. The actual ratio is ``1/cull_percentage``, so
|
||||
set ``cull_percentage=2`` to cull half of the entries when ``max_entries``
|
||||
* ``cull_frequency``: The fraction of entries that are culled when
|
||||
``max_entries`` is reached. The actual ratio is ``1/cull_frequency``, so
|
||||
set ``cull_frequency=2`` to cull half of the entries when ``max_entries``
|
||||
is reached.
|
||||
|
||||
A value of ``0`` for ``cull_percentage`` means that the entire cache will
|
||||
A value of ``0`` for ``cull_frequency`` means that the entire cache will
|
||||
be dumped when ``max_entries`` is reached. This makes culling *much*
|
||||
faster at the expense of more cache misses.
|
||||
|
||||
|
|
|
@ -165,12 +165,37 @@ ones:
|
|||
A choices list looks like this::
|
||||
|
||||
YEAR_IN_SCHOOL_CHOICES = (
|
||||
('FR', 'Freshman'),
|
||||
('SO', 'Sophomore'),
|
||||
('JR', 'Junior'),
|
||||
('SR', 'Senior'),
|
||||
('GR', 'Graduate'),
|
||||
(u'FR', u'Freshman'),
|
||||
(u'SO', u'Sophomore'),
|
||||
(u'JR', u'Junior'),
|
||||
(u'SR', u'Senior'),
|
||||
(u'GR', u'Graduate'),
|
||||
)
|
||||
|
||||
The first element in each tuple is the value that will be stored in the
|
||||
database, the second element will be displayed by the admin interface,
|
||||
or in a ModelChoiceField. Given an instance of a model object, the
|
||||
display value for a choices field can be accessed using the
|
||||
``get_FOO_display`` method. For example::
|
||||
|
||||
from django.db import models
|
||||
|
||||
class Person(models.Model):
|
||||
GENDER_CHOICES = (
|
||||
(u'M', u'Male'),
|
||||
(u'F', u'Female'),
|
||||
)
|
||||
name = models.CharField(max_length=60)
|
||||
gender = models.CharField(max_length=2, choices=GENDER_CHOICES)
|
||||
|
||||
::
|
||||
|
||||
>>> p = Person(name="Fred Flinstone", gender="M")
|
||||
>>> p.save()
|
||||
>>> p.gender
|
||||
u'M'
|
||||
>>> p.get_gender_display()
|
||||
u'Male'
|
||||
|
||||
:attr:`~Field.default`
|
||||
The default value for the field. This can be a value or a callable
|
||||
|
|
|
@ -267,9 +267,9 @@ of all the various ``QuerySet`` methods.
|
|||
Limiting QuerySets
|
||||
------------------
|
||||
|
||||
Use Python's array-slicing syntax to limit your ``QuerySet`` to a certain
|
||||
number of results. This is the equivalent of SQL's ``LIMIT`` and ``OFFSET``
|
||||
clauses.
|
||||
Use a subset of Python's array-slicing syntax to limit your ``QuerySet`` to a
|
||||
certain number of results. This is the equivalent of SQL's ``LIMIT`` and
|
||||
``OFFSET`` clauses.
|
||||
|
||||
For example, this returns the first 5 objects (``LIMIT 5``)::
|
||||
|
||||
|
@ -278,6 +278,9 @@ For example, this returns the first 5 objects (``LIMIT 5``)::
|
|||
This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
|
||||
|
||||
>>> Entry.objects.all()[5:10]
|
||||
|
||||
Negative indexing (i.e. ``Entry.objects.all()[-1]``) is not supported, nor is
|
||||
the third "step" slice parameter.
|
||||
|
||||
Generally, slicing a ``QuerySet`` returns a new ``QuerySet`` -- it doesn't
|
||||
evaluate the query. An exception is if you use the "step" parameter of Python
|
||||
|
|
|
@ -310,7 +310,9 @@ Using a formset in views and templates
|
|||
|
||||
Using a formset inside a view is as easy as using a regular ``Form`` class.
|
||||
The only thing you will want to be aware of is making sure to use the
|
||||
management form inside the template. Lets look at a sample view::
|
||||
management form inside the template. Let's look at a sample view:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def manage_articles(request):
|
||||
ArticleFormSet = formset_factory(ArticleForm)
|
||||
|
@ -355,7 +357,9 @@ You are able to use more than one formset in a view if you like. Formsets
|
|||
borrow much of its behavior from forms. With that said you are able to use
|
||||
``prefix`` to prefix formset form field names with a given value to allow
|
||||
more than one formset to be sent to a view without name clashing. Lets take
|
||||
a look at how this might be accomplished::
|
||||
a look at how this might be accomplished:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def manage_articles(request):
|
||||
ArticleFormSet = formset_factory(ArticleForm)
|
||||
|
|
|
@ -45,35 +45,62 @@ the full list of conversions:
|
|||
Model field Form field
|
||||
=============================== ========================================
|
||||
``AutoField`` Not represented in the form
|
||||
|
||||
``BooleanField`` ``BooleanField``
|
||||
|
||||
``CharField`` ``CharField`` with ``max_length`` set to
|
||||
the model field's ``max_length``
|
||||
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
|
||||
``DateField`` ``DateField``
|
||||
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
|
||||
``DecimalField`` ``DecimalField``
|
||||
|
||||
``EmailField`` ``EmailField``
|
||||
|
||||
``FileField`` ``FileField``
|
||||
|
||||
``FilePathField`` ``CharField``
|
||||
|
||||
``FloatField`` ``FloatField``
|
||||
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
|
||||
``ImageField`` ``ImageField``
|
||||
|
||||
``IntegerField`` ``IntegerField``
|
||||
|
||||
``IPAddressField`` ``IPAddressField``
|
||||
|
||||
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
|
||||
below)
|
||||
|
||||
``NullBooleanField`` ``CharField``
|
||||
|
||||
``PhoneNumberField`` ``USPhoneNumberField``
|
||||
(from ``django.contrib.localflavor.us``)
|
||||
|
||||
``PositiveIntegerField`` ``IntegerField``
|
||||
|
||||
``PositiveSmallIntegerField`` ``IntegerField``
|
||||
|
||||
``SlugField`` ``SlugField``
|
||||
|
||||
``SmallIntegerField`` ``IntegerField``
|
||||
``TextField`` ``CharField`` with ``widget=Textarea``
|
||||
|
||||
``TextField`` ``CharField`` with
|
||||
``widget=forms.Textarea``
|
||||
|
||||
``TimeField`` ``TimeField``
|
||||
|
||||
``URLField`` ``URLField`` with ``verify_exists`` set
|
||||
to the model field's ``verify_exists``
|
||||
``XMLField`` ``CharField`` with ``widget=Textarea``
|
||||
|
||||
``XMLField`` ``CharField`` with
|
||||
``widget=forms.Textarea``
|
||||
=============================== ========================================
|
||||
|
||||
|
||||
|
@ -458,14 +485,15 @@ queryset that includes all objects in the model (e.g.,
|
|||
|
||||
>>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
|
||||
|
||||
Alternatively, you can create a subclass that implements a ``get_queryset()``
|
||||
method::
|
||||
|
||||
Alternatively, you can create a subclass that sets ``self.queryset`` in
|
||||
``__init__``::
|
||||
|
||||
from django.forms.models import BaseModelFormSet
|
||||
|
||||
class BaseAuthorFormSet(BaseModelFormSet):
|
||||
def get_queryset(self):
|
||||
return super(BaseAuthorFormSet, self).get_queryset().filter(name__startswith='O')
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.queryset = Author.objects.filter(name__startswith='O')
|
||||
super(BaseAuthorFormSet, self).__init__(*args, **kwargs)
|
||||
|
||||
Then, pass your ``BaseAuthorFormSet`` class to the factory function::
|
||||
|
||||
|
|
|
@ -111,6 +111,12 @@ middleware is always called on every response.
|
|||
object. It could alter the given ``response``, or it could create and return a
|
||||
brand-new :class:`~django.http. HttpResponse`.
|
||||
|
||||
Remember that your middleware will not be called if another middleware object
|
||||
returns a response before you. But unlike ``process_request()`` and
|
||||
``process_view()``, during the response phase the classes are applied in reverse
|
||||
order, from the bottom up. This means classes defined at the end of
|
||||
:setting:`MIDDLEWARE_CLASSES` will be run first.
|
||||
|
||||
.. _exception-middleware:
|
||||
|
||||
``process_exception``
|
||||
|
@ -127,6 +133,10 @@ Django calls ``process_exception()`` when a view raises an exception.
|
|||
:class:`~django.http. HttpResponse` object, the response will be returned to
|
||||
the browser. Otherwise, default exception handling kicks in.
|
||||
|
||||
Again, middleware are run in reverse order during the response phase, which
|
||||
includes ``process_exception``. If an exception middleware return a response,
|
||||
the middleware classes above that middleware will not be called at all.
|
||||
|
||||
``__init__``
|
||||
------------
|
||||
|
||||
|
|
|
@ -9,6 +9,11 @@ objects into other formats. Usually these other formats will be text-based and
|
|||
used for sending Django objects over a wire, but it's possible for a
|
||||
serializer to handle any format (text-based or not).
|
||||
|
||||
.. seealso::
|
||||
|
||||
If you just want to get some data from your tables into a serialized
|
||||
form, you could use the :djadmin:`dumpdata` management command.
|
||||
|
||||
Serializing data
|
||||
----------------
|
||||
|
||||
|
|
|
@ -944,9 +944,10 @@ See the :djadmin:`dumpdata documentation<dumpdata>` for more details.
|
|||
Fixtures with other names can always be installed manually using the
|
||||
``manage.py loaddata`` command.
|
||||
|
||||
Once you've created a fixture and placed it somewhere in your Django project,
|
||||
you can use it in your unit tests by specifying a ``fixtures`` class attribute
|
||||
on your ``django.test.TestCase`` subclass::
|
||||
Once you've created a fixture and placed it in a ``fixtures`` directory in one
|
||||
of your :setting:`INSTALLED_APPS`, you can use it in your unit tests by
|
||||
specifying a ``fixtures`` class attribute on your ``django.test.TestCase``
|
||||
subclass::
|
||||
|
||||
from django.test import TestCase
|
||||
from myapp.models import Animal
|
||||
|
|