2009-04-29 4 views
24

Con inspectdb sono riuscito a ottenere un campo "intervallo" da postgres in django. In Django, era un campo di testo. L'oggetto che ho recuperato era davvero un oggetto timedelta!Come inserire timedelta nel modello di django?

Ora voglio inserire questo oggetto timedelta in un nuovo modello. Qual'è il miglior modo per farlo? Perché mettere un timedelta in un TextField si traduce nella versione str dell'oggetto ...

risposta

27

È possibile banalmente normalizzare un timedelta ad un unico numero in virgola mobile in giorni o secondi .

Ecco la versione "Normalize to Days".

float(timedelta.days) + float(timedelta.seconds)/float(86400) 

È possibile trasformare banalmente un numero in virgola mobile in un timedelta.

>>> datetime.timedelta(2.5) 
datetime.timedelta(2, 43200) 

Quindi, memorizzare il timedelta come un galleggiante.

Ecco la versione "Normalize to Seconds".

timedelta.days*86400+timedelta.seconds 

Ecco il contrario (utilizzando secondi)

datetime.timedelta(someSeconds/86400) 
+1

Ovviamente si intende float (timedelta.days) + float (timedelta.seconds)/float (86400) ... ma funziona! –

+0

@ Jack Ha: Grazie per aver individuato il problema. –

+0

timedelta.days + timedelta.seconds/86400.0 – aehlke

7

In primo luogo, definire il modello:

class TimeModel(models.Model): 
    time = models.FloatField() 

Per memorizzare un oggetto timedelta:

# td is a timedelta object 
TimeModel.objects.create(time=td.total_seconds()) 

per ottenere l'oggetto timedelta dal database:

# Assume the previously created TimeModel object has an id of 1 
td = timedelta(seconds=TimeModel.objects.get(id=1).time) 

Nota: sto usando Python 2.7 per questo esempio.

+1

su python con versione inferiore a 2.7 può essere utilizzato formula: 'total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6)/10 ** 6' – Pol

+0

Questo è ottimo . Grazie per essere sia conciso che approfondito –

3
Ci

è un biglietto che risale al luglio 2006, relativa a questo: https://code.djangoproject.com/ticket/2443

Diverse macchie sono state scritte, ma quello che è stato trasformato in un progetto: https://github.com/johnpaulett/django-durationfield

Rispetto a tutti gli altri Risposte qui questo progetto è maturo e sarebbe stato unito al nucleo tranne che la sua inclusione è attualmente considerata "gonfia".

Personalmente, ho appena provato un sacco di soluzioni e questa è quella che funziona magnificamente.

from django.db import models 
from durationfield.db.models.fields.duration import DurationField 

class Event(models.Model): 
    start = models.DateTimeField() 
    duration = DurationField() 

    @property 
    def finish(self): 
     return self.start + self.duration 

Risultato:

$ evt = Event.objects.create(start=datetime.datetime.now(), duration='1 week') 
$ evt.finish 
Out[]: datetime.datetime(2013, 6, 13, 5, 29, 29, 404753) 

E in admin:

evento Change

Durata: 7 days, 0:00:00

+1

Sembra che in Django 1.8, quel biglietto sarà finalmente chiuso e Django avrà un 'DurationField': https://docs.djangoproject.com/en/dev/releases/1.8/# new-data-types – nnyby

2

mettere questo là fuori causa potrebbe essere un altro modo per risolvi questo problema. installare questa libreria: https://pypi.python.org/pypi/django-timedeltafield

Poi:

import timedelta 

class ModelWithTimeDelta(models.Model): 
    timedeltafield = timedelta.fields.TimedeltaField() 

entro l'amministratore vi verrà chiesto di inserire i dati nel campo con il seguente formato: 3 giorni, 4 ore, 2 minuti

+0

Preferisco questa soluzione con Django 1.7 perché è nel repository pip e non è una fonte esterna. –

54

Dal momento che Django 1.8 è possibile utilizzare DurationField.