Opened 17 years ago
Closed 17 years ago
#5868 closed (fixed)
Newforms ErrorDict serialization problem
Reported by: | tangerine | Owned by: | nobody |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Keywords: | serialization newforms JSON | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
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 (1)
Change History (5)
by , 17 years ago
Attachment: | serialization_example.py added |
---|
comment:1 by , 17 years ago
Triage Stage: | Unreviewed → Design decision needed |
---|
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"]'
comment:2 by , 17 years ago
Triage Stage: | Design decision needed → 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.
comment:3 by , 17 years ago
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.
comment:4 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Sample