首页 > 解决方案 > 从 DateTimeField/DateField Django ORM 比较年份

问题描述

我有一个模型配置如下,

class Foo(models.Model):
    start = models.DateTimeField()
    end = models.DateTimeField()

如何检索具有相同年份Foo的实例?


尝试失败:

from django.db.models import F

Foo.objects.filter(start__year=F('end__year'))

返回空QuerySet

标签: djangodjango-modelsdjango-ormdjango-database-functions

解决方案


语句的SQL查询Foo.objects.filter(start__year=F('end__year'))是,

SELECT "foo"."id", "foo"."start", "foo"."end" 
FROM "foo" 
WHERE django_datetime_extract('year', "foo"."start", 'UTC') = ("foo"."end")

看..?比较发生在整数(提取的start year)和日期时间(end datetime)之间

所以,Django 返回了 empty QuerySet

解决方案是什么?

我们可以使用ExtractYear()db 函数从中提取YearDateTimeField使用annotate()函数来临时存储它。然后将带注释的字段与年份查找进行比较。

from django.db.models import F
from django.db.models.functions import ExtractYear

Foo.objects.annotate(start_year=ExtractYear(F('start'))).filter(<b>end__year=F('start_year'))

SQL查询:

SELECT 
    "foo"."id", "foo"."start", "foo"."end", 
    django_datetime_extract('year', "foo"."start", 'UTC') AS "start_year" 
FROM 
    "foo" 
WHERE 
    django_datetime_extract('year', "foo"."end", 'UTC') = (django_datetime_extract('year', "foo"."start", 'UTC'))

推荐阅读