django object is not JSON serializable error after upgrading django to 1.6.5
Asked Answered
M

3

11

I have a django app which was running on 1.4.2 version and working completely fine, but recently i updated it to django 1.6.5 and facing some wierd errors like below

Actually i am getting this during user/client registration process in my site functionality

Request URL:    http://example.com/client/registration/
Django Version:     1.6.5
Exception Type:     TypeError
Exception Value:    <Client: test one> is not JSON serializable
Exception Location:     /usr/lib/python2.7/json/encoder.py in default, line 184
Python Executable:  /home/user/.virtualenvs/test_proj/bin/python
Python Version:     2.7.5

traceback

Traceback:
File "/home/user/.virtualenvs/test_proj/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  199.                 response = middleware_method(request, response)
File "/home/user/.virtualenvs/test_proj/local/lib/python2.7/site-packages/django/contrib/sessions/middleware.py" in process_response
  38.                     request.session.save()
File "/home/user/.virtualenvs/test_proj/local/lib/python2.7/site-packages/django/contrib/sessions/backends/db.py" in save
  57.             session_data=self.encode(self._get_session(no_load=must_create)),
File "/home/user/.virtualenvs/test_proj/local/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py" in encode
  87.         serialized = self.serializer().dumps(session_dict)
File "/home/user/.virtualenvs/test_proj/local/lib/python2.7/site-packages/django/core/signing.py" in dumps
  88.         return json.dumps(obj, separators=(',', ':')).encode('latin-1')
File "/usr/lib/python2.7/json/__init__.py" in dumps
  250.         sort_keys=sort_keys, **kw).encode(obj)
File "/usr/lib/python2.7/json/encoder.py" in encode
  207.         chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py" in iterencode
  270.         return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py" in default
  184.         raise TypeError(repr(o) + " is not JSON serializable")

Exception Type: TypeError at /client/registration/
Exception Value: <Client: test one> is not JSON serializable

I am confused on why the above json error has been appearing after updation and by the way i am using a customized json field in some of my models as below

proj/utils.py

from django.db import models
from django.utils import simplejson as json
from django.core.serializers.json import DjangoJSONEncoder


class JSONField(models.TextField):
    '''JSONField is a generic textfield that neatly serializes/unserializes
    JSON objects seamlessly'''

    # Used so to_python() is called
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        '''Convert our string value to JSON after we load it from the DB'''
        if value == '':
            return None
        try:
            if isinstance(value, basestring):
                return json.loads(value)
        except ValueError:
            pass
        return value

    def get_db_prep_save(self, value, connection=None):
        '''Convert our JSON object to a string before we save'''
        if not value or value == '':
            return None
        if isinstance(value, (dict, list)):
            value = json.dumps(value, mimetype="application/json")
        return super(JSONField, self).get_db_prep_save(value, connection=connection)

from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^proj\.util\.jsonfield\.JSONField"])

settings.py

SERIALIZATION_MODULES = {
     'custom_json': 'proj.util.json_serializer',
        }

json_serializer.py

from django.core.serializers.json import Serializer as JSONSerializer
from django.utils.encoding import is_protected_type

# JSONFields that are normally incorrectly serialized as strings
json_fields = ['field_1', 'field_2']


class Serializer(JSONSerializer):
    """
    A fix on JSONSerializer in order to prevent stringifying JSONField data.
    """
    def handle_field(self, obj, field):
        value = field._get_val_from_obj(obj)
        # Protected types (i.e., primitives like None, numbers, dates,
        # and Decimals) are passed through as is. All other values are
        # converted to string first.
        if is_protected_type(value) or field.name in json_fields:
            self._current[field.name] = value
        else:
            self._current[field.name] = field.value_to_string(obj)

So how to solve the above error ? can some one give me an explanation of what happening to cause the error ?

Mandrill answered 15/6, 2014 at 12:2 Comment(0)
R
45

Django 1.6 changed the serializer from pickle to json. pickle can serialize things that json can't.

You can change the value of SESSION_SERIALIZER in your settings.py to get back the behaviour from Django before version 1.6.

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

You might want to read about session serialization in the documentation.

Roadbed answered 15/6, 2014 at 20:21 Comment(5)
yeah settings this line in settings.py has cleared the issue SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'. ThanksMandrill
what kind of things are not serializable in JSON than in Pickle? ThanksYeargain
@aRkadeFR: For me it was a complex data structure with a lot of own classes.Roadbed
@Roadbed ok, thanks. I chose to go back to Pickle cause security is not a big concern for the current website I'm working on.Yeargain
@aRkadeFR: I am getting this problem with a datetime object aftern an upgrade.Collate
M
6

Setting this line to settings.py will clear the error when upgraded to django 1.6 version

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
Mandrill answered 16/6, 2014 at 9:27 Comment(0)
F
1

After analyzing the traceback, it seems that the JSONEncoder can not serialize the instance of your Client model. Generally, you got such error if you try to serialize a model related to other models (Many2ManyField, etc.) using json or simplejson libraries.

See this https://docs.djangoproject.com/en/dev/topics/serialization/, You can also use some 3rd-party packages such as DjangoRestFramework depending on your needs.

Franchot answered 15/6, 2014 at 12:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.