diff options
author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-06-03 04:45:23 +0000 |
---|---|---|
committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2007-06-03 04:45:23 +0000 |
commit | bb97eea9ec88978ecd5dca0a17d9b3ba344f9152 (patch) | |
tree | 452049c9841e7adcfe3051488135f7873b81db3e | |
parent | 554f4e7aa8a3ffe65cac3b6698906c06e7db4fe6 (diff) | |
download | django-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-- | AUTHORS | 1 | ||||
-rw-r--r-- | django/bin/daily_cleanup.py | 10 | ||||
-rw-r--r-- | django/conf/project_template/settings.py | 5 | ||||
-rw-r--r-- | django/contrib/comments/feeds.py | 9 | ||||
-rw-r--r-- | django/core/serializers/json.py | 2 | ||||
-rw-r--r-- | django/core/serializers/pyyaml.py | 2 | ||||
-rw-r--r-- | django/db/backends/dummy/base.py | 5 | ||||
-rw-r--r-- | django/middleware/common.py | 2 | ||||
-rw-r--r-- | docs/django-admin.txt | 9 | ||||
-rw-r--r-- | docs/generic_views.txt | 3 | ||||
-rw-r--r-- | docs/serialization.txt | 23 | ||||
-rw-r--r-- | docs/settings.txt | 2 | ||||
-rw-r--r-- | docs/templates_python.txt | 4 | ||||
-rw-r--r-- | docs/testing.txt | 12 | ||||
-rw-r--r-- | docs/tutorial04.txt | 5 | ||||
-rw-r--r-- | docs/url_dispatch.txt | 9 | ||||
-rw-r--r-- | tests/modeltests/serializers/models.py | 4 | ||||
-rw-r--r-- | tests/regressiontests/serializers_regress/models.py | 4 | ||||
-rw-r--r-- | tests/regressiontests/serializers_regress/tests.py | 37 |
19 files changed, 116 insertions, 32 deletions
@@ -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)) |