2014-06-15 18 views
11

Tôi có một ứng dụng django được chạy trên phiên bản 1.4.2 và làm việc hoàn toàn tốt, nhưng gần đây tôi cập nhật nó để django 1.6.5 và phải đối mặt với một số lỗi lạ như dưới đâyđối tượng django không phải là JSON lỗi serializable sau khi nâng cấp django để 1.6.5

trên thực tế tôi đang nhận được này trong quá trình đăng ký người dùng/khách hàng về tính năng trang web của tôi

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 

Tôi đang bối rối về lý do lỗi json trên đã được xuất hiện sau khi updation và bằng cách này tôi đang sử dụng một lĩnh vực json tùy chỉnh trong một số mô hình của tôi như sau

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) 

Vậy làm thế nào để giải quyết lỗi trên? một số có thể cho tôi một lời giải thích về những gì đang xảy ra gây ra lỗi không?

Trả lời

40

Django 1.6 đã thay đổi bộ nối tiếp từ dưa sang json. dưa có thể tuần tự hóa những thứ mà json không thể.

Bạn có thể thay đổi giá trị SESSION_SERIALIZER trong số settings.py để lấy lại hành vi từ Django trước phiên bản 1.6.

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

Bạn có thể muốn đọc khoảng session serialization trong tài liệu.

+5

vâng thiết lập dòng này trong settings.py đã xóa các vấn đề 'SESSION_SERIALIZER = 'django.contrib.sessions.serializers .PickleSerializer''. Cảm ơn –

+0

loại sự kiện nào không thể tuần tự hóa được trong JSON so với trong Pickle? Cảm ơn – aRkadeFR

+0

@aRkadeFR: Đối với tôi đó là một cấu trúc dữ liệu phức tạp với rất nhiều lớp riêng. – Matthias

0

Sau khi phân tích truy nguyên, có vẻ như JSONEncoder không thể tuần tự hóa thể hiện của mô hình Khách hàng của bạn. Nói chung, bạn gặp lỗi như vậy nếu bạn cố gắng sắp xếp một mô hình liên quan đến các mô hình khác (Many2ManyField, v.v.) bằng cách sử dụng các thư viện json hoặc simplejson.

Xem điều này https://docs.djangoproject.com/en/dev/topics/serialization/, Bạn cũng có thể sử dụng một số gói của bên thứ ba như DjangoRestFramework tùy theo nhu cầu của bạn.

5

Thiết dòng này để settings.py sẽ xóa lỗi khi nâng cấp lên phiên bản 1.6 django

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' 
Các vấn đề liên quan