summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoulder Sprinters <boulder-sprinters@djangoproject.com>2007-03-20 16:21:17 +0000
committerBoulder Sprinters <boulder-sprinters@djangoproject.com>2007-03-20 16:21:17 +0000
commit815837c8af6cb917dabbb3638b2ccf182263866d (patch)
tree5ed1c4d8448c2977f8773404effe4360c1f9ae9d
parent881c07cf2e212e04b2a8be47f444c6da56b5f382 (diff)
downloaddjango-815837c8af6cb917dabbb3638b2ccf182263866d.tar.gz
boulder-oracle-sprint: Merged to [4754]. 8 tests still fail, although
serializers_regress fails on Postgres as well so it may need a more general fix. git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@4755 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/core/serializers/base.py20
-rw-r--r--django/core/serializers/pyyaml.py4
-rw-r--r--django/core/serializers/xml_serializer.py9
-rw-r--r--django/db/backends/mysql/base.py10
-rw-r--r--django/db/models/fields/__init__.py12
-rw-r--r--django/db/models/fields/generic.py1
-rw-r--r--django/db/models/options.py1
-rw-r--r--django/db/models/query.py2
-rw-r--r--django/template/defaulttags.py8
-rw-r--r--django/utils/datastructures.py2
-rw-r--r--django/utils/text.py2
-rw-r--r--docs/contributing.txt14
-rw-r--r--docs/databases.txt122
-rw-r--r--docs/distributions.txt2
-rw-r--r--docs/django-admin.txt2
-rw-r--r--docs/i18n.txt14
-rw-r--r--docs/model-api.txt5
-rw-r--r--tests/regressiontests/defaultfilters/tests.py6
-rw-r--r--tests/regressiontests/serializers_regress/models.py19
-rw-r--r--tests/regressiontests/serializers_regress/tests.py20
20 files changed, 170 insertions, 105 deletions
diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
index 7dde2a4faf..8e610ad240 100644
--- a/django/core/serializers/base.py
+++ b/django/core/serializers/base.py
@@ -34,17 +34,17 @@ class Serializer(object):
for obj in queryset:
self.start_object(obj)
for field in obj._meta.fields:
- if field is obj._meta.pk:
- continue
- elif field.rel is None:
- if self.selected_fields is None or field.attname in self.selected_fields:
- self.handle_field(obj, field)
- else:
- if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
- self.handle_fk_field(obj, field)
+ if field.serialize:
+ if field.rel is None:
+ if self.selected_fields is None or field.attname in self.selected_fields:
+ self.handle_field(obj, field)
+ else:
+ if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
+ self.handle_fk_field(obj, field)
for field in obj._meta.many_to_many:
- if self.selected_fields is None or field.attname in self.selected_fields:
- self.handle_m2m_field(obj, field)
+ if field.serialize:
+ if self.selected_fields is None or field.attname in self.selected_fields:
+ self.handle_m2m_field(obj, field)
self.end_object(obj)
self.end_serialization()
return self.getvalue()
diff --git a/django/core/serializers/pyyaml.py b/django/core/serializers/pyyaml.py
index f45a511e79..fa3dec984e 100644
--- a/django/core/serializers/pyyaml.py
+++ b/django/core/serializers/pyyaml.py
@@ -15,7 +15,7 @@ import yaml
class Serializer(PythonSerializer):
"""
- Convert a queryset to JSON.
+ Convert a queryset to YAML.
"""
def end_serialization(self):
yaml.dump(self.objects, self.stream, **self.options)
@@ -25,7 +25,7 @@ class Serializer(PythonSerializer):
def Deserializer(stream_or_string, **options):
"""
- Deserialize a stream or string of JSON data.
+ Deserialize a stream or string of YAML data.
"""
if isinstance(stream_or_string, basestring):
stream = StringIO(stream_or_string)
diff --git a/django/core/serializers/xml_serializer.py b/django/core/serializers/xml_serializer.py
index 9e37f03cc2..3a0fdb5395 100644
--- a/django/core/serializers/xml_serializer.py
+++ b/django/core/serializers/xml_serializer.py
@@ -13,6 +13,10 @@ class Serializer(base.Serializer):
Serializes a QuerySet to XML.
"""
+ def indent(self, level):
+ if self.options.get('indent', None) is not None:
+ self.xml.ignorableWhitespace('\n' + ' ' * self.options.get('indent', None) * level)
+
def start_serialization(self):
"""
Start serialization -- open the XML document and the root element.
@@ -25,6 +29,7 @@ class Serializer(base.Serializer):
"""
End serialization -- end the document.
"""
+ self.indent(0)
self.xml.endElement("django-objects")
self.xml.endDocument()
@@ -35,6 +40,7 @@ class Serializer(base.Serializer):
if not hasattr(obj, "_meta"):
raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
+ self.indent(1)
self.xml.startElement("object", {
"pk" : str(obj._get_pk_val()),
"model" : str(obj._meta),
@@ -44,6 +50,7 @@ class Serializer(base.Serializer):
"""
Called after handling all fields for an object.
"""
+ self.indent(1)
self.xml.endElement("object")
def handle_field(self, obj, field):
@@ -51,6 +58,7 @@ class Serializer(base.Serializer):
Called to handle each field on an object (except for ForeignKeys and
ManyToManyFields)
"""
+ self.indent(2)
self.xml.startElement("field", {
"name" : field.name,
"type" : field.get_internal_type()
@@ -94,6 +102,7 @@ class Serializer(base.Serializer):
"""
Helper to output the <field> element for relational fields
"""
+ self.indent(2)
self.xml.startElement("field", {
"name" : field.name,
"rel" : field.rel.__class__.__name__,
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index c635e58cba..5767eaed51 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -10,8 +10,14 @@ try:
except ImportError, e:
from django.core.exceptions import ImproperlyConfigured
raise ImproperlyConfigured, "Error loading MySQLdb module: %s" % e
-if Database.version_info < (1,2,1,'final',2):
- raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % MySQLdb.__version__
+
+# We want version (1, 2, 1, 'final', 2) or later. We can't just use
+# lexicographic ordering in this check because then (1, 2, 1, 'gamma')
+# inadvertently passes the version test.
+version = Database.version_info
+if (version < (1,2,1) or (version[:3] == (1, 2, 1) and
+ (len(version) < 5 or version[3] != 'final' or version[4] < 2))):
+ raise ImportError, "MySQLdb-1.2.1p2 or newer is required; you have %s" % Database.__version__
from MySQLdb.converters import conversions
from MySQLdb.constants import FIELD_TYPE
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index b1436dcecd..cb167004bc 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -67,7 +67,7 @@ class Field(object):
def __init__(self, verbose_name=None, name=None, primary_key=False,
maxlength=None, unique=False, blank=False, null=False, db_index=False,
- core=False, rel=None, default=NOT_PROVIDED, editable=True,
+ core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
prepopulate_from=None, unique_for_date=None, unique_for_month=None,
unique_for_year=None, validator_list=None, choices=None, radio_admin=None,
help_text='', db_column=None):
@@ -78,6 +78,7 @@ class Field(object):
self.blank, self.null = blank, null
self.core, self.rel, self.default = core, rel, default
self.editable = editable
+ self.serialize = serialize
self.validator_list = validator_list or []
self.prepopulate_from = prepopulate_from
self.unique_for_date, self.unique_for_month = unique_for_date, unique_for_month
@@ -851,9 +852,12 @@ class TimeField(Field):
value = value.replace(microsecond=0)
value = str(value)
elif settings.DATABASE_ENGINE == 'oracle':
- value = value.replace(microsecond=0)
- # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
- value = datetime.datetime(1900, 1, 1, value.hour, value.minute, value.second)
+ if hasattr(value, 'microsecond'):
+ value = value.replace(microsecond=0)
+ # cx_Oracle expects a datetime.datetime to persist into TIMESTAMP field.
+ value = datetime.datetime(1900, 1, 1, value.hour, value.minute, value.second)
+ else:
+ value = datetime.datetime(*(time.strptime(value, '%H:%M:%S')[:6]))
else:
value = str(value)
return Field.get_db_prep_save(self, value)
diff --git a/django/db/models/fields/generic.py b/django/db/models/fields/generic.py
index 1ad8346e42..480ee689c9 100644
--- a/django/db/models/fields/generic.py
+++ b/django/db/models/fields/generic.py
@@ -94,6 +94,7 @@ class GenericRelation(RelatedField, Field):
kwargs['blank'] = True
kwargs['editable'] = False
+ kwargs['serialize'] = False
Field.__init__(self, **kwargs)
def get_manipulator_field_objs(self):
diff --git a/django/db/models/options.py b/django/db/models/options.py
index 32a9a274ce..e2c896a668 100644
--- a/django/db/models/options.py
+++ b/django/db/models/options.py
@@ -88,6 +88,7 @@ class Options(object):
self.fields.insert(bisect(self.fields, field), field)
if not self.pk and field.primary_key:
self.pk = field
+ field.serialize = False
def __repr__(self):
return '<Options for %s>' % self.object_name
diff --git a/django/db/models/query.py b/django/db/models/query.py
index b92cf4e04e..b9dd620afc 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -808,7 +808,7 @@ def fill_table_cache(opts, select, tables, where, old_prefix, cache_tables_seen,
def parse_lookup(kwarg_items, opts):
# Helper function that handles converting API kwargs
# (e.g. "name__exact": "tom") to SQL.
- # Returns a tuple of (tables, joins, where, params).
+ # Returns a tuple of (joins, where, params).
# 'joins' is a sorted dictionary describing the tables that must be joined
# to complete the query. The dictionary is sorted because creation order
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index ed870047b1..b18fa1dce7 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -582,7 +582,7 @@ ifequal = register.tag(ifequal)
#@register.tag
def ifnotequal(parser, token):
- """Output the contents of the block if the two arguments are not equal. See ifequal"""
+ """Output the contents of the block if the two arguments are not equal. See ifequal."""
return do_ifequal(parser, token, True)
ifnotequal = register.tag(ifnotequal)
@@ -901,7 +901,7 @@ def url(parser, token):
"""
Returns an absolute URL matching given view with its parameters.
- This is a way to define links that aren't tied to a particular url configuration::
+ This is a way to define links that aren't tied to a particular URL configuration::
{% url path.to.some_view arg1,arg2,name1=value1 %}
@@ -912,11 +912,11 @@ def url(parser, token):
URL. All arguments for the URL should be present.
For example if you have a view ``app_name.client`` taking client's id and
- the corresponding line in a urlconf looks like this::
+ the corresponding line in a URLconf looks like this::
('^client/(\d+)/$', 'app_name.client')
- and this app's urlconf is included into the project's urlconf under some
+ and this app's URLconf is included into the project's URLconf under some
path::
('^clients/', include('project_name.app_name.urls'))
diff --git a/django/utils/datastructures.py b/django/utils/datastructures.py
index e924e4edbc..7b7fa2b0f0 100644
--- a/django/utils/datastructures.py
+++ b/django/utils/datastructures.py
@@ -94,7 +94,7 @@ class SortedDict(dict):
def copy(self):
"Returns a copy of this object."
- # This way of initialising the copy means it works for subclasses, too.
+ # This way of initializing the copy means it works for subclasses, too.
obj = self.__class__(self)
obj.keyOrder = self.keyOrder
return obj
diff --git a/django/utils/text.py b/django/utils/text.py
index 1c1c456e2d..faf8705fa9 100644
--- a/django/utils/text.py
+++ b/django/utils/text.py
@@ -17,7 +17,7 @@ def wrap(text, width):
pos = len(word) - word.rfind('\n') - 1
for word in it:
if "\n" in word:
- lines = word.splitlines()
+ lines = word.split('\n')
else:
lines = (word,)
pos += len(lines[0]) + 1
diff --git a/docs/contributing.txt b/docs/contributing.txt
index 8364405775..1d2b635b76 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -303,11 +303,11 @@ Please follow these coding standards when writing code for inclusion in Django:
def my_view(req, foo):
# ...
- * Our policy is to keep the names of developers and contributors
- in the ``AUTHORS`` file distributed with Django, so please don't include
- your name in the actual code. Feel free to include a change to the
- ``AUTHORS`` file in your patch if you make more than a single trivial
- change.
+ * Please don't put your name in the code you contribute. Our policy is to
+ keep contributors' names in the ``AUTHORS`` file distributed with Django
+ -- not scattered throughout the codebase itself. Feel free to include a
+ change to the ``AUTHORS`` file in your patch if you make more than a
+ single trivial change.
Committing code
===============
@@ -527,12 +527,12 @@ sure all other lines are commented::
# http://code.djangoproject.com/svn/django/trunk/
#
/path/to/trunk
-
+
# <branch> is a svn checkout of:
# http://code.djangoproject.com/svn/django/branches/<branch>/
#
#/path/to/<branch>
-
+
# On windows a path may look like this:
# C:/path/to/<branch>
diff --git a/docs/databases.txt b/docs/databases.txt
index ff6abd7271..3545b58d47 100644
--- a/docs/databases.txt
+++ b/docs/databases.txt
@@ -1,56 +1,59 @@
===============================
-Notes About Supported Databases
+Notes about supported databases
===============================
-Django attempts to support as many features as possible on all databases.
-However, since not all database servers are identical, there is obviously
-going to be some variations. This file describes some of the
-features that might relevant to Django usage. It is not intended as a
-replacement for server-specific documentation or reference manuals.
+Django attempts to support as many features as possible on all database
+backends. However, not all database backends are alike, and we've had to make
+design decisions on which features to support and which assumptions we can make
+safely.
-MySQL Notes
+This file describes some of the features that might be relevant to Django
+usage. Of course, it is not intended as a replacement for server-specific
+documentation or reference manuals.
+
+MySQL notes
===========
Django expects the database to support transactions, referential integrity,
-and Unicode support (UTF-8 encoding). Fortunately MySQL_ has all these
+and Unicode support (UTF-8 encoding). Fortunately, MySQL_ has all these
features as available as far back as 3.23. While it may be possible to use
-3.23 or 4.0, you will probably have less trouble if you use 4.1 or 5.0.
+3.23 or 4.0, you'll probably have less trouble if you use 4.1 or 5.0.
-MySQL-4.1
+MySQL 4.1
---------
-MySQL-4.1_ has greatly improved support for character sets. It is possible to
+`MySQL 4.1`_ has greatly improved support for character sets. It is possible to
set different default character sets on the database, table, and column.
Previous versions have only a server-wide character set setting. It's also the
first version where the character set can be changed on the fly. 4.1 also has
-support for views, but these are not currently used by Django.
+support for views, but Django currently doesn't use views.
-MySQL-5.0
+MySQL 5.0
---------
-MySQL-5.0_ adds the ``information_schema`` database, which contains detailed
-data on all database schema. This is used for Django's ``inspectdb`` feature,
-when it is available. 5.0 also has support for stored procedures, but these
-are not currently used by Django.
+`MySQL 5.0`_ adds the ``information_schema`` database, which contains detailed
+data on all database schema. Django's ``inspectdb`` feature uses this
+``information_schema`` if it's available. 5.0 also has support for stored
+procedures, but Django currently doesn't use stored procedures.
.. _MySQL: http://www.mysql.com/
-.. _MySQL-4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html
-.. _MySQL-5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html
+.. _MySQL 4.1: http://dev.mysql.com/doc/refman/4.1/en/index.html
+.. _MySQL 5.0: http://dev.mysql.com/doc/refman/5.0/en/index.html
-Storage Engines
+Storage engines
---------------
MySQL has several `storage engines`_ (previously called table types). You can
change the default storage engine in the server configuration.
-The default one is MyISAM_. The main drawback of MyISAM is that it does not
-currently have support for transactions or foreign keys. On the plus side, it
-is currently the only engine that supports full-text indexing and searching.
+The default engine is MyISAM_. The main drawback of MyISAM is that it doesn't
+currently support transactions or foreign keys. On the plus side, it's
+currently the only engine that supports full-text indexing and searching.
The InnoDB_ engine is fully transactional and supports foreign key references.
The BDB_ engine, like InnoDB, is also fully transactional and supports foreign
-key references. However, it's use seems to be somewhat deprecated.
+key references. However, its use seems to be deprecated.
`Other storage engines`_, including SolidDB_ and Falcon_, are on the horizon.
For now, InnoDB is probably your best choice.
@@ -66,25 +69,25 @@ For now, InnoDB is probably your best choice.
MySQLdb
-------
-`MySQLdb`_ is the Python interface to MySQL. 1.2.1 is the first version which
-has support for MySQL-4.1 and newer. If you are trying to use an older version
-of MySQL, then 1.2.0 *may* work for you.
+`MySQLdb`_ is the Python interface to MySQL. 1.2.1 is the first version that
+has support for MySQL 4.1 and newer. If you are trying to use an older version
+of MySQL, then 1.2.0 *might* work for you.
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
Creating your database
-~~~~~~~~~~~~~~~~~~~~~~
+----------------------
You can `create your database`_ using the command-line tools and this SQL::
CREATE DATABASE <dbname> CHARACTER SET utf8;
-
-This ensures all tables and columns will use utf8 by default.
-
+
+This ensures all tables and columns will use UTF-8 by default.
+
.. _create your database: http://dev.mysql.com/doc/refman/5.0/en/create-database.html
Connecting to the database
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+--------------------------
Refer to the `settings documentation`_.
@@ -106,7 +109,7 @@ Here's a sample configuration which uses a MySQL option file::
DATABASE_OPTIONS = {
'read_default_file': '/path/to/my.cnf',
}
-
+
# my.cnf
[client]
database = DATABASE_NAME
@@ -114,49 +117,46 @@ Here's a sample configuration which uses a MySQL option file::
passwd = DATABASE_PASSWORD
default-character-set = utf8
-There are several other MySQLdb connection options which may be useful, such
-as ``ssl``, ``use_unicode``, ``init_command``, and ``sql_mode``; consult the
+Several other MySQLdb connection options may be useful, such as ``ssl``,
+``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
`MySQLdb documentation`_ for more details.
-
+
.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
Creating your tables
-~~~~~~~~~~~~~~~~~~~~
+--------------------
-When Django generates the schema, it doesn't specify a storage engine, so they
-will be created with whatever default `storage engine`__ your database server
-is configured for. The easiest solution is to set your database server's default
-storage engine to the desired engine.
+When Django generates the schema, it doesn't specify a storage engine, so
+tables will be created with whatever default storage engine your database
+server is configured for. The easiest solution is to set your database server's
+default storage engine to the desired engine.
-__ `storage engines`_
-
-If you are using a hosting service and can't change your server's default
+If you're using a hosting service and can't change your server's default
storage engine, you have a couple of options.
-After the tables is created, all that is needed to convert it to a new storage
-engine (such as InnoDB) is::
-
- ALTER TABLE <tablename> ENGINE=INNODB;
+ * After the tables are created, execute an ``ALTER TABLE`` statement to
+ convert a table to a new storage engine (such as InnoDB)::
-With a lot of tables, this can be tedious.
+ ALTER TABLE <tablename> ENGINE=INNODB;
-Another option is to use the ``init_command`` option for MySQLdb prior to
-creating your tables::
+ This can be tedious if you have a lot of tables.
- DATABASE_OPTIONS = {
- ...
- "init_command": "SET storage_engine=INNODB",
- ...
- }
+ * Another option is to use the ``init_command`` option for MySQLdb prior to
+ creating your tables::
+
+ DATABASE_OPTIONS = {
+ # ...
+ "init_command": "SET storage_engine=INNODB",
+ # ...
+ }
-This sets the default storage engine upon connecting to the database. After
-your tables are set up and running in production, you should remove this
-option.
+ This sets the default storage engine upon connecting to the database.
+ After your tables have been created, you should remove this option.
-Another method for changing the storage engine is described in
-AlterModelOnSyncDB_.
+ * Another method for changing the storage engine is described in
+ AlterModelOnSyncDB_.
.. _AlterModelOnSyncDB: http://code.djangoproject.com/wiki/AlterModelOnSyncDB
diff --git a/docs/distributions.txt b/docs/distributions.txt
index a77d3a1959..63206c535e 100644
--- a/docs/distributions.txt
+++ b/docs/distributions.txt
@@ -57,7 +57,7 @@ Gentoo
------
A Django build is available for `Gentoo Linux`_, and is based on Django 0.95.1.
-The `current Gentoo build`_ can be installed by typing ``emerge Django``.
+The `current Gentoo build`_ can be installed by typing ``emerge django``.
.. _Gentoo Linux: http://www.gentoo.org/
.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index 371c44e010..ef1d73cdbd 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -216,7 +216,7 @@ installation will be aborted, and any data installed in the call to
``loaddata`` will be removed from the database.
The fixtures that are named can include directory components. These
-directories will be inluded in the search path. For example::
+directories will be included in the search path. For example::
django-admin.py loaddata foo/bar/mydata.json
diff --git a/docs/i18n.txt b/docs/i18n.txt
index d430a56160..4a05e53ddf 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -284,13 +284,13 @@ obtain) the language translations themselves. Here's how that works.
.. admonition:: Locale restrictions
- Django does not support localising your application into a locale for
- which Django itself has not been translated -- it will ignore your
- translation files. If you were to try this and Django supported it, you
- would inevitably see a mixture of translated strings (from your
- application) and English strings (from Django itself). If you are wanting
- to support a locale for your application that is not already part of
- Django, you will need to make at least a minimal translation of the Django
+ Django does not support localizing your application into a locale for
+ which Django itself has not been translated. In this case, it will ignore
+ your translation files. If you were to try this and Django supported it,
+ you would inevitably see a mixture of translated strings (from your
+ application) and English strings (from Django itself). If you want to
+ support a locale for your application that is not already part of
+ Django, you'll need to make at least a minimal translation of the Django
core.
Message files
diff --git a/docs/model-api.txt b/docs/model-api.txt
index e66e96de68..26686b02fe 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -1216,8 +1216,9 @@ screen via ``<script src="">`` tags. This can be used to tweak a given type of
admin page in JavaScript or to provide "quick links" to fill in default values
for certain fields.
-If relative URLs are used, Django admin will automatically prepend these links
-with ``settings.ADMIN_MEDIA_PREFIX``.
+If you use relative URLs -- URLs that don't start with ``http://`` or ``/`` --
+then the admin site will automatically prefix these links with
+``settings.ADMIN_MEDIA_PREFIX``.
``list_display``
----------------
diff --git a/tests/regressiontests/defaultfilters/tests.py b/tests/regressiontests/defaultfilters/tests.py
index c850806052..db3f7fab2a 100644
--- a/tests/regressiontests/defaultfilters/tests.py
+++ b/tests/regressiontests/defaultfilters/tests.py
@@ -133,6 +133,12 @@ u'\xcb'
>>> wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14)
"this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI'm afraid"
+>>> wordwrap('this is a short paragraph of text.\n But this line should be indented',14)
+'this is a\nshort\nparagraph of\ntext.\n But this\nline should be\nindented'
+
+>>> wordwrap('this is a short paragraph of text.\n But this line should be indented',15)
+'this is a short\nparagraph of\ntext.\n But this line\nshould be\nindented'
+
>>> ljust('test', 10)
'test '
diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
index b558050022..d3415ac1b9 100644
--- a/tests/regressiontests/serializers_regress/models.py
+++ b/tests/regressiontests/serializers_regress/models.py
@@ -6,7 +6,8 @@ This class sets up a model for each model field type
"""
from django.db import models
-
+from django.contrib.contenttypes.models import ContentType
+
# The following classes are for testing basic data
# marshalling, including NULL values.
@@ -73,6 +74,22 @@ class USStateData(models.Model):
class XMLData(models.Model):
data = models.XMLField(null=True)
+class Tag(models.Model):
+ """A tag on an item."""
+ data = models.SlugField()
+ content_type = models.ForeignKey(ContentType)
+ object_id = models.PositiveIntegerField()
+
+ content_object = models.GenericForeignKey()
+
+ class Meta:
+ ordering = ["data"]
+
+class GenericData(models.Model):
+ data = models.CharField(maxlength=30)
+
+ tags = models.GenericRelation(Tag)
+
# The following test classes are all for validation
# of related objects; in particular, forward, backward,
# and self references.
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index 008ccecc2c..97b3fbacbe 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -24,6 +24,14 @@ def data_create(pk, klass, data):
instance.data = data
instance.save()
return instance
+
+def generic_create(pk, klass, data):
+ instance = klass(id=pk)
+ instance.data = data[0]
+ instance.save()
+ for tag in data[1:]:
+ instance.tags.create(data=tag)
+ return instance
def fk_create(pk, klass, data):
instance = klass(id=pk)
@@ -56,6 +64,11 @@ def data_compare(testcase, pk, klass, data):
testcase.assertEqual(data, instance.data,
"Objects with PK=%d not equal; expected '%s' (%s), got '%s' (%s)" % (pk,data, type(data), instance.data, type(instance.data)))
+def generic_compare(testcase, pk, klass, data):
+ instance = klass.objects.get(id=pk)
+ testcase.assertEqual(data[0], instance.data)
+ testcase.assertEqual(data[1:], [t.data for t in instance.tags.all()])
+
def fk_compare(testcase, pk, klass, data):
instance = klass.objects.get(id=pk)
testcase.assertEqual(data, instance.data_id)
@@ -76,6 +89,7 @@ def pk_compare(testcase, pk, klass, data):
# actually a pair of functions; one to create
# and one to compare objects of that type
data_obj = (data_create, data_compare)
+generic_obj = (generic_create, generic_compare)
fk_obj = (fk_create, fk_compare)
m2m_obj = (m2m_create, m2m_compare)
o2o_obj = (o2o_create, o2o_compare)
@@ -140,6 +154,9 @@ The end."""),
(data_obj, 190, XMLData, "<foo></foo>"),
(data_obj, 191, XMLData, None),
+ (generic_obj, 200, GenericData, ['Generic Object 1', 'tag1', 'tag2']),
+ (generic_obj, 201, GenericData, ['Generic Object 2', 'tag2', 'tag3']),
+
(data_obj, 300, Anchor, "Anchor 1"),
(data_obj, 301, Anchor, "Anchor 2"),
@@ -222,6 +239,9 @@ def serializerTest(format, self):
transaction.commit()
transaction.leave_transaction_management()
+ # Add the generic tagged objects to the object list
+ objects.extend(Tag.objects.all())
+
# Serialize the test database
serialized_data = serializers.serialize(format, objects, indent=2)