2009-04-29 24 views
24

Con inspectdb pude obtener un campo de "intervalo" de postgres en django. En Django, era un campo de texto. El objeto que recuperé fue de hecho un objeto timedelta!¿Cómo poner timedelta en el modelo django?

Ahora quiero poner este objeto timedelta en un nuevo modelo. ¿Cuál es la mejor manera de hacer esto? Debido a poner un timedelta en un campo de texto se traduce en la versión str del objeto ...

Respuesta

27

Usted puede normalizar trivialmente un timedelta a un solo número en coma flotante en días o segundo .

Aquí está la versión "Normalizar a días".

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

Puede convertir trivialmente un número de punto flotante en un timedelta.

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

Así que, almacene su timedelta como un flotador.

Aquí está la versión "Normalizar a segundos".

timedelta.days*86400+timedelta.seconds 

Aquí está la inversa (usando segundos)

datetime.timedelta(someSeconds/86400) 
+1

fuera de curso te refieres a float (timedelta.days) + float (timedelta.seconds)/float (86400) ... ¡pero funciona! –

+0

@Jack Ha: Gracias por detectar el problema. –

+0

timedelta.days + timedelta.seconds/86400.0 – aehlke

7

En primer lugar, definir su modelo:

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

Para almacenar un objeto timedelta:

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

para obtener el objeto timedelta fuera de la base de datos:

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

Nota: estoy usando Python 2.7 para este ejemplo.

+1

en python con una versión inferior a 2.7 se puede utilizar fórmula: 'total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6)/10 ** 6' – Pol

+0

Esto es genial . Gracias por ser conciso y completo –

3

No es un billete que se remonta a julio de 2006, relativa a esto: https://code.djangoproject.com/ticket/2443

varios parches fueron escritos, pero la que fue entregada a un proyecto: https://github.com/johnpaulett/django-durationfield

En comparación con todos los demás respuestas aquí este proyecto está maduro y se habría fusionado al núcleo, excepto que su inclusión actualmente se considera "inflada".

Personalmente, acabo de probar varias soluciones y esta es la que funciona muy bien.

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 

Resultado:

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

Y admin:

evento Change

Duración: 7 days, 0:00:00

+1

Parece que en Django 1.8, ese ticket finalmente se cerrará y Django tendrá un 'DurationField': https://docs.djangoproject.com/en/dev/releases/1.8/# new-data-types – nnyby

2

poner esto por ahí Porque podría ser otra forma de resuelve este problema. instalar primero esta biblioteca: https://pypi.python.org/pypi/django-timedeltafield

continuación:

import timedelta 

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

dentro del administrador se le pedirá para introducir datos en el campo con el siguiente formato: 3 días, 4 horas, 2 minutos

+0

Prefiero esta solución con Django 1.7 porque está en el repositorio de pip y no en una fuente externa. –

Cuestiones relacionadas