日付と比較する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
含むはより速いようです。
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))
上記は私が使用したものです。動作するだけでなく、固有の論理的な裏付けもあります。
現在、Djangoには __ date querysetフィルターがあり、開発バージョンの日付に対してdatetimeオブジェクトを照会します。したがって、1.9ですぐに利用可能になります。
Django 1.9現在、これを行う方法は、日時オブジェクトで __date
を使用することです。
例:MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))
これにより、__ year、__ month、および__dayを使用した場合と同じ結果が得られ、私にとってはうまくいくようです:
YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
active_onが日付オブジェクトであると仮定して、1日増やしてから範囲を指定します
next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
ここに興味深いテクニックがあります。MySQLのDjangoで実装されているstartswithプロシージャを利用して、日付のみで日付時刻を検索するだけの結果を達成しました。基本的に、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が解決策を出すまで、これがすべての人に役立つことを願っています!
うーん。私のソリューションは機能しています。
Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
これをカバーする素晴らしいブログポストがあります: 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を個人的に扱ったことはありませんが、一部のグーグルはPostgreSQLにDATE()関数がないと信じさせます。したがって、この単純な実装は、必然的にある程度バックエンドに依存するように思われます。
記事を参照してください Django Documentation
JZの回答に非常によく似ています
ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27)
Django 1.7.6の場合:
MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)