web-dev-qa-db-ja.com

Djangoで日付け範囲でクエリオジェットをフィルタするにはどうすればいいですか?

私は1つのモデルの中にフィールドを持っています:

class Sample(models.Model):
    date = fields.DateField(auto_now=False)

今、私は日付範囲でオブジェクトをフィルタリングする必要があります。

1-Jan-201131-Jan-2011の間の日付を持つすべてのオブジェクトをどのようにフィルター処理しますか?

192
user469652

つかいます

Sample.objects.filter(date__range=["2011-01-01", "2011-01-31"])

あるいは、月単位でフィルターをかけようとしているだけの場合は、

Sample.objects.filter(date__year='2011', 
                      date__month='01')

編集する

Bernhard Vallantが言ったように、specified range endsを除外するクエリセットが欲しいなら 彼の解決策 を考慮すべきです。それはgt/lt(大なり/小なり)を利用します。

338
crodjer

Djangoのfilterdatetime.dateオブジェクト を一緒に使えます:

import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
                                sampledate__lte=datetime.date(2011, 1, 31))
160

Djangoの範囲をフィルタで処理するときは、dateオブジェクトとdatetimeオブジェクトを使うことの違いを確実に知ってください。 __rangeは日付を含みますが、終了日にdatetimeオブジェクトを使用する場合、時間が設定されていないとその日のエントリは含まれません。

    startdate = date.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

開始日から終了日までのすべてのエントリを、それらの日付のエントリも含めて返します。これは1週間後にエントリを返しているので悪い例ですが、あなたはドリフトを得ます。

    startdate = datetime.today()
    enddate = startdate + timedelta(days=6)
    Sample.objects.filter(date__range=[startdate, enddate])

日付フィールドの時間が何に設定されているかによって、24時間分のエントリが欠落します。

73
cademan

DateTimeField/dateオブジェクト比較の精度不足による「インピーダンスの不一致」を回避するには、rangeを使用している場合は、datetime.timedeltaを使用します。範囲内の最後の日に日を追加します。これは次のように機能します。

start = date(2012, 12, 11)
end = date(2012, 12, 18)
new_end = end + datetime.timedelta(days=1)

ExampleModel.objects.filter(some_datetime_field__range=[start, new_end])

前に説明したように、このようなことをしないで、レコードは最終日に無視されます。

datetime.combineの使用を避けるために編集されました - DateTimeFieldと比較するとき、捨てられた(そして混乱させる)datetimeオブジェクトをめちゃくちゃにするのではなく、日付インスタンスに固執する方が論理的に思えます。以下のコメントでさらなる説明を参照してください。

17
trojjer

単純です

YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())

私のために働きます

5

より柔軟にするために、次のようにFilterBackendを設計できます。

class AnalyticsFilterBackend(generic_filters.BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        predicate = request.query_params # or request.data for POST

        if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is not None:
            queryset = queryset.filter(your_date__range=(predicate['from_date'], predicate['to_date']))

        if predicate.get('from_date', None) is not None and predicate.get('to_date', None) is None:
            queryset = queryset.filter(your_date__gte=predicate['from_date'])

        if predicate.get('to_date', None) is not None and predicate.get('from_date', None) is None:
            queryset = queryset.filter(your_date__lte=predicate['to_date'])
        return queryset
0
saran3h

今日もまだ関連があります。次のこともできます。

import dateutil
import pytz

date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)
0
Bhavik Shah