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

Django会话,处理日期时间类型,django,session,Django,Session,我正在使用当前django项目中的会话,最近得到一个类型为“date”的对象不可JSON序列化“错误-由于下面的move_in_date字段 通过将以下模型的模型表单保存到会话时: if form.is_valid(): request.session.update(form.cleaned_data) 我的模型: class Address(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL

我正在使用当前django项目中的会话,最近得到一个类型为“date”的
对象不可JSON序列化“
错误-由于下面的
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\u SERIALIZER=DjangoJSONEncoder
的设置来处理日期时间(这应该是序列化程序而不是编码器吗?),但尝试该操作或
SESSION\u SERIALIZER=pickle SERIALIZER
都会给出一个属性错误-。。。没有属性“rsplit”

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

使用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'

有几件事情让你感到困惑:

  • 设置序列化程序时,不要提供类引用,而是提供虚线部分。这可以从错误中看出: 模块路径,类名称=点路径.rsplit('.',1)

  • DjangoJSONEncoder不是序列化程序的正确修复程序。文档中引用了它,作为在将模型放入会话之前序列化模型的一种方法
  • 如果您想创建一个智能序列化程序,那么您仍然需要创建一个序列化程序,它应该支持
    转储
    加载
    接口,分别利用和
  • Pickle序列化程序可以很好地工作,但是正如前面所说的,您需要提供
  • 如果您想使用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')
    

    包括错误的完整错误回溯。哪个序列化程序导致此错误?你也可以发布吗?感谢stacktrace更新,我想它使用了默认的
    JSONSerializer
    ,它不支持datetime对象。默认的JSONSerializer将无法工作。您必须为此创建自己的序列化程序。感谢文档提到DjangoJSONEncoder可用于该序列化程序,并且尝试使用PickerSerializer都会导致属性错误?感谢是否有一个标准解码器与json.loads一起使用,该解码器也可以支持日期时间?没有,但这是因为json没有日期时间类型。有关更多信息和可能的解决方案,请参阅。谢谢,太好了