次のような1つのモデルにフィールドがあります。
class Sample(models.Model):
date = fields.DateField(auto_now=False)
次に、日付範囲でオブジェクトをフィルタリングする必要があります。
1-Jan-2011
との間の日付を持つすべてのオブジェクトをフィルタリングするにはどうすればよい31-Jan-2011
ですか?
次のような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(より大/小)を使用する彼のソリューションを検討する必要があります。
__range
境界線(sqlのようなBETWEEN
)が含まれていると言う必要があります。境界線を含めたくない場合は、私のgt / ltソリューションを使用する必要があります...
order_by
生成さQuerySet
れたを使用する場合に基づきますfilter
。私は何年もDjangoを使っていません。
あなたは使用することができます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の範囲を実行するときは、日付オブジェクトと日付時刻オブジェクトの違いを理解してください。__rangeは日付に含まれますが、終了日にdatetimeオブジェクトを使用する場合、時刻が設定されていなければ、その日のエントリは含まれません。
startdate = date.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
startdateからenddateまでのすべてのエントリを、それらの日付のエントリを含めて返します。これは1週間後のエントリを返すため、悪い例ですが、ドリフトが発生します。
startdate = datetime.today()
enddate = startdate + timedelta(days=6)
Sample.objects.filter(date__range=[startdate, enddate])
日付フィールドの時刻の設定に応じて、24時間分のエントリが欠落します。
date
オブジェクトを: >>> from datetime import date
>>> startdate = date.today()
範囲DateTimeField/date
を使用している場合に発生する可能性がある、オブジェクト比較の精度の欠如が原因で発生する「インピーダンスの不一致」を回避するには、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
オブジェクトをいじるのではなく、と比較するときに日付インスタンスに固執する方が論理的です。以下のコメントで詳細な説明を参照してください。
Example.objects.filter(created__range=[date(2014, 1, 1), date(2014, 2, 1)])
上で作成されたオブジェクトが含まれていないでしょうdate(2014, 2, 1)
@cademanが親切に説明したように、。しかし、1日を追加して終了日を増やした場合、欠落しているオブジェクトをカバーするクエリセットが得られます(date(2014, 2, 2)
同じ癖のために作成されたオブジェクトは省略されます)。ここでの厄介なことは、で指定された「手動」範囲created__gte ... created__lte=date(2014, 2, 1)
も機能しないことです。これは、明らかに直観に反するIMHOです。
シンプルです
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