接受 Django 形式的日期时间同格式



Django之上有一个API服务器构建。模型 Author 具有序列化为 iso 格式字符串(如 2015-04-10T07:28:45.571039+00:00 (的DateTimeField

class Author(models.Model):
    created = models.DateTimeField()

客户端是用Javascript实现的。它使用给定的日期时间字段构建模型,因此要更新模型,我想使用相同的格式字段。

为了在服务器端处理请求,有一个模型表单

class AuthorForm(forms.ModelForm):
    class Meta:
        model = Author

POST/PUT 请求处理程序引发异常:"输入有效的日期/时间。原因DATETIME_INPUT_FORMATS允许。无法接受包含冒号的时区信息。

鉴于我不想删除时区支持(USE_TZ(并希望接受带有时区信息的数据,实现服务器端的方法是什么?我目前有两种解决方案:1(全部排除字段2(在表单中使用CharField dateutil.parser.parse并在表单清理方法中使用函数。你有什么建议如何处理吗?

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

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):
            """ stackoverflow won't let me save just an indent! """
            return parse_datetime(force_str(value))

您的存储不太可能接受时区感知日期时间,您的 Django 应用程序是否针对时区进行了设置? 从文档中:

启用时区支持后,Django 会存储日期时间 数据库中的 UTC 信息,使用时区感知日期时间 对象在内部,并将它们转换为最终用户的时区 模板和表单。

另外,如果您不使用PostgreSQL:

其他后端存储没有时区信息的日期时间。如果你 从 USE_TZ = False 切换到 USE_TZ = True,您必须转换您的 从本地时间到 UTC 的数据 - 如果您的本地时间,则不确定 时间有夏令时。

基本上,它并没有完全为您完成,只是在 settings.py 中设置USE_TZ

我使用@elnygren代码,并且我有一个表单错误,即不需要ISODateTimeField字段,它一直尝试验证,我以这种方式修复:

def to_python(self, value):
    if value in self.empty_values:
        return None
    value = value.strip()
    for _format in self.input_formats:
        try:
            return self.strptime(value, _format)
        except (ValueError, TypeError):
            continue
    raise forms.ValidationError(self.error_messages["invalid"], code="invalid")

相关内容

  • 没有找到相关文章

最新更新