[python] Django에서 날짜 범위별로 쿼리 객체를 어떻게 필터링합니까?

하나의 모델에 다음과 같은 필드가 있습니다.

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가 말했듯이, 제외하는 쿼리 세트를 원하면 gt / lt (보다 큼 /보다 큼)를 사용하는 솔루션을specified range ends 고려해야 합니다.


답변

djangofilterdatetime.date객체 와 함께 사용할 수 있습니다 .

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


답변

필터를 사용하여 장고 범위를 수행하는 경우 날짜 개체와 날짜 시간 개체의 차이점을 알아야합니다. __range는 날짜를 포함하지만 종료 날짜에 datetime 객체를 사용하는 경우 시간이 설정되지 않은 경우 해당 날짜의 항목이 포함되지 않습니다.

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

해당 날짜의 항목을 포함하여 시작 날짜부터 종료 날짜까지의 모든 항목을 반환합니다. 이것은 일주일에 미래에 항목을 반환하기 때문에 나쁜 예이지만 드리프트를 얻습니다.

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

날짜 필드의 시간 설정에 따라 24 시간 분량의 항목이 누락됩니다.


답변

datetime.timedelta 를 사용 DateTimeField/date하여 범위의 마지막 날짜에 날짜 를 추가 하여 범위 를 사용하는 경우 발생할 수있는 개체 비교 의 정밀도 부족으로 인한 “임피던스 불일치” 를 해결할 수 있습니다 . 이것은 다음과 같이 작동합니다.

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.combineDateTimeField버리기 (그리고 혼란스러운) 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)