mirror of
https://github.com/django/django.git
synced 2025-07-04 01:39:20 +00:00
unicode: Merged from trunk up to [5380].
git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5381 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
fa1a0532d3
commit
ddae2ecfe4
1
AUTHORS
1
AUTHORS
@ -232,6 +232,7 @@ answer newbie questions, and generally made Django that much better:
|
||||
viestards.lists@gmail.com
|
||||
Milton Waddams
|
||||
wam-djangobug@wamber.net
|
||||
wangchun <yaohua2000@gmail.com>
|
||||
Dan Watson <http://theidioteque.net/>
|
||||
Chris Wesseling <Chris.Wesseling@cwi.nl>
|
||||
charly.wilhelm@gmail.com
|
||||
|
@ -147,6 +147,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
|
||||
'django.core.context_processors.auth',
|
||||
'django.core.context_processors.debug',
|
||||
'django.core.context_processors.i18n',
|
||||
'django.core.context_processors.media',
|
||||
# 'django.core.context_processors.request',
|
||||
)
|
||||
|
||||
@ -334,6 +335,13 @@ TEST_RUNNER = 'django.test.simple.run_tests'
|
||||
# If None, a name of 'test_' + DATABASE_NAME will be assumed
|
||||
TEST_DATABASE_NAME = None
|
||||
|
||||
# Strings used to set the character set and collation order for the test
|
||||
# database. These values are passed literally to the server, so they are
|
||||
# backend-dependent. If None, no special settings are sent (system defaults are
|
||||
# used).
|
||||
TEST_DATABASE_CHARSET = None
|
||||
TEST_DATABASE_COLLATION = None
|
||||
|
||||
############
|
||||
# FIXTURES #
|
||||
############
|
||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -113,8 +113,8 @@ msgstr "Demà"
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:34
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:72
|
||||
msgid "Show"
|
||||
msgstr ""
|
||||
msgstr "Mostrar"
|
||||
|
||||
#: contrib/admin/media/js/admin/CollapsedFieldsets.js:63
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
msgstr "Ocultar"
|
||||
|
Binary file not shown.
@ -481,8 +481,8 @@ msgid ""
|
||||
"database tables have been created, and make sure the database is readable by "
|
||||
"the appropriate user."
|
||||
msgstr ""
|
||||
"Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, das "
|
||||
"die richtigen Datenbanktabellen angelegt wurden und bitte sicherstellen, das "
|
||||
"Etwas stimmt nicht mit der Datenbankkonfiguration. Bitte sicherstellen, dass "
|
||||
"die richtigen Datenbanktabellen angelegt wurden und "
|
||||
"die Datenbank vom verwendeten Datenbankbenutzer auch lesbar ist."
|
||||
|
||||
#: contrib/admin/templates/admin/login.html:17
|
||||
|
@ -1,4 +1,5 @@
|
||||
from django.core.urlresolvers import RegexURLPattern, RegexURLResolver
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
__all__ = ['handler404', 'handler500', 'include', 'patterns', 'url']
|
||||
|
||||
@ -22,7 +23,10 @@ def url(regex, view, kwargs=None, name=None, prefix=''):
|
||||
# For include(...) processing.
|
||||
return RegexURLResolver(regex, view[0], kwargs)
|
||||
else:
|
||||
if prefix and isinstance(view, basestring):
|
||||
if isinstance(view, basestring):
|
||||
if not view:
|
||||
raise ImproperlyConfigured('Empty URL pattern view name not permitted (for pattern %r)' % regex)
|
||||
if prefix:
|
||||
view = prefix + '.' + view
|
||||
return RegexURLPattern(regex, view, kwargs, name)
|
||||
|
||||
|
@ -42,6 +42,13 @@ def i18n(request):
|
||||
|
||||
return context_extras
|
||||
|
||||
def media(request):
|
||||
"""
|
||||
Adds media-related context variables to the context.
|
||||
|
||||
"""
|
||||
return {'MEDIA_URL': settings.MEDIA_URL}
|
||||
|
||||
def request(request):
|
||||
return {'request': request}
|
||||
|
||||
|
@ -1138,7 +1138,7 @@ def validate(outfile=sys.stdout, silent_success=False):
|
||||
return
|
||||
outfile.write('%s error%s found.\n' % (num_errors, num_errors != 1 and 's' or ''))
|
||||
except ImproperlyConfigured:
|
||||
outfile.write("Skipping validation because things aren't configured properly.")
|
||||
outfile.write("Skipping validation because things aren't configured properly.\n")
|
||||
validate.args = ''
|
||||
|
||||
def _check_for_validation_errors(app=None):
|
||||
|
@ -38,6 +38,11 @@ class Serializer(base.Serializer):
|
||||
def handle_fk_field(self, obj, field):
|
||||
related = getattr(obj, field.name)
|
||||
if related is not None:
|
||||
if field.rel.field_name == related._meta.pk.name:
|
||||
# Related to remote object via primary key
|
||||
related = related._get_pk_val()
|
||||
else:
|
||||
# Related to remote object via other field
|
||||
related = getattr(related, field.rel.field_name)
|
||||
self._current[field.name] = related
|
||||
|
||||
|
@ -83,7 +83,13 @@ class Serializer(base.Serializer):
|
||||
self._start_relational_field(field)
|
||||
related = getattr(obj, field.name)
|
||||
if related is not None:
|
||||
self.xml.characters(smart_unicode(getattr(related, field.rel.field_name)))
|
||||
if field.rel.field_name == related._meta.pk.name:
|
||||
# Related to remote object via primary key
|
||||
related = related._get_pk_val()
|
||||
else:
|
||||
# Related to remote object via other field
|
||||
related = getattr(related, field.rel.field_name)
|
||||
self.xml.characters(smart_unicode(related))
|
||||
else:
|
||||
self.xml.addQuickElement("None")
|
||||
self.xml.endElement("field")
|
||||
|
@ -63,7 +63,7 @@ class BaseForm(StrAndUnicode):
|
||||
self.auto_id = auto_id
|
||||
self.prefix = prefix
|
||||
self.initial = initial or {}
|
||||
self.__errors = None # Stores the errors after clean() has been called.
|
||||
self._errors = None # Stores the errors after clean() has been called.
|
||||
|
||||
# The base_fields class attribute is the *class-wide* definition of
|
||||
# fields. Because a particular *instance* of the class might want to
|
||||
@ -87,12 +87,12 @@ class BaseForm(StrAndUnicode):
|
||||
raise KeyError('Key %r not found in Form' % name)
|
||||
return BoundField(self, field, name)
|
||||
|
||||
def _errors(self):
|
||||
def _get_errors(self):
|
||||
"Returns an ErrorDict for self.data"
|
||||
if self.__errors is None:
|
||||
if self._errors is None:
|
||||
self.full_clean()
|
||||
return self.__errors
|
||||
errors = property(_errors)
|
||||
return self._errors
|
||||
errors = property(_get_errors)
|
||||
|
||||
def is_valid(self):
|
||||
"""
|
||||
@ -171,11 +171,11 @@ class BaseForm(StrAndUnicode):
|
||||
|
||||
def full_clean(self):
|
||||
"""
|
||||
Cleans all of self.data and populates self.__errors and self.cleaned_data.
|
||||
Cleans all of self.data and populates self._errors and
|
||||
self.cleaned_data.
|
||||
"""
|
||||
errors = ErrorDict()
|
||||
self._errors = ErrorDict()
|
||||
if not self.is_bound: # Stop further processing.
|
||||
self.__errors = errors
|
||||
return
|
||||
self.cleaned_data = {}
|
||||
for name, field in self.fields.items():
|
||||
@ -190,14 +190,15 @@ class BaseForm(StrAndUnicode):
|
||||
value = getattr(self, 'clean_%s' % name)()
|
||||
self.cleaned_data[name] = value
|
||||
except ValidationError, e:
|
||||
errors[name] = e.messages
|
||||
self._errors[name] = e.messages
|
||||
if name in self.cleaned_data:
|
||||
del self.cleaned_data[name]
|
||||
try:
|
||||
self.cleaned_data = self.clean()
|
||||
except ValidationError, e:
|
||||
errors[NON_FIELD_ERRORS] = e.messages
|
||||
if errors:
|
||||
self._errors[NON_FIELD_ERRORS] = e.messages
|
||||
if self._errors:
|
||||
delattr(self, 'cleaned_data')
|
||||
self.__errors = errors
|
||||
|
||||
def clean(self):
|
||||
"""
|
||||
|
@ -73,6 +73,20 @@ def _set_autocommit(connection):
|
||||
elif hasattr(connection.connection, "set_isolation_level"):
|
||||
connection.connection.set_isolation_level(0)
|
||||
|
||||
def get_mysql_create_suffix():
|
||||
suffix = []
|
||||
if settings.TEST_DATABASE_CHARSET:
|
||||
suffix.append('CHARACTER SET %s' % settings.TEST_DATABASE_CHARSET)
|
||||
if settings.TEST_DATABASE_COLLATION:
|
||||
suffix.append('COLLATE %s' % settings.TEST_DATABASE_COLLATION)
|
||||
return ' '.join(suffix)
|
||||
|
||||
def get_postgresql_create_suffix():
|
||||
assert settings.TEST_DATABASE_COLLATION is None, "PostgreSQL does not support collation setting at database creation time."
|
||||
if settings.TEST_DATABASE_CHARSET:
|
||||
return "WITH ENCODING '%s'" % settings.TEST_DATABASE_CHARSET
|
||||
return ''
|
||||
|
||||
def create_test_db(verbosity=1, autoclobber=False):
|
||||
if verbosity >= 1:
|
||||
print "Creating test database..."
|
||||
@ -81,6 +95,12 @@ def create_test_db(verbosity=1, autoclobber=False):
|
||||
if settings.DATABASE_ENGINE == "sqlite3":
|
||||
TEST_DATABASE_NAME = ":memory:"
|
||||
else:
|
||||
suffix = {
|
||||
'postgresql': get_postgresql_create_suffix,
|
||||
'postgresql_psycopg2': get_postgresql_create_suffix,
|
||||
'mysql': get_mysql_create_suffix,
|
||||
'mysql_old': get_mysql_create_suffix,
|
||||
}.get(settings.DATABASE_ENGINE, lambda: '')()
|
||||
if settings.TEST_DATABASE_NAME:
|
||||
TEST_DATABASE_NAME = settings.TEST_DATABASE_NAME
|
||||
else:
|
||||
@ -92,7 +112,7 @@ def create_test_db(verbosity=1, autoclobber=False):
|
||||
cursor = connection.cursor()
|
||||
_set_autocommit(connection)
|
||||
try:
|
||||
cursor.execute("CREATE DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))
|
||||
cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix))
|
||||
except Exception, e:
|
||||
sys.stderr.write("Got an error creating the test database: %s\n" % e)
|
||||
if not autoclobber:
|
||||
@ -104,7 +124,7 @@ def create_test_db(verbosity=1, autoclobber=False):
|
||||
cursor.execute("DROP DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))
|
||||
if verbosity >= 1:
|
||||
print "Creating test database..."
|
||||
cursor.execute("CREATE DATABASE %s" % backend.quote_name(TEST_DATABASE_NAME))
|
||||
cursor.execute("CREATE DATABASE %s %s" % (backend.quote_name(TEST_DATABASE_NAME), suffix))
|
||||
except Exception, e:
|
||||
sys.stderr.write("Got an error recreating the test database: %s\n" % e)
|
||||
sys.exit(2)
|
||||
|
@ -168,6 +168,8 @@ class Rss201rev2Feed(RssFeed):
|
||||
(item['author_email'], item['author_name']))
|
||||
elif item["author_email"]:
|
||||
handler.addQuickElement(u"author", item["author_email"])
|
||||
elif item["author_name"]:
|
||||
handler.addQuickElement(u"dc:creator", item["author_name"], {"xmlns:dc": u"http://purl.org/dc/elements/1.1/"})
|
||||
|
||||
if item['pubdate'] is not None:
|
||||
handler.addQuickElement(u"pubDate", rfc2822_date(item['pubdate']).decode('ascii'))
|
||||
|
@ -1748,7 +1748,8 @@ Shortcuts
|
||||
|
||||
As you develop views, you will discover a number of common idioms in the
|
||||
way you use the database API. Django encodes some of these idioms as
|
||||
shortcuts that can be used to simplify the process of writing views.
|
||||
shortcuts that can be used to simplify the process of writing views. These
|
||||
functions are in the ``django.shortcuts`` module.
|
||||
|
||||
get_object_or_404()
|
||||
-------------------
|
||||
|
@ -97,7 +97,9 @@ This file should also be located in your ``site-packages`` directory.
|
||||
|
||||
* If you're using Windows: ``C:\Python2.X\lib\site-packages``
|
||||
|
||||
* If you're using MacOSX: ``/Library/Python2.X/site-packages``
|
||||
* If you're using MacOSX: ``/Library/Python2.X/site-packages`` or
|
||||
``/Library/Frameworks/Python.framework/Versions/2.X/lib/python2.X/site-packages/``
|
||||
(in later releases).
|
||||
|
||||
Install the Django code
|
||||
=======================
|
||||
|
@ -269,6 +269,13 @@ For example, say your ``MEDIA_ROOT`` is set to ``'/home/media'``, and
|
||||
upload a file on Jan. 15, 2007, it will be saved in the directory
|
||||
``/home/media/photos/2007/01/15``.
|
||||
|
||||
If you want to retrieve the upload file's on-disk filename, or a URL that
|
||||
refers to that file, or the file's size, you can use the
|
||||
``get_FOO_filename()``, ``get_FOO_url()`` and ``get_FOO_size()`` methods.
|
||||
They are all documented here__.
|
||||
|
||||
__ ../db-api/#get-foo-filename
|
||||
|
||||
Note that whenever you deal with uploaded files, you should pay close attention
|
||||
to where you're uploading them and what type of files they are, to avoid
|
||||
security holes. *Validate all uploaded files* so that you're sure the files are
|
||||
@ -338,9 +345,14 @@ image. Has two extra optional arguments, ``height_field`` and
|
||||
``width_field``, which, if set, will be auto-populated with the height and
|
||||
width of the image each time a model instance is saved.
|
||||
|
||||
In addition to the special ``get_FOO_*`` methods that are available for
|
||||
``FileField``, an ``ImageField`` also has ``get_FOO_height()`` and
|
||||
``get_FOO_width()`` methods. These are documented elsewhere_.
|
||||
|
||||
Requires the `Python Imaging Library`_.
|
||||
|
||||
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
|
||||
.. _elsewhere: ../db-api/#get-foo-height-and-get-foo-width
|
||||
|
||||
``IntegerField``
|
||||
~~~~~~~~~~~~~~~~
|
||||
@ -463,8 +475,10 @@ If ``True``, Django will store empty values as ``NULL`` in the database.
|
||||
Default is ``False``.
|
||||
|
||||
Note that empty string values will always get stored as empty strings, not
|
||||
as ``NULL`` -- so use ``null=True`` for non-string fields such as integers,
|
||||
booleans and dates.
|
||||
as ``NULL``. Only use ``null=True`` for non-string fields such as integers,
|
||||
booleans and dates. For both types of fields, you will also need to set
|
||||
``blank=True`` if you wish to permit empty values in forms, as the ``null``
|
||||
parameter only affects database storage (see blank_, below).
|
||||
|
||||
Avoid using ``null`` on string-based fields such as ``CharField`` and
|
||||
``TextField`` unless you have an excellent reason. If a string-based field
|
||||
|
@ -211,6 +211,41 @@ Here are two recommended approaches:
|
||||
2. Or, copy the admin media files so that they live within your Apache
|
||||
document root.
|
||||
|
||||
Using eggs with mod_python
|
||||
==========================
|
||||
|
||||
If you installed Django from a Python egg_ or are using eggs in your Django
|
||||
project, some extra configuration is required. Create an extra file in your
|
||||
project (or somewhere else) that contains something like the following::
|
||||
|
||||
import os
|
||||
os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
|
||||
|
||||
Here, ``/some/directory`` is a directory that the Apache webserver process can
|
||||
write to. It will be used as the location for any unpacking of code the eggs
|
||||
need to do.
|
||||
|
||||
Then you have to tell mod_python to import this file before doing anything
|
||||
else. This is done using the PythonImport_ directive to mod_python. You need
|
||||
to ensure that you have specified the ``PythonInterpreter`` directive to
|
||||
mod_python as described above__ (you need to do this even if you aren't
|
||||
serving multiple installations in this case). Then add the ``PythonImport``
|
||||
line inside the ``Location`` or ``VirtualHost`` section. For example::
|
||||
|
||||
PythonInterpreter my_django
|
||||
PythonImport /path/to/my/project/file.py my_django
|
||||
|
||||
Note that you can use an absolute path here (or a normal dotted import path),
|
||||
as described in the `mod_python manual`_. We use an absolute path in the
|
||||
above example because if any Python path modifications are required to access
|
||||
your project, they will not have been done at the time the ``PythonImport``
|
||||
line is processed.
|
||||
|
||||
.. _Egg: http://peak.telecommunity.com/DevCenter/PythonEggs
|
||||
.. _PythonImport: http://www.modpython.org/live/current/doc-html/dir-other-pimp.html
|
||||
.. _mod_python manual: PythonImport_
|
||||
__ `Multiple Django installations on the same Apache`_
|
||||
|
||||
Error handling
|
||||
==============
|
||||
|
||||
@ -256,3 +291,5 @@ 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
|
||||
|
||||
|
||||
|
@ -686,13 +686,13 @@ For example::
|
||||
|
||||
<form method="post">
|
||||
<ul class="myformclass">
|
||||
<li>{{ form.sender.label }} {{ form.sender.label }}</li>
|
||||
<li>{{ form.sender.label }} {{ form.sender }}</li>
|
||||
<li class="helptext">{{ form.sender.help_text }}</li>
|
||||
{% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</dd>{% endif %}
|
||||
{% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</ul>{% endif %}
|
||||
|
||||
<li>{{ form.subject.label }} {{ form.subject.label }}</li>
|
||||
<li>{{ form.subject.label }} {{ form.subject }}</li>
|
||||
<li class="helptext">{{ form.subject.help_text }}</li>
|
||||
{% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</dd>{% endif %}
|
||||
{% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</ul>{% endif %}
|
||||
|
||||
...
|
||||
</ul>
|
||||
|
@ -264,6 +264,11 @@ MySQL will connect via a Unix socket to the specified socket. For example::
|
||||
If you're using MySQL and this value *doesn't* start with a forward slash, then
|
||||
this value is assumed to be the host.
|
||||
|
||||
If you're using PostgreSQL, an empty string means to use a Unix domain socket
|
||||
for the connection, rather than a network connection to localhost. If you
|
||||
explictly need to use a TCP/IP connection on the local machine with
|
||||
PostgreSQL, specify ``localhost`` here.
|
||||
|
||||
DATABASE_NAME
|
||||
-------------
|
||||
|
||||
@ -781,7 +786,8 @@ Default::
|
||||
|
||||
("django.core.context_processors.auth",
|
||||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n")
|
||||
"django.core.context_processors.i18n",
|
||||
"django.core.context_processors.media")
|
||||
|
||||
A tuple of callables that are used to populate the context in ``RequestContext``.
|
||||
These callables take a request object as their argument and return a dictionary
|
||||
@ -830,15 +836,36 @@ misspelled) variables. See `How invalid variables are handled`_.
|
||||
|
||||
.. _How invalid variables are handled: ../templates_python/#how-invalid-variables-are-handled
|
||||
|
||||
TEST_RUNNER
|
||||
-----------
|
||||
TEST_DATABASE_CHARSET
|
||||
---------------------
|
||||
|
||||
Default: ``'django.test.simple.run_tests'``
|
||||
**New in Django development version**
|
||||
|
||||
The name of the method to use for starting the test suite. See
|
||||
`Testing Django Applications`_.
|
||||
Default: ``None``
|
||||
|
||||
.. _Testing Django Applications: ../testing/
|
||||
The character set encoding used to create the test database. The value of this
|
||||
string is passed directly through to the database, so its format is
|
||||
backend-specific.
|
||||
|
||||
Supported for the PostgreSQL_ (``postgresql``, ``postgresql_psycopg2``) and MySQL_ (``mysql``, ``mysql_old``) backends.
|
||||
|
||||
.. _PostgreSQL: http://www.postgresql.org/docs/8.2/static/multibyte.html
|
||||
.. _MySQL: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
|
||||
|
||||
TEST_DATABASE_COLLATION
|
||||
------------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Default: ``None``
|
||||
|
||||
The collation order to use when creating the test database. This value is
|
||||
passed directly to the backend, so it's format is backend-specific.
|
||||
|
||||
Only supported for ``mysql`` and ``mysql_old`` backends (see `section 10.3.2`_
|
||||
of the MySQL manual for details).
|
||||
|
||||
.. _section 10.3.2: http://www.mysql.org/doc/refman/5.0/en/charset-database.html
|
||||
|
||||
TEST_DATABASE_NAME
|
||||
------------------
|
||||
@ -850,6 +877,16 @@ The name of database to use when running the test suite. If a value of
|
||||
|
||||
.. _Testing Django Applications: ../testing/
|
||||
|
||||
TEST_RUNNER
|
||||
-----------
|
||||
|
||||
Default: ``'django.test.simple.run_tests'``
|
||||
|
||||
The name of the method to use for starting the test suite. See
|
||||
`Testing Django Applications`_.
|
||||
|
||||
.. _Testing Django Applications: ../testing/
|
||||
|
||||
TIME_FORMAT
|
||||
-----------
|
||||
|
||||
|
@ -112,7 +112,7 @@ know how to write Python code.
|
||||
Comments
|
||||
========
|
||||
|
||||
To comment-out part of a template, use the comment syntax: ``{# #}``.
|
||||
To comment-out part of a line in a template, use the comment syntax: ``{# #}``.
|
||||
|
||||
For example, this template would render as ``'hello'``::
|
||||
|
||||
@ -122,6 +122,12 @@ A comment can contain any template code, invalid or not. For example::
|
||||
|
||||
{# {% if foo %}bar{% else %} #}
|
||||
|
||||
This syntax can only be used for single-line comments (no newlines are
|
||||
permitted between the ``{#`` and ``#}`` delimiters). If you need to comment
|
||||
out a multiline portion of the template, see the ``comment`` tag, below__.
|
||||
|
||||
__ comment_
|
||||
|
||||
Template inheritance
|
||||
====================
|
||||
|
||||
@ -843,10 +849,11 @@ The first argument is a path to a view function in the format
|
||||
should be comma-separated values that will be used as positional and keyword
|
||||
arguments in the URL. All arguments required by the URLconf should be present.
|
||||
|
||||
For example, suppose you have a view, ``app_name.client``, whose URLconf takes
|
||||
a client ID. The URLconf line might look like this::
|
||||
For example, suppose you have a view, ``app_views.client``, whose URLconf
|
||||
takes a client ID (here, ``client()`` is a method inside the views file
|
||||
``app_views.py``). The URLconf line might look like this::
|
||||
|
||||
('^client/(\d+)/$', 'app_name.client')
|
||||
('^client/(\d+)/$', 'app_views.client')
|
||||
|
||||
If this app's URLconf is included into the project's URLconf under a path
|
||||
such as this::
|
||||
@ -855,7 +862,7 @@ such as this::
|
||||
|
||||
...then, in a template, you can create a link to this view like this::
|
||||
|
||||
{% url app_name.client client.id %}
|
||||
{% url app_views.client client.id %}
|
||||
|
||||
The template tag will output the string ``/clients/client/123/``.
|
||||
|
||||
|
@ -294,7 +294,8 @@ return a dictionary of items to be merged into the context. By default,
|
||||
|
||||
("django.core.context_processors.auth",
|
||||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n")
|
||||
"django.core.context_processors.i18n",
|
||||
"django.core.context_processors.media")
|
||||
|
||||
Each processor is applied in order. That means, if one processor adds a
|
||||
variable to the context and a second processor adds a variable with the same
|
||||
@ -390,6 +391,15 @@ See the `internationalization docs`_ for more.
|
||||
.. _LANGUAGE_CODE setting: ../settings/#language-code
|
||||
.. _internationalization docs: ../i18n/
|
||||
|
||||
django.core.context_processors.media
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processors, every
|
||||
``RequestContext`` will contain ``MEDIA_URL``, providing the
|
||||
value of the `MEDIA_URL setting`_.
|
||||
|
||||
.. _MEDIA_URL setting: ../settings/#media-url
|
||||
|
||||
django.core.context_processors.request
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -4,7 +4,7 @@ Testing Django applications
|
||||
|
||||
Automated testing is an extremely useful bug-killing tool for the modern
|
||||
Web developer. You can use a collection of tests -- a **test suite** -- to
|
||||
to solve, or avoid, a number of problems:
|
||||
solve, or avoid, a number of problems:
|
||||
|
||||
* When you're writing new code, you can use tests to validate your code
|
||||
works as expected.
|
||||
@ -571,6 +571,16 @@ database settings will the same as they would be for the project normally.
|
||||
If you wish to use a name other than the default for the test database,
|
||||
you can use the ``TEST_DATABASE_NAME`` setting to provide a name.
|
||||
|
||||
|
||||
**New in Django development version:** If you wish to have fine-grained
|
||||
control over the character set encoding used in your database, you can control
|
||||
this with the ``TEST_DATABASE_CHARSET`` setting. For MySQL users, you can also
|
||||
control the particular collation used by the test database with the
|
||||
``TEST_DATABASE_COLLATION`` setting. Refer to the settings_ documentation for
|
||||
details of these advanced settings.
|
||||
|
||||
.. _settings: ../settings.txt
|
||||
|
||||
The test database is created by the user in the ``DATABASE_USER`` setting.
|
||||
This user needs to have sufficient privileges to create a new database on the
|
||||
system.
|
||||
|
@ -60,9 +60,10 @@ arguments from the dictionary (an optional third item in the tuple).
|
||||
For more on ``HTTPRequest`` objects, see the `request and response documentation`_.
|
||||
For more details on URLconfs, see the `URLconf documentation`_.
|
||||
|
||||
When you ran ``python manage.py startproject mysite`` at the beginning of
|
||||
When you ran ``python django-admin.py startproject mysite`` at the beginning of
|
||||
Tutorial 1, it created a default URLconf in ``mysite/urls.py``. It also
|
||||
automatically set your ``ROOT_URLCONF`` setting to point at that file::
|
||||
automatically set your ``ROOT_URLCONF`` setting (in ``settings.py``) to point
|
||||
at that file::
|
||||
|
||||
ROOT_URLCONF = 'mysite.urls'
|
||||
|
||||
|
@ -48,6 +48,7 @@ So let's create a ``vote()`` function in ``mysite/polls/views.py``::
|
||||
|
||||
from django.shortcuts import get_object_or_404, render_to_response
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.core.urlresolvers import reverse
|
||||
from mysite.polls.models import Choice, Poll
|
||||
# ...
|
||||
def vote(request, poll_id):
|
||||
@ -66,7 +67,7 @@ So let's create a ``vote()`` function in ``mysite/polls/views.py``::
|
||||
# Always return an HttpResponseRedirect after successfully dealing
|
||||
# with POST data. This prevents data from being posted twice if a
|
||||
# user hits the Back button.
|
||||
return HttpResponseRedirect('/polls/%s/results/' % p.id)
|
||||
return HttpResponseRedirect(reverse('results', args=(p.id,)))
|
||||
|
||||
This code includes a few things we haven't covered yet in this tutorial:
|
||||
|
||||
@ -86,13 +87,28 @@ This code includes a few things we haven't covered yet in this tutorial:
|
||||
* After incrementing the choice count, the code returns an
|
||||
``HttpResponseRedirect`` rather than a normal ``HttpResponse``.
|
||||
``HttpResponseRedirect`` takes a single argument: the URL to which the
|
||||
user will be redirected. You should leave off the "http://" and domain
|
||||
name if you can. That helps your app become portable across domains.
|
||||
user will be redirected (see the following point for how we construct
|
||||
the URL in this case).
|
||||
|
||||
As the Python comment above points out, you should always return an
|
||||
``HttpResponseRedirect`` after successfully dealing with POST data. This
|
||||
tip isn't specific to Django; it's just good Web development practice.
|
||||
|
||||
* We are using the ``reverse()`` function in the ``HttpResponseRedirect``
|
||||
constructor in this example. This function helps avoid having to
|
||||
hardcode a URL in the view function. It is given the name of the view
|
||||
that we want to pass control to and the variable portion of the URL
|
||||
pattern that points to that view. In this case, using the URLConf we set
|
||||
up in Tutorial 3, this ``reverse()`` call will return a string like ::
|
||||
|
||||
'/polls/3/results/'
|
||||
|
||||
... where the ``3`` is the value of ``p.id``. This redirected URL will
|
||||
then call the ``'results'`` view to display the final page.
|
||||
|
||||
For more information about ``reverse()``, see the `URL dispatcher`_
|
||||
documentation.
|
||||
|
||||
As mentioned in Tutorial 3, ``request`` is a ``HTTPRequest`` object. For more
|
||||
on ``HTTPRequest`` objects, see the `request and response documentation`_.
|
||||
|
||||
@ -121,6 +137,7 @@ results page that gets updated each time you vote. If you submit the form
|
||||
without having chosen a choice, you should see the error message.
|
||||
|
||||
.. _request and response documentation: ../request_response/
|
||||
.. _URL dispatcher: ../url_dispatch#reverse
|
||||
|
||||
Use generic views: Less code is better
|
||||
======================================
|
||||
@ -256,4 +273,8 @@ installments:
|
||||
* Advanced admin features: Permissions
|
||||
* Advanced admin features: Custom JavaScript
|
||||
|
||||
In the meantime, you can read through the rest of the `Django documentation`_
|
||||
and start writing your own applications.
|
||||
|
||||
.. _Tutorial 3: ../tutorial03/
|
||||
.. _Django documentation: http://www.djangoproject.com/documentation/
|
||||
|
@ -551,3 +551,37 @@ not restricted to valid Python names.
|
||||
Putting a prefix on your URL names, perhaps derived from the application
|
||||
name, will decrease the chances of collision. We recommend something like
|
||||
``myapp-comment`` instead of ``comment``.
|
||||
|
||||
Utility methods
|
||||
===============
|
||||
|
||||
reverse()
|
||||
---------
|
||||
|
||||
If you need to use something similar to the ``{% url %}`` template tag in your
|
||||
code, Django provides the ``django.core.urlresolvers.reverse()``. The
|
||||
``reverse()`` function has the following signature::
|
||||
|
||||
reverse(viewname, urlconf=None, args=None, kwargs=None)
|
||||
|
||||
The view name is either the function name or the `URL pattern name`_.
|
||||
Normally you will not need to worry about the ``urlconf`` parameter and will
|
||||
only pass in the positional and keyword arguments to use in the url matching.
|
||||
For example::
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
def myview(request):
|
||||
return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
|
||||
|
||||
.. _URL pattern name: `Naming URL patterns`_
|
||||
|
||||
permalink()
|
||||
-----------
|
||||
|
||||
The ``permalink()`` decorator is useful for writing short methods that return
|
||||
a full URL path. For example, a model's ``get_absolute_url()`` method. Refer
|
||||
to the `model API documentation`_ for more information about ``permalink()``.
|
||||
|
||||
.. _model API documentation: ../model-api/#the-permalink-decorator
|
||||
|
||||
|
@ -3655,6 +3655,25 @@ u' id="header"'
|
||||
u' class="news" title="Read this"'
|
||||
>>> flatatt({})
|
||||
u''
|
||||
|
||||
####################################
|
||||
# Test accessing errors in clean() #
|
||||
####################################
|
||||
|
||||
>>> class UserForm(Form):
|
||||
... username = CharField(max_length=10)
|
||||
... password = CharField(widget=PasswordInput)
|
||||
... def clean(self):
|
||||
... data = self.cleaned_data
|
||||
... if not self.errors:
|
||||
... data['username'] = data['username'].lower()
|
||||
... return data
|
||||
|
||||
>>> f = UserForm({'username': 'SirRobin', 'password': 'blue'})
|
||||
>>> f.is_valid()
|
||||
True
|
||||
>>> f.cleaned_data['username']
|
||||
u'sirrobin'
|
||||
"""
|
||||
|
||||
__test__ = {
|
||||
|
@ -129,6 +129,9 @@ class M2MSelfData(models.Model):
|
||||
class FKDataToField(models.Model):
|
||||
data = models.ForeignKey(UniqueAnchor, null=True, to_field='data')
|
||||
|
||||
class FKDataToO2O(models.Model):
|
||||
data = models.ForeignKey(O2OData, null=True)
|
||||
|
||||
# The following test classes are for validating the
|
||||
# deserialization of objects that use a user-defined
|
||||
# field as the primary key.
|
||||
|
@ -200,6 +200,8 @@ The end."""),
|
||||
(fk_obj, 451, FKDataToField, "UAnchor 2"),
|
||||
(fk_obj, 452, FKDataToField, None),
|
||||
|
||||
(fk_obj, 460, FKDataToO2O, 300),
|
||||
|
||||
(data_obj, 500, Anchor, "Anchor 3"),
|
||||
(data_obj, 501, Anchor, "Anchor 4"),
|
||||
(data_obj, 502, UniqueAnchor, "UAnchor 2"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user