I have a model which contains a DurationField. If positive values are saved in this field, I get the correct result, if negative values are saved it returns "None" if I'm trying to access the attribute of the model.
The model looks like the following:
class Calendar(models.Model):
    nominal_actual_comparison = models.DurationField(null=True,blank = True)
If I'm trying to access it now within a view like the following and the value is negative I'm obtaining a NoneType object:
calendar_object = Calendar.objects.get(id = 1)
calendar_object.nominal_actual_comparison
I looked into the database and saw, that the DurationField is saved as a BigInt. The values in the database are definitely correct, therefore I'm wondering if there is a bug in the implementation of the DurationField or am I doing something wrong? What can I do instead? Is it possible to overwrite the DurationField class to adapt the way how the BigInt gets converted into a datetime.timedelta object? I saw a method called to_python which apparently calls a parse_duration method, but the to_python method is somehow never getting called !?
I hope you can help me, thanks in advance!
I solved this issue in the meantime by overriding the DurationField class.
I had to handle the conversion of the BigInt on my own, therefore I had to overwrite the get_db_converters method because in the original DurationField it calls a method parse_datetime which isn't capable of handling negative values obviously. Moreover I had to overwrite from_db_value to implement my own conversion of the database value.
The code of my DurationField looks like the following now:
class DurationField(DurationField):
def get_db_converters(self, connection):
    if hasattr(self, 'from_db_value'):
        return [self.from_db_value]
    return []
def from_db_value(self, value, expression, connection, context):
    result = ""
    if (value != None):
        d = str(decimal.Decimal(value) / decimal.Decimal(1000000))
        try:
            sec = d.split(".")[0]
            micro_sec = d.split(".")[1]
        except IndexError:
            sec = int(d)
            micro_sec = 0
        result = self.convertSecondsToTimeDelta(seconds = sec, microseconds = micro_sec)
        return result
    else:
        return None
def convertSecondsToTimeDelta(self, seconds = 0 , microseconds = 0):
    return datetime.timedelta(seconds = seconds, microseconds = microseconds)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With