DateTimeField
날짜와 비교 를 필터링하려고 합니다. 내말은:
MyObject.objects.filter(datetime_attr=datetime.date(2009,8,22))
나는 시간을 고려하지 않고 "언제나"를 원하기 때문에 빈 쿼리 세트 목록을 대답으로 얻습니다.
Django 에서이 작업을 수행하는 쉬운 방법이 있습니까?
날짜 시간에 시간이 설정되어 00:00
있습니다.
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와 날짜를 비교하는 것이 너무 어렵다 "를 확인하십시오.
Q(created__gte=datetime.combine(created_value, time.min))
Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
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
포함 이 더 빠른 것 같습니다.
contains
해결책을 시도 할 때 다음과 같은 오류 메시지가 표시 되기 때문에 4 개의 upvotes가 있다는 것에 놀랐습니다 .Unable to get repr for <class 'django.db.models.query.QuerySet'>
__contains
필터로 인한 오류가 아닌 것 같습니다 . 그러나 문제가 발생 하면를 사용 하는 django docs 예제 를 사용해보십시오 __gte
.
startswith
해결책을 좋아한다 ..
이제 Django에는 개발 버전의 날짜에 대해 datetime 객체를 쿼리하는 __date queryset 필터가 있습니다. 따라서 곧 1.9에서 사용할 수 있습니다.
이것은 __year, __month 및 __day를 사용하는 것과 동일한 결과를 생성하며 저에게 효과적입니다.
YourModel.objects.filter(your_datetime_field__startswith=datetime.date(2009,8,22))
흥미로운 기술이 있습니다. 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가 해결책을 찾을 때까지 이것은 모두를 도울 것입니다!
Django ORM의 날짜 및 날짜 시간 비교 : 여기에 이것을 다루는 환상적인 블로그 게시물이 있습니다.
Django> 1.7, <1.9에 게시 된 최상의 솔루션은 변환을 등록하는 것입니다.
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()
그런 다음 필터에서 다음과 같이 사용할 수 있습니다.
Foo.objects.filter(created_on__date=date)
편집하다
이 솔루션은 확실히 백엔드에 의존합니다. 기사에서 :
물론,이 구현은 DATE () 함수가있는 특정 버전의 SQL에 의존합니다. MySQL은 그렇습니다. SQLite도 마찬가지입니다. 반면에, 나는 개인적으로 PostgreSQL과 함께 일하지 않았지만 일부 인터넷 검색은 DATE () 함수가 없다고 믿습니다. 따라서이 간단한 구현은 반드시 다소 백엔드에 의존하는 것처럼 보입니다.
return '{}::date'.format(lhs), params
Model.objects.filter(datetime__year=2011, datetime__month=2, datetime__day=30)
Django Documentation 기사를 참조하십시오
ur_data_model.objects.filter(ur_date_field__gte=datetime(2009, 8, 22), ur_date_field__lt=datetime(2009, 8, 23))