2009-04-29 40 views
24

Với inspectdb tôi đã có thể nhận được một "khoảng thời gian" trường từ postgres vào django. Ở Django, nó là một TextField. Các đối tượng mà tôi lấy ra thực sự là một đối tượng timedelta!Làm thế nào để đặt timedelta trong mô hình django?

Bây giờ tôi muốn đặt đối tượng timedelta này vào một mô hình mới. Cách tốt nhất để làm điều này là gì? Bởi vì đặt một timedelta trong một TextField quả trong phiên bản str của đối tượng ...

Trả lời

27

Bạn trivially có thể bình thường hóa một timedelta một số dấu chấm động duy nhất trong ngày hoặc giây .

Đây là phiên bản "Chuẩn hóa sang ngày".

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

Bạn có thể lần lượt chuyển số dấu phẩy động thành một dấu thời gian.

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

Vì vậy, lưu trữ timedelta của bạn dưới dạng phao.

Đây là phiên bản "Chuẩn hóa sang giây".

timedelta.days*86400+timedelta.seconds 

Đây là điều ngược lại (sử dụng giây)

datetime.timedelta(someSeconds/86400) 
+1

tắt khóa học bạn có nghĩa là float (timedelta.days) + float (timedelta.seconds)/float (86400) ... nhưng nó hoạt động! –

+0

@Jack Ha: Cảm ơn bạn đã tìm hiểu vấn đề. –

+0

timedelta.days + timedelta.seconds/86400.0 – aehlke

7

Thứ nhất, xác định mô hình của bạn:

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

Để lưu một đối tượng timedelta:

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

Để có được đối tượng timedelta ra khỏi cơ sở dữ liệu:

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

Lưu ý: Tôi đang sử dụng Python 2.7 cho ví dụ này.

+1

trên python với phiên bản thấp hơn 2.7 có thể được sử dụng công thức: 'total_seconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6)/10 ** 6' – Pol

+0

Điều này thật tuyệt . Cảm ơn bạn đã được cả hai ngắn gọn và kỹ lưỡng –

3

Có một vé mà ngày trở lại vào tháng 7 năm 2006 về vấn đề này: https://code.djangoproject.com/ticket/2443

Một số bản vá lỗi được viết nhưng một trong đó đã được chuyển vào một dự án: https://github.com/johnpaulett/django-durationfield

So với tất cả các khác câu trả lời ở đây dự án này là trưởng thành và sẽ được sáp nhập vào lõi ngoại trừ việc sự bao gồm của nó hiện được coi là "bloaty".

Cá nhân, tôi vừa thử một loạt các giải pháp và đây là giải pháp hiệu quả nhất.

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 

Kết quả:

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

Và trong admin:

Thay đổi sự kiện

Thời gian: 7 days, 0:00:00

+1

Nó trông giống như trong Django 1.8, mà vé cuối cùng sẽ được đóng lại và Django sẽ có một 'DurationField': https://docs.djangoproject.com/en/dev/releases/1.8/# new-data-types – nnyby

2

Đưa này ra có nguyên nhân nó có thể là một cách khác để giải quyết vấn đề. đầu tiên cài đặt thư viện này: https://pypi.python.org/pypi/django-timedeltafield

Sau đó:

import timedelta 

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

trong quản trị, bạn sẽ được yêu cầu nhập dữ liệu vào lĩnh vực này với các định dạng sau: 3 ngày, 4 giờ, 2 phút

+0

Tôi thích giải pháp này với Django 1.7 vì nó nằm trong repo pip và không phải là nguồn bên ngoài. –

Các vấn đề liên quan