2015-12-03 14 views
6

Mam model, który zawiera DurationField. Jeśli w tym polu zostaną zapisane wartości dodatnie, otrzymam poprawny wynik, jeśli wartości ujemne zostaną zapisane, zwróci "Brak", jeśli próbuję uzyskać dostęp do atrybutu modelu.Django Czas trwania Pole z wartością ujemną

Model wygląda następująco:

class Calendar(models.Model): 
    nominal_actual_comparison = models.DurationField(null=True,blank = True) 

Jeśli próbuję teraz do niego dostęp w widoku jak na poniższej ilustracji, a wartość jest ujemna mam uzyskania NoneType obiektu:

calendar_object = Calendar.objects.get(id = 1) 
calendar_object.nominal_actual_comparison 

Zajrzałem do bazy danych i zobaczyłem, że DurationField jest zapisany jako BigInt. Wartości w bazie danych są zdecydowanie poprawne, dlatego zastanawiam się, czy istnieje błąd w implementacji DurationField, czy też robię coś nie tak? Co mogę zamiast tego zrobić? Czy jest możliwe zastąpienie klasy DurationField, aby dostosować sposób przekształcania BigInt w obiekt datetime.timedelta? Widziałem metodę o nazwie to_python, która najwyraźniej nazywa się metodą parse_duration, ale metoda to_python nigdy nie jest wywoływana! Mam nadzieję, że możesz mi pomóc, z góry dzięki!

Odpowiedz

1

Rozwiązałem ten problem w międzyczasie, zastępując klasę DurationField. Musiałem samodzielnie przetworzyć konwersję BigInt, dlatego musiałem nadpisać metodę get_db_converters, ponieważ w oryginalnym DurationField wywołuje ona metodę parse_datetime, która oczywiście nie jest w stanie obsługiwać wartości ujemnych. Ponadto musiałem nadpisać from_db_value, aby zaimplementować własną konwersję wartości bazy danych. Kod mojego DurationField wygląda teraz tak:

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) 
Powiązane problemy