在Django之上构建了一个API服务器。模型Author
具有DateTimeField
,序列化为iso格式的字符串,例如2015-04-10T07:28:45.571039+00:00
。
class Author(models.Model):
created = models.DateTimeField()
客户端在Javascript中实现。它使用给定的datetime字段构建模型,所以为了更新模型,我想以相同的格式使用字段。
要在服务器端处理请求,有一个模型表单
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
POST / PUT请求处理程序引发异常:“输入有效的日期/时间。”。允许DATETIME_INPUT_FORMATS的原因。内部冒号无法接受时区信息。
鉴于我不想删除时区支持(USE_TZ)并希望接受带有时区信息的数据,实现服务器端的方法是什么?我目前有两个解决方案:1)完全排除字段2)在表单清除方法中使用CharField
函数形式使用dateutil.parser.parse
。
你有什么建议可以解决吗?
答案 0 :(得分:1)
Python(3.7之前的版本)无法使用+00:00处理ISO8601字符串。具体而言,冒号就是问题(参见:https://bugs.python.org/issue15873,https://bugs.python.org/msg169952)。但是,Django通过django.utils.dateparse.parse_datetime
提供解决方案(参见:https://stackoverflow.com/a/30449246/5043802)
要解决此问题,您可以推出自己的使用parse_datetime
的DateTimeField。
https://gist.github.com/elnygren/da7a1b7496a598f95bc8d8277f420b2d
from django import forms
from django.utils.dateparse import parse_datetime
from django.utils.encoding import force_str
from django.forms.widgets import DateTimeInput
from django.utils.translation import gettext_lazy as _, ngettext_lazy
class ISODateTimeField(forms.Field):
"""DateTimeField that uses django.utils.dateparse.parse_datetime.
More precisely, this DateTimeField accepts ISO 8601 datetime strings
that specify timezone with +00:00 syntax.
https://en.wikipedia.org/wiki/ISO_8601
https://code.djangoproject.com/ticket/11385
https://bugs.python.org/issue15873
https://bugs.python.org/msg169952
"""
widget = DateTimeInput
default_error_messages = {
'invalid': _('Enter a valid date/time.'),
}
def to_python(self, value):
value = value.strip()
try:
return self.strptime(value, format)
except (ValueError, TypeError):
raise forms.ValidationError(self.error_messages['invalid'], code='invalid')
def strptime(self, value, format):
return parse_datetime(force_str(value))
答案 1 :(得分:0)
您的存储不太可能接受时区感知日期时间,您的django应用程序是否设置了时区?来自文档:
当启用对时区的支持时,Django会存储日期时间 数据库中的UTC信息使用时区感知日期时间 内部对象,并将它们转换为最终用户的时区 模板和表格。
如果你没有使用postgresql:
其他后端存储没有时区信息的日期时间。如果你 从USE_TZ = False切换到USE_TZ = True,你必须转换你的 从当地时间到UTC的数据 - 如果您的本地时间不确定 时间有DST。
基本上,只是在settings.py
中设置USE_TZ并不是完全没有完成的答案 2 :(得分:0)
我使用@elnygren代码,并且遇到一个错误,该错误的形式是不需要ISODateTimeField字段,它会一直尝试进行验证,我通过以下方式进行了修复:
session()->push()