DateTimeField
日付との比較をフィルタリングしようとしています。つまり:
MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))
私は時間を考慮していないので(私は思う)、答えとして空のクエリセットリストを取得しますが、「いつでも」したいのです。
Django でこれを行う簡単な方法はありますか?
日時が設定されていますが、そうではありません00:00
。
DateTimeField
日付との比較をフィルタリングしようとしています。つまり:
MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))
私は時間を考慮していないので(私は思う)、答えとして空のクエリセットリストを取得しますが、「いつでも」したいのです。
Django でこれを行う簡単な方法はありますか?
日時が設定されていますが、そうではありません00:00
。
このようなルックアップは、次のように実装されdjango.views.generic.date_based
ています。
{'date_time_field__range': (datetime.datetime.combine(date, datetime.time.min),
datetime.datetime.combine(date, datetime.time.max))}
非常に冗長なので、__date
演算子を使用して構文を改善する計画があります。詳細については、 「#9596 DateTimeField を日付と比較するのは難しすぎる」を確認してください。
YourModel.objects.filter(datetime_published__year='2008',
datetime_published__month='03',
datetime_published__day='27')
// コメントの後に編集
YourModel.objects.filter(datetime_published=datetime(2008, 03, 27))
時刻値が 0 に設定された datetime オブジェクトを作成するため、機能しません。そのため、データベースの時刻が一致しません。
ipython の timeit 関数で得た結果は次のとおりです。
from datetime import date
today = date.today()
timeit[Model.objects.filter(date_created__year=today.year, date_created__month=today.month, date_created__day=today.day)]
1000 loops, best of 3: 652 us per loop
timeit[Model.objects.filter(date_created__gte=today)]
1000 loops, best of 3: 631 us per loop
timeit[Model.objects.filter(date_created__startswith=today)]
1000 loops, best of 3: 541 us per loop
timeit[Model.objects.filter(date_created__contains=today)]
1000 loops, best of 3: 536 us per loop
containsの方が速いようです。
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))
上記は私が使用したものです。それは機能するだけでなく、いくつかの固有の論理的裏付けもあります。
これにより、__ year、__ month、および__dayを使用した場合と同じ結果が得られ、私にとってはうまくいくようです。
YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
active_on が日付オブジェクトであると仮定し、それを 1 日増やしてから range を実行します
next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
ここでこれをカバーする素晴らしいブログ投稿があります: Comparing Dates and Datetimes in the Django ORM
Django>1.7、<1.9 に投稿された最善の解決策は、変換を登録することです。
from django.db import models
class MySQLDatetimeDate(models.Transform):
"""
This implements a custom SQL lookup when using `__date` with datetimes.
To enable filtering on datetimes that fall on a given date, import
this transform and register it with the DateTimeField.
"""
lookup_name = 'date'
def as_sql(self, compiler, connection):
lhs, params = compiler.compile(self.lhs)
return 'DATE({})'.format(lhs), params
@property
def output_field(self):
return models.DateField()
次に、次のようにフィルターで使用できます。
Foo.objects.filter(created_on__date=date)
編集
このソリューションは、間違いなくバックエンドに依存しています。記事から:
もちろん、この実装は、DATE() 関数を持つ特定のフレーバーの SQL に依存しています。MySQL はそうです。SQLiteもそうです。一方、個人的に PostgreSQL を使用したことはありませんが、Google で調べてみると、PostgreSQL には DATE() 関数がないと思われます。したがって、この単純な実装は、必然的に多少バックエンドに依存するように見えます。
ここに興味深い手法があります。MySQL の Django で実装されている startwith プロシージャを利用して、日付のみを介して日時のみを検索するという結果を達成しました。基本的に、Django がデータベースでルックアップを行うとき、DATETIME MySQL ストレージ オブジェクトの文字列変換を行う必要があるため、日付のタイムスタンプ部分を除外して、それをフィルタリングできます。そのようにして、%LIKE% は日付のみに一致します。オブジェクトと指定された日付のすべてのタイムスタンプを取得します。
datetime_filter = datetime(2009, 8, 22)
MyObject.objects.filter(datetime_attr__startswith=datetime_filter.date())
これにより、次のクエリが実行されます。
SELECT (values) FROM myapp_my_object \
WHERE myapp_my_object.datetime_attr LIKE BINARY 2009-08-22%
この場合の LIKE BINARY は、タイムスタンプに関係なく、日付のすべてに一致します。次のような値が含まれます。
+---------------------+
| datetime_attr |
+---------------------+
| 2009-08-22 11:05:08 |
+---------------------+
Django が解決策を提示するまで、これがすべての人に役立つことを願っています!
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
ur_data_model.objects.filter(ur_date_field__gte=datetime(2009, 8, 22), ur_date_field__lt=datetime(2009, 8, 23))
うーん..私のソリューションは機能しています:
Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
datetimefield がある場合は、datetime.date.today() を使用できます。
context['now'] = Mymodel.objects.filter(date_time_field=datetime.date.today())