Django会话,处理日期时间类型

时间:2017-08-31 14:09:42

标签: django session

我在当前的django项目中使用会话,最近收到了'Object of type 'date' is not JSON serializable'错误 - 由于下面的move_in_date字段。

通过以下方式将以下模型的模型保存到会话时

if form.is_valid():
        request.session.update(form.cleaned_data)

我的模特:

class Address(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    house_name_number = models.CharField(max_length=255, verbose_name="house name or number")
    street_name = models.CharField(max_length=255)
    town_city = models.CharField(max_length=255)
    county = models.CharField(max_length=255)
    postcode = models.CharField(max_length=8)

    same_address = models.BooleanField() 
    move_in_date = models.DateField(null=True, blank=True)

我已经尝试使用文档建议的DjangoJSONEncoder来解决问题,这可以通过SESSION_SERIALIZER=DjangoJSONEncoder的设置处理日期时间(这应该是序列化程序而不是编码器? ),但尝试或SESSION_SERIALIZER=PickleSerializer都给出属性错误 - ...没有属性’'

此外,我在使用django向导之前存储了会话中的中间数据(例如导致上述日期问题的字段)。我现在已经切换应用程序的这一部分以使用单独的视图来获得灵活性(因为注册不仅仅是一个线性路径),django向导没有这个问题,它是如何解决这个问题的?

使用stacktrace

更新
Traceback (most recent call last):
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/deprecation.py", line 142, in __call__
    response = self.process_response(request, response)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/middleware.py", line 58, in process_response
    request.session.save()
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 83, in save
    obj = self.create_model_instance(data)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 69, in create_model_instance
    session_data=self.encode(data),
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 98, in encode
    serialized = self.serializer().dumps(session_dict)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/signing.py", line 93, in dumps
    return json.dumps(obj, separators=(',', ':')).encode('latin-1')
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/Cellar/python3/3.6.0/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'date' is not JSON serializable

用于尝试DjangoJSONEncoder的堆栈跟踪:

Traceback (most recent call last):
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/deprecation.py", line 138, in __call__
    response = self.process_request(request)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/middleware.py", line 20, in process_request
    request.session = self.SessionStore(session_key)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/db.py", line 18, in __init__
    super(SessionStore, self).__init__(session_key)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/contrib/sessions/backends/base.py", line 51, in __init__
    self.serializer = import_string(settings.SESSION_SERIALIZER)
  File "/Users/Barclay/.virtualenvs/switcher5/lib/python3.6/site-packages/django/utils/module_loading.py", line 15, in import_string
    module_path, class_name = dotted_path.rsplit('.', 1)
AttributeError: type object 'DjangoJSONEncoder' has no attribute 'rsplit'

1 个答案:

答案 0 :(得分:1)

一些混乱的事情正在打击你:

  1. 设置序列化程序时,请勿提供类引用,而应提供虚线部分。这在错误中可见:
      

    module_path,class_name = dotted_pa​​th.rsplit('。',1)

  2. DjangoJSONEncoder不是串行器的正确修复程序。它在文档中被引用为序列化模型之前将它们放入会话。
  3. 如果您想制作智能序列化程序,那么您仍然需要创建一个序列化程序,它应该支持dumpsloads接口,该接口利用JsonEncoder和{{3}分别。
  4. Pickle序列化程序可以正常工作,但正如您所说,您需要提供JsonDecoder
  5. 如果你想使用JSON作为序列化器,那么这可能是一个好的开始:

    from django.core.serializers.json import DjangoJSONEncoder
    from django.core.signing import JSONSerializer as BaseJSONSerializer
    
    
    class SmartJSONSerializer(BaseJSONSerializer):
        def dumps(self, obj):
            return json.dumps(obj, separators=(',', ':'), cls=DjangoJSONEncoder).encode('latin-1')