【问题标题】:How to make a class JSON serializable for usage in Django session如何使类 JSON 可序列化以在 Django 会话中使用
【发布时间】:2019-06-06 22:37:00
【问题描述】:

我尝试在 Django 会话中存储以下几乎任意的类:

class QuizInfo:
    def __init__(self):
        self.i_active_question = INVALID_PQA_ID  # integer
        self.sequence = []

反过来,QuizInfo.sequence 列表的每一项都是AnsweredQuestion 的一个实例:

class AnsweredQuestion:
    def __init__(self, i_question, i_answer):
        self.i_question = i_question
        self.i_answer = i_answer

我尝试将这样的数据结构存储在HttpRequest.session 中,如下所示:

qi = QuizInfo()
qi.i_active_question = 5  # e.g.
qi.sequence.append(AnsweredQuestion(1, 2))  # e.g.
qi.sequence.append(AnsweredQuestion(3, 4))  # e.g.
quiz_id = 7  # e.g.
request.session['quiz_infos'] = {quiz_id : qi}

所以request.session['quiz_infos']int 键和QuizInfo 值的字典。

我收到以下错误:

Traceback:

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\utils\deprecation.py" in __call__
  93.             response = self.process_response(request, response)

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\contrib\sessions\middleware.py" in process_response
  58.                             request.session.save()

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\contrib\sessions\backends\db.py" in save
  83.         obj = self.create_model_instance(data)

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\contrib\sessions\backends\db.py" in create_model_instance
  70.             session_data=self.encode(data),

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\contrib\sessions\backends\base.py" in encode
  96.         serialized = self.serializer().dumps(session_dict)

File "C:\Users\Sarge\Envs\PqaWeb1\lib\site-packages\django\core\signing.py" in dumps
  87.         return json.dumps(obj, separators=(',', ':')).encode('latin-1')

File "c:\programs\python37\Lib\json\__init__.py" in dumps
  238.         **kw).encode(obj)

File "c:\programs\python37\Lib\json\encoder.py" in encode
  199.         chunks = self.iterencode(o, _one_shot=True)

File "c:\programs\python37\Lib\json\encoder.py" in iterencode
  257.         return _iterencode(o, 0)

File "c:\programs\python37\Lib\json\encoder.py" in default
  179.         raise TypeError(f'Object of type {o.__class__.__name__} '

Exception Type: TypeError at /
Exception Value: Object of type QuizInfo is not JSON serializable

如何使数据结构 JSON 可序列化?

我看到了其他问题,但是,那里的答案大多建议实现一种方法作为参数传递。但是在 Django 中哪里可以做到这一点呢?

【问题讨论】:

    标签: python json django session serialization


    【解决方案1】:

    使用__dict__ 将其更改为字典。在您的情况下,尽管您有嵌套对象,也需要将其转换为字典。这可以在 jsbueno 答案here 中找到。基本上你必须遍历你的对象来检查嵌套对象,

    def my_dict(obj):
       if not  hasattr(obj,"__dict__"):
           return obj
       result = {}
       for key, val in obj.__dict__.items():
           if key.startswith("_"):
               continue
           element = []
           if isinstance(val, list):
               for item in val:
                   element.append(my_dict(item))
           else:
               element = my_dict(val)
           result[key] = element
       return result
    

    编辑:

    然后你可以像这样将结果转储到一个字符串中,

    import json
    
    json.dumps(result)
    

    希望这会有所帮助!

    【讨论】:

    • 那么如何反序列化这样的结构呢?
    • 使用 json.dumps(result) 会给你一个字符串。
    【解决方案2】:

    Here 是一种可能的解决方案。

    在序列化/反序列化数据方面,Django 的序列化程序非常方便。

    您也可以关注this。 另请查看deserialization

    【讨论】:

      猜你喜欢
      • 2019-06-17
      • 2020-04-22
      • 2011-04-15
      • 2011-11-18
      • 1970-01-01
      • 2014-07-07
      • 2013-11-13
      相关资源
      最近更新 更多