浏览代码

Fixed #15889 -- when trying to access to access a serializer that doesn't exist, raise a new SerializerDoesNotExist exception. Thanks to Mathieu Agopian for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16104 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Alex Gaynor 14 年之前
父节点
当前提交
930371e91b

+ 1 - 0
AUTHORS

@@ -35,6 +35,7 @@ answer newbie questions, and generally made Django that much better:
 
 
     Gisle Aas <gisle@aas.no>
     Gisle Aas <gisle@aas.no>
     Chris Adams
     Chris Adams
+    Mathieu Agopian <mathieu.agopian@gmail.com>
     ajs <adi@sieker.info>
     ajs <adi@sieker.info>
     alang@bright-green.com
     alang@bright-green.com
     A S Alam <aalam@users.sf.net>
     A S Alam <aalam@users.sf.net>

+ 7 - 0
django/core/serializers/__init__.py

@@ -18,6 +18,7 @@ To add your own serializers, use the SERIALIZATION_MODULES setting::
 
 
 from django.conf import settings
 from django.conf import settings
 from django.utils import importlib
 from django.utils import importlib
+from django.core.serializers.base import SerializerDoesNotExist
 
 
 # Built-in serializers
 # Built-in serializers
 BUILTIN_SERIALIZERS = {
 BUILTIN_SERIALIZERS = {
@@ -60,11 +61,15 @@ def unregister_serializer(format):
     "Unregister a given serializer. This is not a thread-safe operation."
     "Unregister a given serializer. This is not a thread-safe operation."
     if not _serializers:
     if not _serializers:
         _load_serializers()
         _load_serializers()
+    if format not in _serializers:
+        raise SerializerDoesNotExist(format)
     del _serializers[format]
     del _serializers[format]
 
 
 def get_serializer(format):
 def get_serializer(format):
     if not _serializers:
     if not _serializers:
         _load_serializers()
         _load_serializers()
+    if format not in _serializers:
+        raise SerializerDoesNotExist(format)
     return _serializers[format].Serializer
     return _serializers[format].Serializer
 
 
 def get_serializer_formats():
 def get_serializer_formats():
@@ -80,6 +85,8 @@ def get_public_serializer_formats():
 def get_deserializer(format):
 def get_deserializer(format):
     if not _serializers:
     if not _serializers:
         _load_serializers()
         _load_serializers()
+    if format not in _serializers:
+        raise SerializerDoesNotExist(format)
     return _serializers[format].Deserializer
     return _serializers[format].Deserializer
 
 
 def serialize(format, queryset, **options):
 def serialize(format, queryset, **options):

+ 4 - 0
django/core/serializers/base.py

@@ -8,6 +8,10 @@ from django.db import models
 from django.utils.encoding import smart_str, smart_unicode
 from django.utils.encoding import smart_str, smart_unicode
 from django.utils import datetime_safe
 from django.utils import datetime_safe
 
 
+class SerializerDoesNotExist(KeyError):
+    """The requested serializer was not found."""
+    pass
+
 class SerializationError(Exception):
 class SerializationError(Exception):
     """Something bad happened during serialization."""
     """Something bad happened during serialization."""
     pass
     pass

+ 6 - 0
docs/topics/serialization.txt

@@ -38,6 +38,12 @@ This is useful if you want to serialize data directly to a file-like object
     out = open("file.xml", "w")
     out = open("file.xml", "w")
     xml_serializer.serialize(SomeModel.objects.all(), stream=out)
     xml_serializer.serialize(SomeModel.objects.all(), stream=out)
 
 
+.. note::
+
+    Calling :func:`~django.core.serializers.get_serializer` with an unknown
+    :ref:`format <serialization-formats>` will raise a
+    :class:`~django.core.serializers.SerializerDoesNotExist` exception.
+
 Subset of fields
 Subset of fields
 ~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~
 
 

+ 24 - 2
tests/regressiontests/serializers_regress/tests.py

@@ -6,7 +6,7 @@ test case that is capable of testing the capabilities of
 the serializers. This includes all valid data values, plus
 the serializers. This includes all valid data values, plus
 forward, backwards and self references.
 forward, backwards and self references.
 """
 """
-
+from __future__ import with_statement
 
 
 import datetime
 import datetime
 import decimal
 import decimal
@@ -17,6 +17,7 @@ except ImportError:
 
 
 from django.conf import settings
 from django.conf import settings
 from django.core import serializers, management
 from django.core import serializers, management
+from django.core.serializers import SerializerDoesNotExist
 from django.db import transaction, DEFAULT_DB_ALIAS, connection
 from django.db import transaction, DEFAULT_DB_ALIAS, connection
 from django.test import TestCase
 from django.test import TestCase
 from django.utils.functional import curry
 from django.utils.functional import curry
@@ -350,7 +351,28 @@ if connection.features.allows_primary_key_0:
 # Dynamically create serializer tests to ensure that all
 # Dynamically create serializer tests to ensure that all
 # registered serializers are automatically tested.
 # registered serializers are automatically tested.
 class SerializerTests(TestCase):
 class SerializerTests(TestCase):
-    pass
+    def test_get_unknown_serializer(self):
+        """
+        #15889: get_serializer('nonsense') raises a SerializerDoesNotExist
+        """
+        with self.assertRaises(SerializerDoesNotExist):
+            serializers.get_serializer("nonsense")
+
+        with self.assertRaises(KeyError):
+            serializers.get_serializer("nonsense")
+
+        # SerializerDoesNotExist is instantiated with the nonexistent format
+        with self.assertRaises(SerializerDoesNotExist) as cm:
+            serializers.get_serializer("nonsense")
+        self.assertEqual(cm.exception.args, ("nonsense",))
+
+    def test_unregister_unkown_serializer(self):
+        with self.assertRaises(SerializerDoesNotExist):
+            serializers.unregister_serializer("nonsense")
+
+    def test_get_unkown_deserializer(self):
+        with self.assertRaises(SerializerDoesNotExist):
+            serializers.get_deserializer("nonsense")
 
 
 def serializerTest(format, self):
 def serializerTest(format, self):