Django模型字段中的子类timedelta

时间:2017-08-18 14:36:14

标签: python django

我已经扩展了datetime.timedelta以前的工作来更新除法运算符以支持浮点数(在python 3.x之前不支持)。在我的一个模型中开始使用DurationField后,我想创建一个使用我的扩展timedelta类的自定义版本,以便查询后返回的对象包括我的自定义timedelta类。实现这个的正确方法是什么?

我一直在编辑DurationField类本身,同时我在下一步找出如何添加自定义模型字段之前弄清楚如何执行上述操作。代码如下(modified Django source code

class TimeDeltaExtended(datetime.timedelta):
    def __div__(self, divisor):
        return TimeDeltaExtended(seconds=self.total_seconds()/divisor)

    def __mul__(self, multiplier):
        return TimeDeltaExtended(seconds=self.total_seconds()*multiplier)

    def __add__(self, other):
        if isinstance(other, int) and other is 0:
            return self
        else:
            datetime.timedelta.__add__(other)

class DurationField(Field):
...

    def to_python(self, value):
        if value is None:
            return value
        if isinstance(value, TimeDeltaExtended):
            return value
        try:
            parsed = parse_duration(value)
        except ValueError:
            pass
        else:
            if parsed is not None:
                return parsed

        raise exceptions.ValidationError(
            self.error_messages['invalid'],
            code='invalid',
            params={'value': value},
        )
...

但是,当我使用此代码时,查询仍会返回正常的TimeDelta对象。这甚至是我应该关注的领域吗?

环境Python 2.7,Django 1.11

1 个答案:

答案 0 :(得分:1)

这是duration字段将解析序列化形式timedelta(seconds=123.456)

的方式
>>> DurationField().to_python('00:02:03.456000')
datetime.timedelta(0, 123, 456000)

你可以让超类完成繁琐的验证,异常处理等。只需转换为你的专业类作为后处理步骤:

>>> class MyDurationField(DurationField):
...     def to_python(self, value):
...         timedelta = super(MyDurationField, self).to_python(value)
...         return TimeDeltaExtended(seconds=timedelta.total_seconds())
...     
>>> MyDurationField().to_python('00:02:03.456000')
TimeDeltaExtended(0, 123, 456000)
>>> MyDurationField().to_python('00:02:03.456000') / 2.0
TimeDeltaExtended(0, 61, 728000)