私は1つのモデルの中にフィールドを持っています:
class Sample(models.Model):
date = fields.DateField(auto_now=False)
今、私は日付範囲でオブジェクトをフィルタリングする必要があります。
1-Jan-2011
と31-Jan-2011
の間の日付を持つすべてのオブジェクトをどのようにフィルター処理しますか?
つかいます
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(大なり/小なり)を利用します。
Djangoのfilter
と datetime.date
オブジェクト を一緒に使えます:
import datetime
samples = Sample.objects.filter(sampledate__gte=datetime.date(2011, 1, 1),
sampledate__lte=datetime.date(2011, 1, 31))
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時間分のエントリが欠落します。
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
オブジェクトをめちゃくちゃにするのではなく、日付インスタンスに固執する方が論理的に思えます。以下のコメントでさらなる説明を参照してください。
単純です
YourModel.objects.filter(YOUR_DATE_FIELD__date=timezone.now())
私のために働きます
より柔軟にするために、次のように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
今日もまだ関連があります。次のこともできます。
import dateutil
import pytz
date = dateutil.parser.parse('02/11/2019').replace(tzinfo=pytz.UTC)