mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
[soc2009/multidb] Merged up to trunk r11205
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/multidb@11209 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -6,10 +6,16 @@ import docutils.nodes
|
||||
import docutils.transforms
|
||||
import sphinx
|
||||
import sphinx.addnodes
|
||||
import sphinx.builder
|
||||
try:
|
||||
from sphinx import builders
|
||||
except ImportError:
|
||||
import sphinx.builder as builders
|
||||
import sphinx.directives
|
||||
import sphinx.environment
|
||||
import sphinx.htmlwriter
|
||||
try:
|
||||
import sphinx.writers.html as sphinx_htmlwriter
|
||||
except ImportError:
|
||||
import sphinx.htmlwriter as sphinx_htmlwriter
|
||||
import sphinx.roles
|
||||
from docutils import nodes
|
||||
|
||||
@@ -44,7 +50,7 @@ def setup(app):
|
||||
directivename = "django-admin-option",
|
||||
rolename = "djadminopt",
|
||||
indextemplate = "pair: %s; django-admin command-line option",
|
||||
parse_node = lambda env, sig, signode: sphinx.directives.parse_option_desc(signode, sig),
|
||||
parse_node = parse_django_adminopt_node,
|
||||
)
|
||||
app.add_config_value('django_next_version', '0.0', True)
|
||||
app.add_directive('versionadded', parse_version_directive, 1, (1, 1, 1))
|
||||
@@ -102,7 +108,7 @@ class SuppressBlockquotes(docutils.transforms.Transform):
|
||||
if len(node.children) == 1 and isinstance(node.children[0], self.suppress_blockquote_child_nodes):
|
||||
node.replace_self(node.children[0])
|
||||
|
||||
class DjangoHTMLTranslator(sphinx.htmlwriter.SmartyPantsHTMLTranslator):
|
||||
class DjangoHTMLTranslator(sphinx_htmlwriter.SmartyPantsHTMLTranslator):
|
||||
"""
|
||||
Django-specific reST to HTML tweaks.
|
||||
"""
|
||||
@@ -125,10 +131,10 @@ class DjangoHTMLTranslator(sphinx.htmlwriter.SmartyPantsHTMLTranslator):
|
||||
#
|
||||
def visit_literal_block(self, node):
|
||||
self.no_smarty += 1
|
||||
sphinx.htmlwriter.SmartyPantsHTMLTranslator.visit_literal_block(self, node)
|
||||
|
||||
sphinx_htmlwriter.SmartyPantsHTMLTranslator.visit_literal_block(self, node)
|
||||
|
||||
def depart_literal_block(self, node):
|
||||
sphinx.htmlwriter.SmartyPantsHTMLTranslator.depart_literal_block(self, node)
|
||||
sphinx_htmlwriter.SmartyPantsHTMLTranslator.depart_literal_block(self, node)
|
||||
self.no_smarty -= 1
|
||||
|
||||
#
|
||||
@@ -162,7 +168,7 @@ class DjangoHTMLTranslator(sphinx.htmlwriter.SmartyPantsHTMLTranslator):
|
||||
# Give each section a unique ID -- nice for custom CSS hooks
|
||||
# This is different on docutils 0.5 vs. 0.4...
|
||||
|
||||
if hasattr(sphinx.htmlwriter.SmartyPantsHTMLTranslator, 'start_tag_with_title') and sphinx.__version__ == '0.4.2':
|
||||
if hasattr(sphinx_htmlwriter.SmartyPantsHTMLTranslator, 'start_tag_with_title') and sphinx.__version__ == '0.4.2':
|
||||
def start_tag_with_title(self, node, tagname, **atts):
|
||||
node = {
|
||||
'classes': node.get('classes', []),
|
||||
@@ -176,7 +182,7 @@ class DjangoHTMLTranslator(sphinx.htmlwriter.SmartyPantsHTMLTranslator):
|
||||
node['ids'] = ['s-' + i for i in old_ids]
|
||||
if sphinx.__version__ != '0.4.2':
|
||||
node['ids'].extend(old_ids)
|
||||
sphinx.htmlwriter.SmartyPantsHTMLTranslator.visit_section(self, node)
|
||||
sphinx_htmlwriter.SmartyPantsHTMLTranslator.visit_section(self, node)
|
||||
node['ids'] = old_ids
|
||||
|
||||
def parse_django_admin_node(env, sig, signode):
|
||||
@@ -186,6 +192,25 @@ def parse_django_admin_node(env, sig, signode):
|
||||
signode += sphinx.addnodes.desc_name(title, title)
|
||||
return sig
|
||||
|
||||
def parse_django_adminopt_node(env, sig, signode):
|
||||
"""A copy of sphinx.directives.CmdoptionDesc.parse_signature()"""
|
||||
from sphinx import addnodes
|
||||
from sphinx.directives.desc import option_desc_re
|
||||
count = 0
|
||||
firstname = ''
|
||||
for m in option_desc_re.finditer(sig):
|
||||
optname, args = m.groups()
|
||||
if count:
|
||||
signode += addnodes.desc_addname(', ', ', ')
|
||||
signode += addnodes.desc_name(optname, optname)
|
||||
signode += addnodes.desc_addname(args, args)
|
||||
if not count:
|
||||
firstname = optname
|
||||
count += 1
|
||||
if not firstname:
|
||||
raise ValueError
|
||||
return firstname
|
||||
|
||||
def monkeypatch_pickle_builder():
|
||||
import shutil
|
||||
from os import path
|
||||
@@ -214,12 +239,12 @@ def monkeypatch_pickle_builder():
|
||||
|
||||
# copy the environment file from the doctree dir to the output dir
|
||||
# as needed by the web app
|
||||
shutil.copyfile(path.join(self.doctreedir, sphinx.builder.ENV_PICKLE_FILENAME),
|
||||
path.join(self.outdir, sphinx.builder.ENV_PICKLE_FILENAME))
|
||||
shutil.copyfile(path.join(self.doctreedir, builders.ENV_PICKLE_FILENAME),
|
||||
path.join(self.outdir, builders.ENV_PICKLE_FILENAME))
|
||||
|
||||
# touch 'last build' file, used by the web application to determine
|
||||
# when to reload its environment and clear the cache
|
||||
open(path.join(self.outdir, sphinx.builder.LAST_BUILD_FILENAME), 'w').close()
|
||||
open(path.join(self.outdir, builders.LAST_BUILD_FILENAME), 'w').close()
|
||||
|
||||
builders.PickleHTMLBuilder.handle_finish = handle_finish
|
||||
|
||||
sphinx.builder.PickleHTMLBuilder.handle_finish = handle_finish
|
||||
|
||||
|
||||
2
docs/_templates/layout.html
vendored
2
docs/_templates/layout.html
vendored
@@ -1,6 +1,6 @@
|
||||
{% extends "!layout.html" %}
|
||||
|
||||
{%- macro secondnav %}
|
||||
{%- macro secondnav() %}
|
||||
{%- if prev %}
|
||||
« <a href="{{ prev.link|e }}" title="{{ prev.title|e }}">previous</a>
|
||||
{{ reldelim2 }}
|
||||
|
||||
@@ -37,20 +37,19 @@ Set the :setting:`CACHE_MIDDLEWARE_ANONYMOUS_ONLY` setting to ``True``. See the
|
||||
How do I automatically set a field's value to the user who last edited the object in the admin?
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
At this point, Django doesn't have an official way to do this. But it's an oft-requested
|
||||
feature, so we're discussing how it can be implemented. The problem is we don't want to couple
|
||||
the model layer with the admin layer with the request layer (to get the current user). It's a
|
||||
tricky problem.
|
||||
|
||||
One person hacked up a `solution that doesn't require patching Django`_, but note that it's an
|
||||
unofficial solution, and there's no guarantee it won't break at some point.
|
||||
|
||||
.. _solution that doesn't require patching Django: http://lukeplant.me.uk/blog.php?id=1107301634
|
||||
The :class:`ModelAdmin` class provides customization hooks that allow you to transform
|
||||
an object as it saved, using details from the request. By extracting the current user
|
||||
from the request, and customizing the :meth:`ModelAdmin.save_model` hook, you can update
|
||||
an object to reflect the user that edited it. See :ref:`the documentation on ModelAdmin
|
||||
methods <model-admin-methods>` for an example.
|
||||
|
||||
How do I limit admin access so that objects can only be edited by the users who created them?
|
||||
---------------------------------------------------------------------------------------------
|
||||
|
||||
See the answer to the previous question.
|
||||
The :class:`ModelAdmin` class also provides customization hooks that allow you to control the
|
||||
visibility and editability of objects in the admin. Using the same trick of extracting the
|
||||
user from the request, the :meth:`ModelAdmin.queryset` and :meth:`ModelAdmin.has_change_permission`
|
||||
can be used to control the visibility and editability of objects in the admin.
|
||||
|
||||
My admin-site CSS and images showed up fine using the development server, but they're not displaying when using mod_python.
|
||||
---------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -6,8 +6,8 @@ How to use Django with Apache and mod_python
|
||||
|
||||
.. highlight:: apache
|
||||
|
||||
The `mod_python`_ module for Apache_ can be used to deploy Django to a
|
||||
production server, although it has been mostly superseded by the simpler
|
||||
The `mod_python`_ module for Apache_ can be used to deploy Django to a
|
||||
production server, although it has been mostly superseded by the simpler
|
||||
:ref:`mod_wsgi deployment option <howto-deployment-modwsgi>`.
|
||||
|
||||
mod_python is similar to (and inspired by) `mod_perl`_ : It embeds Python within
|
||||
@@ -378,3 +378,24 @@ as necessary.
|
||||
.. _Expat Causing Apache Crash: http://www.dscpl.com.au/articles/modpython-006.html
|
||||
.. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp
|
||||
.. _Getting mod_python Working: http://www.dscpl.com.au/articles/modpython-001.html
|
||||
|
||||
If you get a UnicodeEncodeError
|
||||
===============================
|
||||
|
||||
If you're taking advantage of the internationalization features of Django (see
|
||||
:ref:`topics-i18n`) and you intend to allow users to upload files, you must
|
||||
ensure that the environment used to start Apache is configured to accept
|
||||
non-ASCII file names. If your environment is not correctly configured, you
|
||||
will trigger ``UnicodeEncodeError`` exceptions when calling functions like
|
||||
``os.path()`` on filenames that contain non-ASCII characters.
|
||||
|
||||
To avoid these problems, the environment used to start Apache should contain
|
||||
settings analogous to the following::
|
||||
|
||||
export LANG='en_US.UTF-8'
|
||||
export LC_ALL='en_US.UTF-8'
|
||||
|
||||
Consult the documentation for your operating system for the appropriate syntax
|
||||
and location to put these configuration items; ``/etc/apache2/envvars`` is a
|
||||
common location on Unix platforms. Once you have added these statements
|
||||
to your environment, restart Apache.
|
||||
|
||||
@@ -704,6 +704,8 @@ objects. Templates can override or extend base admin templates as described in
|
||||
If you don't specify this attribute, a default template shipped with Django
|
||||
that provides the standard appearance is used.
|
||||
|
||||
.. _model-admin-methods:
|
||||
|
||||
``ModelAdmin`` methods
|
||||
----------------------
|
||||
|
||||
@@ -792,7 +794,7 @@ return a subset of objects for this foreign key field based on the user::
|
||||
class MyModelAdmin(admin.ModelAdmin):
|
||||
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||
if db_field.name == "car":
|
||||
kwargs["queryset"] = Car.object.filter(owner=request.user)
|
||||
kwargs["queryset"] = Car.objects.filter(owner=request.user)
|
||||
return db_field.formfield(**kwargs)
|
||||
return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ bytestrings (which shouldn't be too difficult) is the recommended solution.
|
||||
Should you decide to use ``utf8_bin`` collation for some of your tables with
|
||||
MySQLdb 1.2.1p2, you should still use ``utf8_collation_ci_swedish`` (the
|
||||
default) collation for the :class:`django.contrib.sessions.models.Session`
|
||||
table (usually called ``django_session`` and the table
|
||||
table (usually called ``django_session``) and the
|
||||
:class:`django.contrib.admin.models.LogEntry` table (usually called
|
||||
``django_admin_log``). Those are the two standard tables that use
|
||||
:class:`~django.db.model.TextField` internally.
|
||||
|
||||
@@ -101,6 +101,14 @@ You can use any number of values in a ``{% cycle %}`` tag, separated by spaces.
|
||||
Values enclosed in single (``'``) or double quotes (``"``) are treated as
|
||||
string literals, while values without quotes are treated as template variables.
|
||||
|
||||
Note that the variables included in the cycle will not be escaped. This is
|
||||
because template tags do not escape their content. If you want to escape the
|
||||
variables in the cycle, you must do so explicitly::
|
||||
|
||||
{% filter force_escape %}
|
||||
{% cycle var1 var2 var3 %}
|
||||
{% endfilter %}
|
||||
|
||||
For backwards compatibility, the ``{% cycle %}`` tag supports the much inferior
|
||||
old syntax from previous Django versions. You shouldn't use this in any new
|
||||
projects, but for the sake of the people who are still using it, here's what it
|
||||
@@ -160,8 +168,9 @@ Sample usage::
|
||||
firstof
|
||||
~~~~~~~
|
||||
|
||||
Outputs the first variable passed that is not False. Outputs nothing if all the
|
||||
passed variables are False.
|
||||
Outputs the first variable passed that is not False, without escaping.
|
||||
|
||||
Outputs nothing if all the passed variables are False.
|
||||
|
||||
Sample usage::
|
||||
|
||||
@@ -170,11 +179,11 @@ Sample usage::
|
||||
This is equivalent to::
|
||||
|
||||
{% if var1 %}
|
||||
{{ var1 }}
|
||||
{{ var1|safe }}
|
||||
{% else %}{% if var2 %}
|
||||
{{ var2 }}
|
||||
{{ var2|safe }}
|
||||
{% else %}{% if var3 %}
|
||||
{{ var3 }}
|
||||
{{ var3|safe }}
|
||||
{% endif %}{% endif %}{% endif %}
|
||||
|
||||
You can also use a literal string as a fallback value in case all
|
||||
@@ -182,6 +191,14 @@ passed variables are False::
|
||||
|
||||
{% firstof var1 var2 var3 "fallback value" %}
|
||||
|
||||
Note that the variables included in the firstof tag will not be escaped. This
|
||||
is because template tags do not escape their content. If you want to escape
|
||||
the variables in the firstof tag, you must do so explicitly::
|
||||
|
||||
{% filter force_escape %}
|
||||
{% firstof var1 var2 var3 "fallback value" %}
|
||||
{% endfilter %}
|
||||
|
||||
.. templatetag:: for
|
||||
|
||||
for
|
||||
|
||||
@@ -223,7 +223,19 @@ Pluralization
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Use the function ``django.utils.translation.ungettext()`` to specify pluralized
|
||||
messages. Example::
|
||||
messages.
|
||||
|
||||
``ungettext`` takes three arguments: the singular translation string, the plural
|
||||
translation string and the number of objects.
|
||||
|
||||
This function is useful when your need you Django application to be localizable
|
||||
to languages where the number and complexity of `plural forms
|
||||
<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
|
||||
greater than the two forms used in English ('object' for the singular and
|
||||
'objects' for all the cases where ``count`` is different from zero, irrespective
|
||||
of its value.)
|
||||
|
||||
For example::
|
||||
|
||||
from django.utils.translation import ungettext
|
||||
def hello_world(request, count):
|
||||
@@ -232,9 +244,61 @@ messages. Example::
|
||||
}
|
||||
return HttpResponse(page)
|
||||
|
||||
``ungettext`` takes three arguments: the singular translation string, the plural
|
||||
translation string and the number of objects (which is passed to the
|
||||
translation languages as the ``count`` variable).
|
||||
In this example the number of objects is passed to the translation languages as
|
||||
the ``count`` variable.
|
||||
|
||||
Lets see a slightly more complex usage example::
|
||||
|
||||
from django.utils.translation import ungettext
|
||||
|
||||
count = Report.objects.count()
|
||||
if count == 1:
|
||||
name = Report._meta.verbose_name
|
||||
else:
|
||||
name = Report._meta.verbose_name_plural
|
||||
|
||||
text = ungettext(
|
||||
'There is %(count)d %(name)s available.',
|
||||
'There are %(count)d %(name)s available.',
|
||||
count
|
||||
) % {
|
||||
'count': count,
|
||||
'name': name
|
||||
}
|
||||
|
||||
Here we reuse localizable, hopefully already translated literals (contained in
|
||||
the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for
|
||||
other parts of the sentence so all of it is consistently based on the
|
||||
cardinality of the elements at play.
|
||||
|
||||
.. _pluralization-var-notes:
|
||||
|
||||
.. note::
|
||||
|
||||
When using this technique, make sure you use a single name for every
|
||||
extrapolated variable included in the literal. In the example above note how
|
||||
we used the ``name`` Python variable in both translation strings. This
|
||||
example would fail::
|
||||
|
||||
from django.utils.translation import ungettext
|
||||
from myapp.models import Report
|
||||
|
||||
count = Report.objects.count()
|
||||
d = {
|
||||
'count': count,
|
||||
'name': Report._meta.verbose_name
|
||||
'plural_name': Report._meta.verbose_name_plural
|
||||
}
|
||||
text = ungettext(
|
||||
'There is %(count)d %(name)s available.',
|
||||
'There are %(count)d %(plural_name)s available.',
|
||||
count
|
||||
) % d
|
||||
|
||||
You would get a ``a format specification for argument 'name', as in
|
||||
'msgstr[0]', doesn't exist in 'msgid'`` error when running
|
||||
``django-admin.py compilemessages`` or a ``KeyError`` Python exception at
|
||||
runtime.
|
||||
|
||||
In template code
|
||||
----------------
|
||||
@@ -257,6 +321,8 @@ content that will require translation in the future::
|
||||
|
||||
<title>{% trans "myvar" noop %}</title>
|
||||
|
||||
Internally, inline translations use an ``ugettext`` call.
|
||||
|
||||
It's not possible to mix a template variable inside a string within ``{% trans
|
||||
%}``. If your translations require strings with variables (placeholders), use
|
||||
``{% blocktrans %}``::
|
||||
@@ -288,8 +354,11 @@ To pluralize, specify both the singular and plural forms with the
|
||||
There are {{ counter }} {{ name }} objects.
|
||||
{% endblocktrans %}
|
||||
|
||||
Internally, all block and inline translations use the appropriate
|
||||
``ugettext`` / ``ungettext`` call.
|
||||
When you use the pluralization feature and bind additional values to local
|
||||
variables apart from the counter value that selects the translated literal to be
|
||||
used, have in mind that the ``blocktrans`` construct is internally converted
|
||||
to an ``ungettext`` call. This means the same :ref:`notes regarding ungettext
|
||||
variables <pluralization-var-notes>` apply.
|
||||
|
||||
Each ``RequestContext`` has access to three translation-specific variables:
|
||||
|
||||
|
||||
@@ -479,7 +479,7 @@ arguments at time of construction:
|
||||
Once you have a ``Client`` instance, you can call any of the following
|
||||
methods:
|
||||
|
||||
.. method:: Client.get(path, data={}, follow=False)
|
||||
.. method:: Client.get(path, data={}, follow=False, **extra)
|
||||
|
||||
|
||||
Makes a GET request on the provided ``path`` and returns a ``Response``
|
||||
@@ -495,6 +495,17 @@ arguments at time of construction:
|
||||
|
||||
/customers/details/?name=fred&age=7
|
||||
|
||||
The ``extra`` keyword arguments parameter can be used to specify
|
||||
headers to be sent in the request. For example::
|
||||
|
||||
>>> c = Client()
|
||||
>>> c.get('/customers/details/', {'name': 'fred', 'age': 7},
|
||||
... HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
|
||||
...will send the HTTP header ``HTTP_X_REQUESTED_WITH`` to the
|
||||
details view, which is a good way to test code paths that use the
|
||||
:meth:`django.http.HttpRequest.is_ajax()` method.
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
If you already have the GET arguments in URL-encoded form, you can
|
||||
@@ -518,7 +529,7 @@ arguments at time of construction:
|
||||
>>> response.redirect_chain
|
||||
[(u'http://testserver/next/', 302), (u'http://testserver/final/', 302)]
|
||||
|
||||
.. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, follow=False)
|
||||
.. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra)
|
||||
|
||||
Makes a POST request on the provided ``path`` and returns a
|
||||
``Response`` object, which is documented below.
|
||||
@@ -569,6 +580,8 @@ arguments at time of construction:
|
||||
Note that you should manually close the file after it has been provided
|
||||
to ``post()``.
|
||||
|
||||
The ``extra`` argument acts the same as for :meth:`Client.get`.
|
||||
|
||||
.. versionchanged:: 1.1
|
||||
|
||||
If the URL you request with a POST contains encoded parameters, these
|
||||
@@ -585,7 +598,7 @@ arguments at time of construction:
|
||||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
.. method:: Client.head(path, data={}, follow=False)
|
||||
.. method:: Client.head(path, data={}, follow=False, **extra)
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@@ -597,7 +610,7 @@ arguments at time of construction:
|
||||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
.. method:: Client.options(path, data={}, follow=False)
|
||||
.. method:: Client.options(path, data={}, follow=False, **extra)
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@@ -608,7 +621,9 @@ arguments at time of construction:
|
||||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
.. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT, follow=False)
|
||||
The ``extra`` argument acts the same as for :meth:`Client.get`.
|
||||
|
||||
.. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra)
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@@ -620,7 +635,7 @@ arguments at time of construction:
|
||||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
.. method:: Client.delete(path, follow=False)
|
||||
.. method:: Client.delete(path, follow=False, **extra)
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
@@ -631,6 +646,8 @@ arguments at time of construction:
|
||||
and a ``redirect_chain`` attribute will be set in the response object
|
||||
containing tuples of the intermediate urls and status codes.
|
||||
|
||||
The ``extra`` argument acts the same as for :meth:`Client.get`.
|
||||
|
||||
.. method:: Client.login(**credentials)
|
||||
|
||||
.. versionadded:: 1.0
|
||||
|
||||
Reference in New Issue
Block a user