web-dev-qa-db-ja.com

DjangoでDateTimeFieldの日付をフィルタリングするにはどうすればよいですか?

日付と比較するDateTimeFieldをフィルタリングしようとしています。というのは:

MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))

空のクエリセットリストを回答として取得します(時間を考慮していないため).

Djangoでこれを行う簡単な方法はありますか?

日時の時間が設定されていますが、00:00ではありません。

158
Xidobix

このようなルックアップは、次のように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を日付と比較するのが難しい 」を確認してください。

110
Piotr Czapla
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オブジェクトを作成し、データベース内の時刻が一致しないため、機能しません。

95
zalew

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

含むはより速いようです。

79
Moreno
Mymodel.objects.filter(date_time_field__contains=datetime.date(1986, 7, 28))

上記は私が使用したものです。動作するだけでなく、固有の論理的な裏付けもあります。

40
kettlehell

現在、Djangoには __ date querysetフィルターがあり、開発バージョンの日付に対してdatetimeオブジェクトを照会します。したがって、1.9ですぐに利用可能になります。

39
omat

Django 1.9現在、これを行う方法は、日時オブジェクトで __date を使用することです。

例:MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))

25
Andrew B.

これにより、__ year、__ month、および__dayを使用した場合と同じ結果が得られ、私にとってはうまくいくようです:

YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
25
mhost

active_onが日付オブジェクトであると仮定して、1日増やしてから範囲を指定します

next_day = active_on + datetime.timedelta(1)
queryset = queryset.filter(date_created__range=(active_on, next_day) )
8
davidj411

ここに興味深いテクニックがあります。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が解決策を出すまで、これがすべての人に役立つことを願っています!

2
bbengfort

うーん。私のソリューションは機能しています。

Mymodel.objects.filter(date_time_field__startswith=datetime.datetime(1986, 7, 28))
1
satels

これをカバーする素晴らしいブログポストがあります: 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()関数がないと信じさせます。したがって、この単純な実装は、必然的にある程度バックエンドに依存するように思われます。

0
Dan Gayle

記事を参照してください Django Documentation

JZの回答に非常によく似ています

ur_data_model.objects.filter(ur_date_field=datetime(2005, 7, 27)
0
shahjapan

Django 1.7.6の場合:

MyObject.objects.filter(datetime_attr__startswith=datetime.date(2009,8,22))
0
FACode
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
0
Skylar Saveland