mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #15091 -- Allowed passing custom encoder to JSON serializer.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						parent
						
							6bf7964023
						
					
				
				
					commit
					c1b6f554e4
				
			| @@ -37,6 +37,7 @@ class Serializer(PythonSerializer): | ||||
|         if self.options.get('indent'): | ||||
|             # Prevent trailing spaces | ||||
|             self.json_kwargs['separators'] = (',', ': ') | ||||
|         self.json_kwargs.setdefault('cls', DjangoJSONEncoder) | ||||
|  | ||||
|     def start_serialization(self): | ||||
|         self._init_options() | ||||
| @@ -58,8 +59,7 @@ class Serializer(PythonSerializer): | ||||
|                 self.stream.write(" ") | ||||
|         if indent: | ||||
|             self.stream.write("\n") | ||||
|         json.dump(self.get_dump_object(obj), self.stream, | ||||
|                   cls=DjangoJSONEncoder, **self.json_kwargs) | ||||
|         json.dump(self.get_dump_object(obj), self.stream, **self.json_kwargs) | ||||
|         self._current = None | ||||
|  | ||||
|     def getvalue(self): | ||||
|   | ||||
| @@ -206,6 +206,10 @@ Serialization | ||||
| * The new ``django.core.serializers.base.Serializer.stream_class`` attribute | ||||
|   allows subclasses to customize the default stream. | ||||
|  | ||||
| * The encoder used by the :ref:`JSON serializer <serialization-formats-json>` | ||||
|   can now be customized by passing a ``cls`` keyword argument to the | ||||
|   ``serializers.serialize()`` function. | ||||
|  | ||||
| Signals | ||||
| ~~~~~~~ | ||||
|  | ||||
|   | ||||
| @@ -265,6 +265,17 @@ work:: | ||||
|                 return force_text(obj) | ||||
|             return super(LazyEncoder, self).default(obj) | ||||
|  | ||||
| You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()`` | ||||
| function:: | ||||
|  | ||||
|     from django.core.serializers import serialize | ||||
|  | ||||
|     serialize('json', SomeModel.objects.all(), cls=LazyEncoder) | ||||
|  | ||||
| .. versionchanged:: 1.11 | ||||
|  | ||||
|     The ability to use a custom encoder using ``cls=...`` was added. | ||||
|  | ||||
| Also note that GeoDjango provides a :doc:`customized GeoJSON serializer | ||||
| </ref/contrib/gis/serializers>`. | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,16 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import decimal | ||||
| import json | ||||
| import re | ||||
|  | ||||
| from django.core import serializers | ||||
| from django.core.serializers.base import DeserializationError | ||||
| from django.core.serializers.json import DjangoJSONEncoder | ||||
| from django.db import models | ||||
| from django.test import SimpleTestCase, TestCase, TransactionTestCase | ||||
| from django.test.utils import isolate_apps | ||||
| from django.utils.translation import override, ugettext_lazy | ||||
|  | ||||
| from .models import Score | ||||
| @@ -80,6 +83,23 @@ class JsonSerializerTestCase(SerializersTestBase, TestCase): | ||||
|             if re.search(r'.+,\s*$', line): | ||||
|                 self.assertEqual(line, line.rstrip()) | ||||
|  | ||||
|     @isolate_apps('serializers') | ||||
|     def test_custom_encoder(self): | ||||
|         class ScoreDecimal(models.Model): | ||||
|             score = models.DecimalField() | ||||
|  | ||||
|         class CustomJSONEncoder(json.JSONEncoder): | ||||
|             def default(self, o): | ||||
|                 if isinstance(o, decimal.Decimal): | ||||
|                     return str(o) | ||||
|                 return super(CustomJSONEncoder, self).default(o) | ||||
|  | ||||
|         s = serializers.json.Serializer() | ||||
|         json_data = s.serialize( | ||||
|             [ScoreDecimal(score=decimal.Decimal(1.0))], cls=CustomJSONEncoder | ||||
|         ) | ||||
|         self.assertIn('"fields": {"score": "1"}', json_data) | ||||
|  | ||||
|     def test_json_deserializer_exception(self): | ||||
|         with self.assertRaises(DeserializationError): | ||||
|             for obj in serializers.deserialize("json", """[{"pk":1}"""): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user