+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

强制执行严格的字段。日期格式带有棉花糖反序列化

发布于2020-07-02 21:46     阅读(326)     评论(0)     点赞(23)     收藏(2)


我正在为Flask项目使用Marshmallow 2.15.3,并想强制使用严格的Date和DateTime格式。严格来说,我的意思是我只想接受与以下格式相同的字符串。我遇到的是在处理Date和DateTime方面的一些区别。格式:

DATE_FORMAT = '%Y-%m-%d'
DATETIME_FORMAT = '%Y-%m-%dT%H:%M:%S'

例如,使用DateTime,我可以执行以下操作:

dt = fields.DateTime(format=DATETIME_FORMAT)
dt.deserialize('2018-01-01')  # fails, as desired
dt.deserialize('2018-01-01T05:06:08.012312+02:00')  # fails, as desired
dt.deserialize('2018-01-01T05:06:08')  # works, as desired and according to format

使用日期,我可以执行以下操作:

d = fields.Date() # does not accept format argument
d.deserialize('2018-01')  # fails, as desired
d.deserialize('2018-01-01T05:06:08.012312+02:00')  # works, NOT as desired
d.deserialize('2018-01-01')  # works, as desired and according to format

虽然DateTime不允许额外的信息,但Date允许它。据我了解format,“日期”字段没有任何论据。我有什么办法可以解决类似功能的问题,并对太短和太长的输入值都强制执行严格的格式?


解决方案


对于面向未来的代码,我发现Date棉花糖3.0.0b17中的类现在是的子类,DateTime而不是Field,使它继承了formatkwarg(相关的commit)。

对于2.15.3和(通常为2.XX)版本,我无法找到任何内置函数。一种解决方法是对fields.Date进行猴子修补经过修改,它看起来像这样:

class Date(Field):
    """ISO8601-formatted date string.

    :param kwargs: The same keyword arguments that :class:`Field` receives.
    """
    default_error_messages = {
        'invalid': 'Not a valid date.',
        'format': '"{input}" cannot be formatted as a date.',
    }

    def __init__(self, format=None, **kwargs):
        super(Date, self).__init__(**kwargs)
        self.dateformat = format

    def _serialize(self, value, attr, obj):
        if value is None:
            return None
        try:
            return value.isoformat()
        except AttributeError:
            self.fail('format', input=value)
        return value

    def _deserialize(self, value, attr, data):
        """Deserialize an ISO8601-formatted date string to a
        :class:`datetime.date` object.
        """
        if not value:  # falsy values are invalid
            self.fail('invalid')
        elif self.dateformat:
            try:
                return dt.datetime.strptime(value, self.dateformat).date()
            except (TypeError, AttributeError, ValueError):
                raise self.fail('invalid')
        try:
            return utils.from_iso_date(value)
        except (AttributeError, TypeError, ValueError):
            self.fail('invalid')

此处的修改是__init__定义的添加,并在_deserialize整个- elif self.dateformat子句添加了。这使我可以使用提交的格式反序列化,例如:

d = fields.Date('%Y-%m-%d') # now accepts a format
d.deserialize('2018-01-01T05:06:08.012312+02:00')  # fails, as desired


所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接: https://www.pythonheidong.com/blog/article/433203/

来源: python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

23 0
收藏该文
已收藏

评论内容:(最多支持255个字符)