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