1
0
mirror of https://github.com/django/django.git synced 2025-07-07 11:19:12 +00:00

Merged to trunk at r11079

git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11083 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Honza Král 2009-06-21 19:24:30 +00:00
parent 98e6ab0afc
commit 5ea9b72585
19 changed files with 91 additions and 67 deletions

View File

@ -226,6 +226,7 @@ answer newbie questions, and generally made Django that much better:
Ian G. Kelly <ian.g.kelly@gmail.com>
Ryan Kelly <ryan@rfk.id.au>
Thomas Kerpe <thomas@kerpe.net>
Wiley Kestner <wiley.kestner@gmail.com>
Ossama M. Khayat <okhayat@yahoo.com>
Ben Khoo <khoobks@westnet.com.au>
Garth Kidd <http://www.deadlybloodyserious.com/>

View File

@ -3,6 +3,7 @@ from django.template import resolve_variable
from django.core.cache import cache
from django.utils.encoding import force_unicode
from django.utils.http import urlquote
from django.utils.hashcompat import md5_constructor
register = Library()
@ -23,7 +24,8 @@ class CacheNode(Node):
except (ValueError, TypeError):
raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
# Build a unicode key for this fragment and all vary-on's.
cache_key = u':'.join([self.fragment_name] + [urlquote(resolve_variable(var, context)) for var in self.vary_on])
args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
value = cache.get(cache_key)
if value is None:
value = self.nodelist.render(context)

View File

@ -26,7 +26,7 @@ For a development environment -- if you just want to experiment with Django --
you don't need to have a separate Web server installed; Django comes with its
own lightweight development server. For a production environment, Django
follows the WSGI_ spec, which means it can run on a variety of server
platforms. See :ref:`Deplying Django <howto-deployment-index>` for some
platforms. See :ref:`Deploying Django <howto-deployment-index>` for some
popular alternatives. Also, the `server arrangements wiki page`_ contains
details for several deployment strategies.

View File

@ -51,8 +51,9 @@ If your project is not on your ``PYTHONPATH`` by default you can add::
sys.path.append('/usr/local/django')
just above the ``import`` line to place your project on the path. Remember to
replace 'mysite.settings' with your correct settings file.
just above the final ``import`` line to place your project on the path. Remember to
replace 'mysite.settings' with your correct settings file, and '/usr/local/django'
with your own project's location.
See the :ref:`Apache/mod_python documentation<howto-deployment-modpython>` for
directions on serving static media, and the `mod_wsgi documentation`_ for an

View File

@ -243,9 +243,9 @@ might look like:
<h1>Articles for {{ year }}</h1>
{% for article in article_list %}
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
<p>{{ article.headline }}</p>
<p>By {{ article.reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}

View File

@ -238,8 +238,8 @@ the admin page doesn't display choices.
Yet.
There are two ways to solve this problem. The first register ``Choice`` with the
admin just as we did with ``Poll``. That's easy::
There are two ways to solve this problem. The first is to register ``Choice``
with the admin just as we did with ``Poll``. That's easy::
from mysite.polls.models import Choice

View File

@ -71,7 +71,7 @@ For more on :class:`~django.http.HttpRequest` objects, see the
:ref:`ref-request-response`. For more details on URLconfs, see the
:ref:`topics-http-urls`.
When you ran ``python django-admin.py startproject mysite`` at the beginning of
When you ran ``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 :setting:`ROOT_URLCONF` setting (in ``settings.py``) to
point at that file::
@ -98,8 +98,7 @@ This is worth a review. When somebody requests a page from your Web site -- say,
the :setting:`ROOT_URLCONF` setting. It finds the variable named ``urlpatterns``
and traverses the regular expressions in order. When it finds a regular
expression that matches -- ``r'^polls/(?P<poll_id>\d+)/$'`` -- it loads the
associated Python package/module: ``mysite.polls.views.detail``. That
corresponds to the function ``detail()`` in ``mysite/polls/views.py``. Finally,
function ``detail()`` from ``mysite/polls/views.py``. Finally,
it calls that ``detail()`` function like so::
detail(request=<HttpRequest object>, poll_id='23')
@ -468,7 +467,10 @@ Copy the file ``mysite/urls.py`` to ``mysite/polls/urls.py``. Then, change
``mysite/urls.py`` to remove the poll-specific URLs and insert an
:func:`~django.conf.urls.defaults.include`::
(r'^polls/', include('mysite.polls.urls')),
...
urlpatterns = patterns('',
(r'^polls/', include('mysite.polls.urls')),
...
:func:`~django.conf.urls.defaults.include`, simply, references another URLconf.
Note that the regular expression doesn't have a ``$`` (end-of-string match
@ -486,7 +488,8 @@ Here's what happens if a user goes to "/polls/34/" in this system:
further processing.
Now that we've decoupled that, we need to decouple the 'mysite.polls.urls'
URLconf by removing the leading "polls/" from each line::
URLconf by removing the leading "polls/" from each line, and removing the
lines registering the admin site::
urlpatterns = patterns('mysite.polls.views',
(r'^$', 'index'),

View File

@ -347,7 +347,7 @@ A few special cases to note about ``list_display``:
birthday = models.DateField()
def born_in_fifties(self):
return self.birthday.strftime('%Y')[:3] == 5
return self.birthday.strftime('%Y')[:3] == '195'
born_in_fifties.boolean = True
class PersonAdmin(admin.ModelAdmin):

View File

@ -611,7 +611,11 @@ sqlsequencereset <appname appname ...>
Prints the SQL statements for resetting sequences for the given app name(s).
See http://simon.incutio.com/archive/2004/04/21/postgres for more information.
Sequences are indexes used by some database engines to track the next available
number for automatically incremented fields.
Use this command to generate SQL which will fix cases where a sequence is out
of sync with its automatically incremented field data.
startapp <appname>
------------------

View File

@ -330,7 +330,7 @@ isn't manually specified. Used with ``DEFAULT_CHARSET`` to construct the
DEFAULT_FILE_STORAGE
--------------------
Default: ``django.core.files.storage.FileSystemStorage``
Default: ``'django.core.files.storage.FileSystemStorage'``
Default file storage class to be used for any file-related operations that don't
specify a particular storage system. See :ref:`topics-files`.

View File

@ -677,7 +677,7 @@ load_data::
management.call_command('flush', verbosity=0, interactive=False)
management.call_command('loaddata', 'test_data', verbosity=0)
Subcommands must now preceed options
Subcommands must now precede options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
``django-admin.py`` and ``manage.py`` now require subcommands to precede

View File

@ -945,11 +945,15 @@ in the :ref:`related objects reference <ref-models-relations>`.
Removes all objects from the related object set.
To assign the members of a related set in one fell swoop, just assign to it
from any iterable object. Example::
from any iterable object. The iterable can contain object instances, or just
a list of primary key values. For example::
b = Blog.objects.get(id=1)
b.entry_set = [e1, e2]
In this example, ``e1`` and ``e2`` can be full Entry instances, or integer
primary key values.
If the ``clear()`` method is available, any pre-existing objects will be
removed from the ``entry_set`` before all objects in the iterable (in this
case, a list) are added to the set. If the ``clear()`` method is *not*

View File

@ -611,7 +611,7 @@ Just like with ``ModelForms``, by default the ``clean()`` method of a
the unique constraints on your model (either ``unique``, ``unique_together`` or
``unique_for_date|month|year``). If you want to overide the ``clean()`` method
on a ``model_formset`` and maintain this validation, you must call the parent
classes ``clean`` method::
class's ``clean`` method::
class MyModelFormSet(BaseModelFormSet):
def clean(self):

View File

@ -107,15 +107,18 @@ middleware is always called on every response.
``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
:class:`~django.http. HttpResponse` object returned by a Django view.
``process_response()`` should return an :class:`~django.http. HttpResponse`
``process_response()`` must return an :class:`~django.http. HttpResponse`
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.
Unlike the ``process_request()`` and ``process_view()`` methods, the
``process_response()`` method is always called, even if the ``process_request()``
and ``process_view()`` methods of the same middleware class were skipped because
an earlier middleware method returned an :class:`~django.http. HttpResponse`
(this means that your ``process_response()`` method cannot rely on setup done in
``process_request()``, for example). In addition, 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:

View File

@ -4,6 +4,9 @@
How to use sessions
===================
.. module:: django.contrib.sessions
:synopsis: Provides session management for Django projects.
Django provides full support for anonymous sessions. The session framework lets
you store and retrieve arbitrary data on a per-site-visitor basis. It stores
data on the server side and abstracts the sending and receiving of cookies.

View File

@ -139,7 +139,7 @@ In the case of model tests, note that the test runner takes care of creating
its own test database. That is, any test that accesses a database -- by
creating and saving model instances, for example -- will not affect your
production database. However, the database is not refreshed between doctests,
so if your doctest requires a certain state you should consider flushin the
so if your doctest requires a certain state you should consider flushing the
database or loading a fixture. (See the section on fixtures, below, for more
on this.) Note that to use this feature, the database user Django is connecting
as must have ``CREATE DATABASE`` rights.
@ -1042,7 +1042,7 @@ applications:
Asserts that a ``Response`` instance produced the given ``status_code`` and
that ``text`` does not appears in the content of the response.
.. method:: assertFormError(response, form, field, errors)
.. method:: TestCase.assertFormError(response, form, field, errors)
Asserts that a field on a form raises the provided list of errors when
rendered on the form.
@ -1057,19 +1057,19 @@ applications:
``errors`` is an error string, or a list of error strings, that are
expected as a result of form validation.
.. method:: assertTemplateUsed(response, template_name)
.. method:: TestCase.assertTemplateUsed(response, template_name)
Asserts that the template with the given name was used in rendering the
response.
The name is a string such as ``'admin/index.html'``.
.. method:: assertTemplateNotUsed(response, template_name)
.. method:: TestCase.assertTemplateNotUsed(response, template_name)
Asserts that the template with the given name was *not* used in rendering
the response.
.. method:: assertRedirects(response, expected_url, status_code=302, target_status_code=200)
.. method:: TestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200)
Asserts that the response return a ``status_code`` redirect status, it
redirected to ``expected_url`` (including any GET data), and the final

View File

@ -629,7 +629,7 @@ class Templates(unittest.TestCase):
# Logically the same as above, just written with explicit
# ifchanged for the day.
'ifchanged-param04': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
'ifchanged-param05': ('{% for d in days %}{% ifchanged d.day %}{{ d.day }}{% endifchanged %}{% for h in d.hours %}{% ifchanged d.day h %}{{ h }}{% endifchanged %}{% endfor %}{% endfor %}', {'days':[{'day':1, 'hours':[1,2,3]},{'day':2, 'hours':[3]},] }, '112323'),
# Test the else clause of ifchanged.
'ifchanged-else01': ('{% for id in ids %}{{ id }}{% ifchanged id %}-first{% else %}-other{% endifchanged %},{% endfor %}', {'ids': [1,1,2,2,2,3]}, '1-first,1-other,2-first,2-other,2-other,3-first,'),
@ -1014,6 +1014,9 @@ class Templates(unittest.TestCase):
# Regression test for #7460.
'cache16': ('{% load cache %}{% cache 1 foo bar %}{% endcache %}', {'foo': 'foo', 'bar': 'with spaces'}, ''),
# Regression test for #11270.
'cache17': ('{% load cache %}{% cache 10 long_cache_key poem %}Some Content{% endcache %}', {'poem': 'Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont.'}, 'Some Content'),
### AUTOESCAPE TAG ##############################################
'autoescape-tag01': ("{% autoescape off %}hello{% endautoescape %}", {}, "hello"),
'autoescape-tag02': ("{% autoescape off %}{{ first }}{% endautoescape %}", {"first": "<b>hello</b>"}, "<b>hello</b>"),