我對Django比較陌生,對Django Querysets也不熟悉。 我想根據一個字段篩選日期時間範圍內的查詢集。 在MySQL中,我會做基於Django中的字段的動態範圍過濾器
這裏START_TIME是一個日期和持續時間是在幾分鐘時間一個int。
我該如何在便攜式的Django中做到這一點?我知道我總是可以使用extra,但我更喜歡它可以在MySQL和Sqlite3中使用。看起來這些數據庫管理員不共享任何日期時間功能。
我對Django比較陌生,對Django Querysets也不熟悉。 我想根據一個字段篩選日期時間範圍內的查詢集。 在MySQL中,我會做基於Django中的字段的動態範圍過濾器
這裏START_TIME是一個日期和持續時間是在幾分鐘時間一個int。
我該如何在便攜式的Django中做到這一點?我知道我總是可以使用extra,但我更喜歡它可以在MySQL和Sqlite3中使用。看起來這些數據庫管理員不共享任何日期時間功能。
你可以用「F」在查詢表達式引用過濾器表達式中的模型的領域(見https://docs.djangoproject.com/en/dev/topics/db/queries/#using-f-expressions-in-filters)
這意味着,在過濾器中,它可能說「這裏time_a
是time_b
之前」任何特別一行:
filter(time_a__lt=F('time_b')
然而,問題的產生是因爲,按照this related question,timedelta
不會接受動態F()
表達......所以它看起來像需要自定義的SQL。不過,您可以在Django中自動測試sqlite和mysql,以斷言它可以在兩者上運行。
同時,避免自定義SQL的特別髒的解決方案是將start_time
轉換爲Unix時間,這使得數學變得簡單。
from calendar import timegm
from datetime import timedelta
from django.db import models
from django.db.models import F
from django.utils.timezone import now
class Journey(models.Model):
name = models.CharField(max_length=64)
start_time = models.IntegerField()
duration_minutes = models.IntegerField()
def current_journeys():
unow = timegm(now().utctimetuple())
q = Journey.objects.filter(start_time__gt=unow-60*F('duration_minutes'))
return q.all()
剛剛測試此使用'django.test.TestCase'和它的工作原理與sqlite3和mysql引擎。 – jamesc 2014-10-02 12:26:46
就我而言,這不是一個固定的範圍。它取決於持續時間字段,該字段對數據庫中的每一行都有所不同。這就是我明確說明start_time和duration類型的原因。 – 2014-10-02 13:57:37
我可能不得不以完全避免這個問題的方式來解決我的問題,但很高興知道這是否可行。 – 2014-10-02 14:01:03
這是一個相關的問題:http://stackoverflow.com/questions/18555247/django-time-difference-with-f-object – jamesc 2014-10-02 17:40:05