IT story

Django에서 DateTimeField의 날짜를 어떻게 필터링합니까?

hot-time 2020. 6. 3. 08:24
반응형

Django에서 DateTimeField의 날짜를 어떻게 필터링합니까?


DateTimeField날짜와 비교 를 필터링하려고 합니다. 내말은:

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

나는 시간을 고려하지 않고 있지만 "언제나"를 원하기 때문에 빈 쿼리 세트 목록을 대답으로 얻습니다.

Django 에서이 작업을 수행하는 쉬운 방법이 있습니까?

날짜 시간에 시간이 설정되어 00:00있습니다.


이러한 조회는 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와 날짜를 비교하는 것이 너무 어렵다 "를 확인하십시오.


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 객체를 생성하므로 데이터베이스의 시간이 일치하지 않으므로 작동하지 않습니다.


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

포함 이 더 빠른 것 같습니다.


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

위는 내가 사용한 것입니다. 작동 할뿐만 아니라 고유 한 논리적 백업도 있습니다.


이제 Django에는 개발 버전의 날짜에 대해 datetime 객체를 쿼리하는 __date queryset 필터가 있습니다. 따라서 곧 1.9에서 사용할 수 있습니다.


Django 1.9 __date부터는 datetime 객체를 사용하는 방법이 있습니다.

예를 들면 다음과 같습니다. MyObject.objects.filter(datetime_attr__date=datetime.date(2009,8,22))


이것은 __year, __month 및 __day를 사용하는 것과 동일한 결과를 생성하며 저에게 효과적입니다.

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

active_on이 날짜 객체라고 가정하고 1 일 단위로 증가시킨 다음 범위를 수행하십시오.

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

흥미로운 기술이 있습니다. 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가 해결책을 찾을 때까지 이것은 모두를 도울 것입니다!


흠 .. 내 솔루션이 작동 중입니다.

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

Django Documentation 기사 참조

JZ 답변과 매우 유사합니다.

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

Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)

장고 1.7.6에서는 다음과 같이 작동합니다.

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

There's a fantastic blogpost that covers this here: Comparing Dates and Datetimes in the Django ORM

The best solution posted for Django>1.7,<1.9 is to register a transform:

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()

Then you can use it in your filters like this:

Foo.objects.filter(created_on__date=date)

EDIT

This solution is definitely back end dependent. From the article:

Of course, this implementation relies on your particular flavor of SQL having a DATE() function. MySQL does. So does SQLite. On the other hand, I haven’t worked with PostgreSQL personally, but some googling leads me to believe that it does not have a DATE() function. So an implementation this simple seems like it will necessarily be somewhat backend-dependent.

참고URL : https://stackoverflow.com/questions/1317714/how-can-i-filter-a-date-of-a-datetimefield-in-django

반응형