Django

Code

Ticket #5868 (closed: fixed)

Opened 3 years ago

Last modified 3 years ago

Newforms ErrorDict serialization problem

Reported by: tangerine Assigned to: nobody
Milestone: Component: Forms
Version: SVN Keywords: serialization newforms JSON
Cc: Triage Stage: Accepted
Has patch: 0 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

Around r6625 a bug has been introduced whereby an attempt to serialize a ErrorDict? instance will fail and throw a TypeError?, complaining of not being able to serialize a proxy object e.g. something like django.utils.functional.__proxy__ object at 0xdeecd0> is not JSON serializable . I have attached some sample code to illustrate the problem.

Attachments

serialization_example.py (408 bytes) - added by tangerine on 11/03/07 12:03:02.
Sample

Change History

11/03/07 12:03:02 changed by tangerine

  • attachment serialization_example.py added.

Sample

11/03/07 19:49:00 changed by gwilson

  • needs_better_patch changed.
  • stage changed from Unreviewed to Design decision needed.
  • needs_tests changed.
  • needs_docs changed.

Yes, r6625 turned all newforms error messages into lazy strings, which aren't supported by the default JSONEncoder:

>>> from django.utils import simplejson
>>> simplejson.dumps(ugettext_lazy('hello world'))
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/home/gdub/bzr/django/upstream/django/utils/simplejson/__init__.py", line 181, in dumps
    separators=separators,
  File "/home/gdub/bzr/django/upstream/django/utils/simplejson/encoder.py", line 312, in encode
    chunks = list(self.iterencode(o))
  File "/home/gdub/bzr/django/upstream/django/utils/simplejson/encoder.py", line 273, in _iterencode
    for chunk in self._iterencode_default(o, markers):
  File "/home/gdub/bzr/django/upstream/django/utils/simplejson/encoder.py", line 279, in _iterencode_default
    newobj = self.default(o)
  File "/home/gdub/bzr/django/upstream/django/utils/simplejson/encoder.py", line 300, in default
    raise TypeError("%r is not JSON serializable" % (o,))
TypeError: <django.utils.functional.__proxy__ object at 0x892378c> is not JSON serializable

The JSONEncoder docstring states:

    To extend this to recognize other objects, subclass and implement a
    ``.default()`` method with another method that returns a serializable
    object for ``o`` if possible, otherwise it should call the superclass
    implementation (to raise ``TypeError``).

Looks like we might want to do this since lazy strings are used in several places throughout Django. Here's a quick and dirty one that works:

from django.utils.functional import Promise
from django.utils.translation import force_unicode
from django.utils.simplejson import JSONEncoder

class LazyEncoder(JSONEncoder):
    def default(self, o):
        if isinstance(o, Promise):
            return force_unicode(o)
        else:
            return super(LazyEncoder, self).default(o)
>>> simplejson.dumps(ugettext_lazy('hello world'), cls=LazyEncoder)
'"hello world"'
>>> simplejson.dumps([1, 2, ugettext_lazy('hi')], cls=LazyEncoder)
'[1, 2, "hi"]'

11/03/07 20:39:31 changed by mtredinnick

  • stage changed from Design decision needed to Accepted.

We shouldn't add this code by default, since it's usually going to be unnecessary overhead. It somebody's going to use simplejson directly, they will need to write such a class if there's a chance they are dumping lazy translation objects. I'll update the docs.

I will add something to Django's core serializers to handle the analogous case over there, though.

11/03/07 20:58:13 changed by mtredinnick

Hmm .. on second thoughts, I can't see how we'd ever end up sending a lazy translation object to Django's serializers, so it's not necessary there.

11/03/07 21:08:24 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(In [6645]) Fixed #5868 -- Provided an example of how to extend simplejson to serialize lazy translation objects for those who want to use it directly.


Add/Change #5868 (Newforms ErrorDict serialization problem)




Change Properties
Action