summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-06-03 04:45:23 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-06-03 04:45:23 +0000
commitbb97eea9ec88978ecd5dca0a17d9b3ba344f9152 (patch)
tree452049c9841e7adcfe3051488135f7873b81db3e
parent554f4e7aa8a3ffe65cac3b6698906c06e7db4fe6 (diff)
downloaddjango-bb97eea9ec88978ecd5dca0a17d9b3ba344f9152.tar.gz
unicode: Merged from trunk up to [5418].
git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5419 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--AUTHORS1
-rw-r--r--django/bin/daily_cleanup.py10
-rw-r--r--django/conf/project_template/settings.py5
-rw-r--r--django/contrib/comments/feeds.py9
-rw-r--r--django/core/serializers/json.py2
-rw-r--r--django/core/serializers/pyyaml.py2
-rw-r--r--django/db/backends/dummy/base.py5
-rw-r--r--django/middleware/common.py2
-rw-r--r--docs/django-admin.txt9
-rw-r--r--docs/generic_views.txt3
-rw-r--r--docs/serialization.txt23
-rw-r--r--docs/settings.txt2
-rw-r--r--docs/templates_python.txt4
-rw-r--r--docs/testing.txt12
-rw-r--r--docs/tutorial04.txt5
-rw-r--r--docs/url_dispatch.txt9
-rw-r--r--tests/modeltests/serializers/models.py4
-rw-r--r--tests/regressiontests/serializers_regress/models.py4
-rw-r--r--tests/regressiontests/serializers_regress/tests.py37
19 files changed, 116 insertions, 32 deletions
diff --git a/AUTHORS b/AUTHORS
index 3e7dbd939d..c419b3092e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -144,6 +144,7 @@ answer newbie questions, and generally made Django that much better:
konrad@gwu.edu
kurtiss@meetro.com
lakin.wecker@gmail.com
+ Nick Lane <nick.lane.au@gmail.com>
Stuart Langridge <http://www.kryogenix.org/>
Nicola Larosa <nico@teknico.net>
Eugene Lazutkin <http://lazutkin.com/blog/>
diff --git a/django/bin/daily_cleanup.py b/django/bin/daily_cleanup.py
index 3b83583d73..c87be1e4c3 100644
--- a/django/bin/daily_cleanup.py
+++ b/django/bin/daily_cleanup.py
@@ -7,13 +7,13 @@ Can be run as a cronjob to clean out old data from the database (only expired
sessions at the moment).
"""
-from django.db import backend, connection, transaction
+import datetime
+from django.db import transaction
+from django.contrib.sessions.models import Session
def clean_up():
- # Clean up old database records
- cursor = connection.cursor()
- cursor.execute("DELETE FROM %s WHERE %s < NOW()" % \
- (backend.quote_name('django_session'), backend.quote_name('expire_date')))
+ """Clean up expired sessions."""
+ Session.objects.filter(expire_date__lt=datetime.datetime.now()).delete()
transaction.commit_unless_managed()
if __name__ == "__main__":
diff --git a/django/conf/project_template/settings.py b/django/conf/project_template/settings.py
index cadb5146b7..36039d7e98 100644
--- a/django/conf/project_template/settings.py
+++ b/django/conf/project_template/settings.py
@@ -38,8 +38,9 @@ USE_I18N = True
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''
-# URL that handles the media served from MEDIA_ROOT.
-# Example: "http://media.lawrence.com"
+# URL that handles the media served from MEDIA_ROOT. Make sure to use a
+# trailing slash if there is a path component (optional in other cases).
+# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
diff --git a/django/contrib/comments/feeds.py b/django/contrib/comments/feeds.py
index 2f395318b6..417e1d928a 100644
--- a/django/contrib/comments/feeds.py
+++ b/django/contrib/comments/feeds.py
@@ -23,16 +23,19 @@ class LatestFreeCommentsFeed(Feed):
self._site = Site.objects.get_current()
return u"Latest comments on %s" % self._site.name
+ def get_query_set(self):
+ return self.comments_class.objects.filter(site__pk=settings.SITE_ID, is_public=True)
+
def items(self):
- return self.comments_class.objects.filter(site__pk=settings.SITE_ID, is_public=True)[:40]
+ return self.get_query_set()[:40]
class LatestCommentsFeed(LatestFreeCommentsFeed):
"""Feed of latest free comments on the current site"""
comments_class = Comment
- def items(self):
- qs = LatestFreeCommentsFeed.items(self)
+ def get_query_set(self):
+ qs = super(LatestCommentsFeed, self).get_query_set()
qs = qs.filter(is_removed=False)
if settings.COMMENTS_BANNED_USERS_GROUP:
where = ['user_id NOT IN (SELECT user_id FROM auth_users_group WHERE group_id = %s)']
diff --git a/django/core/serializers/json.py b/django/core/serializers/json.py
index 55804b8316..fa2dca7295 100644
--- a/django/core/serializers/json.py
+++ b/django/core/serializers/json.py
@@ -21,6 +21,8 @@ class Serializer(PythonSerializer):
Convert a queryset to JSON.
"""
def end_serialization(self):
+ self.options.pop('stream', None)
+ self.options.pop('fields', None)
simplejson.dump(self.objects, self.stream, cls=DjangoJSONEncoder, **self.options)
def getvalue(self):
diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py
index e239681912..92159dbbe3 100644
--- a/django/core/serializers/pyyaml.py
+++ b/django/core/serializers/pyyaml.py
@@ -18,6 +18,8 @@ class Serializer(PythonSerializer):
Convert a queryset to YAML.
"""
def end_serialization(self):
+ self.options.pop('stream', None)
+ self.options.pop('fields', None)
yaml.dump(self.objects, self.stream, **self.options)
def getvalue(self):
diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py
index 6a909016fc..d0ec897407 100644
--- a/django/db/backends/dummy/base.py
+++ b/django/db/backends/dummy/base.py
@@ -12,6 +12,9 @@ from django.core.exceptions import ImproperlyConfigured
def complain(*args, **kwargs):
raise ImproperlyConfigured, "You haven't set the DATABASE_ENGINE setting yet."
+def ignore(*args, **kwargs):
+ pass
+
class DatabaseError(Exception):
pass
@@ -21,7 +24,7 @@ class IntegrityError(DatabaseError):
class DatabaseWrapper:
cursor = complain
_commit = complain
- _rollback = complain
+ _rollback = ignore
def __init__(self, **kwargs):
pass
diff --git a/django/middleware/common.py b/django/middleware/common.py
index 2c72c9a583..5f671dff7d 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -75,7 +75,7 @@ class CommonMiddleware(object):
# Use ETags, if requested.
if settings.USE_ETAGS:
etag = md5.new(response.content).hexdigest()
- if request.META.get('HTTP_IF_NONE_MATCH') == etag:
+ if response.status_code >= 200 and response.status_code < 300 and request.META.get('HTTP_IF_NONE_MATCH') == etag:
response = http.HttpResponseNotModified()
else:
response['ETag'] = etag
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index cc2eadc365..d20db7edc9 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -295,7 +295,7 @@ Serving static files with the development server
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, the development server doesn't serve any static files for your site
-(such as CSS files, images, things under ``MEDIA_ROOT_URL`` and so forth). If
+(such as CSS files, images, things under ``MEDIA_URL`` and so forth). If
you want to configure Django to serve static media, read the `serving static files`_
documentation.
@@ -403,9 +403,10 @@ this command to install the default apps.
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately.
-``syncdb`` will also search for and install any fixture named ``initial_data``.
-See the documentation for ``loaddata`` for details on the specification of
-fixture data files.
+``syncdb`` will also search for and install any fixture named ``initial_data``
+with an appropriate extension (e.g. ``json`` or ``xml``). See the
+documentation for ``loaddata`` for details on the specification of fixture
+data files.
test
----
diff --git a/docs/generic_views.txt b/docs/generic_views.txt
index bb5f7320f6..359a82506a 100644
--- a/docs/generic_views.txt
+++ b/docs/generic_views.txt
@@ -99,6 +99,9 @@ which is a dictionary of the parameters captured in the URL.
dictionary is callable, the generic view will call it
just before rendering the template.
+ * ``mimetype``: The MIME type to use for the resulting document. Defaults
+ to the value of the ``DEFAULT_CONTENT_TYPE`` setting.
+
**Example:**
Given the following URL patterns::
diff --git a/docs/serialization.txt b/docs/serialization.txt
index 3216cb061e..01afa2708c 100644
--- a/docs/serialization.txt
+++ b/docs/serialization.txt
@@ -44,6 +44,25 @@ This is useful if you want to serialize data directly to a file-like object
.. _HTTPResponse: ../request_response/#httpresponse-objects
+Subset of fields
+~~~~~~~~~~~~~~~~
+
+If you only want a subset of fields to be serialized, you can
+specify a `fields` argument to the serializer::
+
+ from django.core import serializers
+ data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))
+
+In this example, only the `name` and `size` attributes of each model will
+be serialized.
+
+.. note::
+
+ Depending on your model, you may find that it is not possible to deserialize
+ a model that only serializes a subset of its fields. If a serialized object
+ doesn't specify all the fields that are required by a model, the deserializer
+ will not be able to save deserialized instances.
+
Deserializing data
------------------
@@ -92,10 +111,14 @@ Django "ships" with a few included serializers:
``python`` Translates to and from "simple" Python objects (lists, dicts,
strings, etc.). Not really all that useful on its own, but
used as a base for other serializers.
+
+ ``yaml`` Serializes to YAML (Yet Another Markup Lanuage). This
+ serializer is only available if PyYAML_ is installed.
========== ==============================================================
.. _json: http://json.org/
.. _simplejson: http://undefined.org/python/#simplejson
+.. _PyYAML: http://www.pyyaml.org/
Notes for specific serialization formats
----------------------------------------
diff --git a/docs/settings.txt b/docs/settings.txt
index de2ad37518..4455864d54 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -860,7 +860,7 @@ TEST_DATABASE_COLLATION
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.
+passed directly to the backend, so its format is backend-specific.
Only supported for ``mysql`` and ``mysql_old`` backends (see `section 10.3.2`_
of the MySQL manual for details).
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index aaf109b659..f3e2f2c64b 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -394,8 +394,8 @@ See the `internationalization docs`_ for more.
django.core.context_processors.media
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processors, every
-``RequestContext`` will contain ``MEDIA_URL``, providing the
+If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
+``RequestContext`` will contain a variable ``MEDIA_URL``, providing the
value of the `MEDIA_URL setting`_.
.. _MEDIA_URL setting: ../settings/#media-url
diff --git a/docs/testing.txt b/docs/testing.txt
index dedb1e15a8..50c4ec3046 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -571,13 +571,11 @@ 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.
+**New in Django development version:** For fine-grained control over the
+character encoding of your database, use the ``TEST_DATABASE_CHARSET`` setting.
+If you're using MySQL, you can also use the ``TEST_DATABASE_COLLATION`` setting
+to control the particular collation used by the test database. See the
+settings_ documentation for details of these advanced settings.
.. _settings: ../settings/
diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt
index 8aa9379c91..5cc12c445d 100644
--- a/docs/tutorial04.txt
+++ b/docs/tutorial04.txt
@@ -67,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(reverse('results', args=(p.id,)))
+ return HttpResponseRedirect(reverse('mysite.polls.views.results', args=(p.id,)))
This code includes a few things we haven't covered yet in this tutorial:
@@ -104,7 +104,8 @@ This code includes a few things we haven't covered yet in this tutorial:
'/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.
+ then call the ``'results'`` view to display the final page. Note that
+ you need to use the full name of the view here (including the prefix).
For more information about ``reverse()``, see the `URL dispatcher`_
documentation.
diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt
index 1a2efe605a..402b1200b5 100644
--- a/docs/url_dispatch.txt
+++ b/docs/url_dispatch.txt
@@ -564,10 +564,11 @@ code, Django provides the ``django.core.urlresolvers.reverse()``. The
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::
+``viewname`` is either the function name (either a function reference, or the
+string version of the name, if you used that form in ``urlpatterns``) or the
+`URL pattern name`_. Normally, you won't 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
diff --git a/tests/modeltests/serializers/models.py b/tests/modeltests/serializers/models.py
index e5064a09fe..b7543f9348 100644
--- a/tests/modeltests/serializers/models.py
+++ b/tests/modeltests/serializers/models.py
@@ -159,4 +159,8 @@ __test__ = {'API_TESTS':"""
>>> article.author
<Author: Agnes>
+# Serializer output can be restricted to a subset of fields
+>>> print serializers.serialize("json", Article.objects.all(), fields=('headline','pub_date'))
+[{"pk": "1", "model": "serializers.article", "fields": {"headline": "Just kidding; I love TV poker", "pub_date": "2006-06-16 11:00:00"}}, {"pk": "2", "model": "serializers.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": "3", "model": "serializers.article", "fields": {"headline": "Forward references pose no problem", "pub_date": "2006-06-16 15:00:00"}}]
+
"""}
diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
index 3b9c228d4c..b441885f10 100644
--- a/tests/regressiontests/serializers_regress/models.py
+++ b/tests/regressiontests/serializers_regress/models.py
@@ -205,3 +205,7 @@ class USStatePKData(models.Model):
# class XMLPKData(models.Model):
# data = models.XMLField(primary_key=True)
+class ComplexModel(models.Model):
+ field1 = models.CharField(maxlength=10)
+ field2 = models.CharField(maxlength=10)
+ field3 = models.CharField(maxlength=10)
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index af0cd64cf8..e20bbbd363 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -9,6 +9,7 @@ forward, backwards and self references.
import unittest, datetime
+from cStringIO import StringIO
from django.utils.functional import curry
from django.core import serializers
@@ -281,5 +282,41 @@ def serializerTest(format, self):
for (func, pk, klass, datum) in test_data:
func[1](self, pk, klass, datum)
+def fieldsTest(format, self):
+ # Clear the database first
+ management.flush(verbosity=0, interactive=False)
+
+ obj = ComplexModel(field1='first',field2='second',field3='third')
+ obj.save()
+
+ # Serialize then deserialize the test database
+ serialized_data = serializers.serialize(format, [obj], indent=2, fields=('field1','field3'))
+ result = serializers.deserialize(format, serialized_data).next()
+
+ # Check that the deserialized object contains data in only the serialized fields.
+ self.assertEqual(result.object.field1, 'first')
+ self.assertEqual(result.object.field2, '')
+ self.assertEqual(result.object.field3, 'third')
+
+def streamTest(format, self):
+ # Clear the database first
+ management.flush(verbosity=0, interactive=False)
+
+ obj = ComplexModel(field1='first',field2='second',field3='third')
+ obj.save()
+
+ # Serialize the test database to a stream
+ stream = StringIO()
+ serializers.serialize(format, [obj], indent=2, stream=stream)
+
+ # Serialize normally for a comparison
+ string_data = serializers.serialize(format, [obj], indent=2)
+
+ # Check that the two are the same
+ self.assertEqual(string_data, stream.buffer())
+ stream.close()
+
for format in serializers.get_serializer_formats():
setattr(SerializerTests, 'test_'+format+'_serializer', curry(serializerTest, format))
+ setattr(SerializerTests, 'test_'+format+'_serializer_fields', curry(fieldsTest, format))
+ setattr(SerializerTests, 'test_'+format+'_serializer_stream', curry(fieldsTest, format))