From d1290b5b43485c7018ba92981d34c1f96614924e Mon Sep 17 00:00:00 2001
From: Russell Keith-Magee <russell@keith-magee.com>
Date: Thu, 3 Mar 2011 13:28:20 +0000
Subject: [PATCH] Fixed #3094 -- Accelerated deprecation of XMLField, since it
 hasn't served any useful purpose since oldforms. Thanks to PaulM for driving
 the issue and providing the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15723 bcc190cf-cafb-0310-a4f2-bffc1f526a37
---
 django/contrib/gis/utils/layermapping.py       |  2 ++
 django/db/models/fields/__init__.py            |  7 +++++--
 docs/internals/deprecation.txt                 | 13 ++++++++++---
 docs/ref/models/fields.txt                     | 17 +++++++++--------
 docs/releases/1.3.txt                          | 18 ++++++++++++++++++
 docs/topics/forms/modelforms.txt               |  3 ---
 .../serializers_regress/models.py              |  6 ------
 .../serializers_regress/tests.py               |  3 ---
 8 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py
index cec1989796..dac53f819b 100644
--- a/django/contrib/gis/utils/layermapping.py
+++ b/django/contrib/gis/utils/layermapping.py
@@ -54,6 +54,8 @@ class LayerMapping(object):
         models.TextField : OFTString,
         models.URLField : OFTString,
         USStateField : OFTString,
+        # This is a reminder that XMLField is deprecated
+        # and this needs to be removed in 1.4
         models.XMLField : OFTString,
         models.SmallIntegerField : (OFTInteger, OFTReal, OFTString),
         models.PositiveSmallIntegerField : (OFTInteger, OFTReal, OFTString),
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index fd0a295483..8081cf3954 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -206,8 +206,8 @@ class Field(object):
         #
         # A Field class can implement the get_internal_type() method to specify
         # which *preexisting* Django Field class it's most similar to -- i.e.,
-        # an XMLField is represented by a TEXT column type, which is the same
-        # as the TextField Django field type, which means XMLField's
+        # a custom field might be represented by a TEXT column type, which is the
+        # same as the TextField Django field type, which means the custom field's
         # get_internal_type() returns 'TextField'.
         #
         # But the limitation of the get_internal_type() / data_types approach
@@ -1136,6 +1136,9 @@ class XMLField(TextField):
     description = _("XML text")
 
     def __init__(self, verbose_name=None, name=None, schema_path=None, **kwargs):
+        import warnings
+        warnings.warn("Use of XMLField has been deprecated; please use TextField instead.",
+                      DeprecationWarning)
         self.schema_path = schema_path
         Field.__init__(self, verbose_name, name, **kwargs)
 
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index de62dc025e..95bc25e9d7 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -41,9 +41,10 @@ their deprecation, as per the :ref:`Django deprecation policy
           removed.
 
         * The ``get_db_prep_save``, ``get_db_prep_value`` and
-          ``get_db_prep_lookup`` methods on Field were modified in 1.2 to support
-          multiple databases. In 1.4, the support functions that allow methods
-          with the old prototype to continue working will be removed.
+          ``get_db_prep_lookup`` methods on Field were modified in 1.2
+          to support multiple databases. In 1.4, the support functions
+          that allow methods with the old prototype to continue
+          working will be removed.
 
         * The ``Message`` model (in ``django.contrib.auth``), its related
           manager in the ``User`` model (``user.message_set``), and the
@@ -105,6 +106,12 @@ their deprecation, as per the :ref:`Django deprecation policy
           with a trailing slash to ensure there is a consistent way to
           combine paths in templates.
 
+        * ``django.db.models.fields.XMLField`` will be removed. This was
+          deprecated as part of the 1.3 release. An accelerated deprecation
+          schedule has been used because the field hasn't performed any role
+          beyond that of a simple ``TextField`` since the removal of oldforms.
+          All uses of ``XMLField`` can be replaced with ``TextField``.
+
     * 1.5
         * The ``mod_python`` request handler has been deprecated since the 1.3
           release. The ``mod_wsgi`` handler should be used instead.
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 38a7a10f2a..66bd04791b 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -12,7 +12,7 @@ This document contains all the gory details about all the `field options`_ and
 
 .. seealso::
 
-    If the built-in fields don't do the trick, you can try 
+    If the built-in fields don't do the trick, you can try
     :mod:`django.contrib.localflavor`, which contains assorted pieces of code
     that are useful for particular countries or cultures. Also, you can easily
     :doc:`write your own custom model fields </howto/custom-model-fields>`.
@@ -462,7 +462,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
 
     For more information about the differences between the
     :class:`FloatField` and :class:`DecimalField` classes, please
-    see :ref:`FloatField vs. DecimalField <floatfield_vs_decimalfield>`. 
+    see :ref:`FloatField vs. DecimalField <floatfield_vs_decimalfield>`.
 
 ``EmailField``
 --------------
@@ -557,7 +557,7 @@ day. If you upload a file on Jan. 15, 2007, it will be saved in the directory
 
 If you wanted to retrieve the uploaded file's on-disk filename, or the file's
 size, you could use the :attr:`~django.core.files.File.name` and
-:attr:`~django.core.files.File.size` attributes respectively; for more 
+:attr:`~django.core.files.File.size` attributes respectively; for more
 information on the available attributes and methods, see the
 :class:`~django.core.files.File` class reference and the :doc:`/topics/files`
 topic guide.
@@ -836,17 +836,18 @@ Like all :class:`CharField` subclasses, :class:`URLField` takes the optional
 ``XMLField``
 ------------
 
+.. deprecated:: 1.3
+   ``XMLField`` is deprecated. Use TextField instead.
+
 .. class:: XMLField(schema_path=None, [**options])
 
-A :class:`TextField` that checks that the value is valid XML that matches a
-given schema. Takes one required argument:
+A :class:`TextField` that stores XML data and a path to a schema. Takes one
+optional argument:
 
 .. attribute:: schema_path
 
-    The filesystem path to a RelaxNG_ schema against which to validate the
-    field.
+    The filesystem path to a schema for the field.
 
-.. _RelaxNG: http://www.relaxng.org/
 
 Relationship fields
 ===================
diff --git a/docs/releases/1.3.txt b/docs/releases/1.3.txt
index 66f78ba0c4..4b6d8d9c06 100644
--- a/docs/releases/1.3.txt
+++ b/docs/releases/1.3.txt
@@ -843,3 +843,21 @@ migration. In Django 1.3, the ``PermWrapper`` class has also been
 moved to ``django.contrib.auth.context_processors``, along with the
 ``PermLookupDict`` support class. The new classes are functionally
 identical to their old versions; only the module location has changed.
+
+Removal of ``XMLField``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+When Django was first released, Django included an ``XMLField`` that
+performed automatic XML validation for any field input. However, this
+validation function hasn't been performed since the introduction of
+``newforms``, prior to the 1.0 release. As a result, ``XMLField`` as
+currently implemented is functionally indistinguishable from a simple
+``TextField``.
+
+For this reason, Django 1.3 has fast-tracked the deprecation of
+``XMLField`` -- instead of a two-release deprecation, ``XMLField``
+will be removed entirely in Django 1.4.
+
+It's easy to update your code to accommodate this change -- just
+replace all uses of ``XMLField`` with ``TextField``, and remove the
+``schema_path`` keyword argument (if it is specified).
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 979eb421a0..99164ecdae 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -106,9 +106,6 @@ the full list of conversions:
 
     ``URLField``                     ``URLField`` with ``verify_exists`` set
                                      to the model field's ``verify_exists``
-
-    ``XMLField``                     ``CharField`` with
-                                     ``widget=forms.Textarea``
     ===============================  ========================================
 
 .. versionadded:: 1.2
diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
index bec0a98202..3a2c81acef 100644
--- a/tests/regressiontests/serializers_regress/models.py
+++ b/tests/regressiontests/serializers_regress/models.py
@@ -79,9 +79,6 @@ class TimeData(models.Model):
 class USStateData(models.Model):
     data = USStateField(null=True)
 
-class XMLData(models.Model):
-    data = models.XMLField(null=True)
-
 class Tag(models.Model):
     """A tag on an item."""
     data = models.SlugField()
@@ -218,9 +215,6 @@ class SmallPKData(models.Model):
 class USStatePKData(models.Model):
     data = USStateField(primary_key=True)
 
-# class XMLPKData(models.Model):
-#     data = models.XMLField(primary_key=True)
-
 class ComplexModel(models.Model):
     field1 = models.CharField(max_length=10)
     field2 = models.CharField(max_length=10)
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index 4180143e21..20581176ab 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -222,9 +222,6 @@ The end."""),
     (data_obj, 180, USStateData, "MA"),
     (data_obj, 181, USStateData, None),
     (data_obj, 182, USStateData, ""),
-    (data_obj, 190, XMLData, "<foo></foo>"),
-    (data_obj, 191, XMLData, None),
-    (data_obj, 192, XMLData, ""),
 
     (generic_obj, 200, GenericData, ['Generic Object 1', 'tag1', 'tag2']),
     (generic_obj, 201, GenericData, ['Generic Object 2', 'tag2', 'tag3']),