我的桌子上有一组Orders
我的客户制作的(购买,也就是说)。
客户可以选择交货日期。该值存储在名为Order
的字段中的每个Order.delivery_date
中(在那里没有太大的创造力)
class Order(BaseModel):
customer = ForeignKey(Customer, on_delete=CASCADE, related_name='orders')
delivery_date = DateField(null=True, blank=True)
我想注释一个查询集,该查询集在前一个星期日为Orders
提取delivery_date
(主要是创建每周报告," bucketized"每周)
我想"哦!我知道!我将在一周内获得日期索引,并且我将使用该周索引的天数减去datetime.timedelta
,并且我将使用它来获取星期日(如Python&) #39; s .weekday()函数)" :
from server.models import *
import datetime
from django.db.models import F, DateField, ExpressionWrapper
from django.db.models.functions import ExtractWeekDay
Order.objects.filter(
delivery_date__isnull=False
).annotate(
sunday=ExpressionWrapper(
F('delivery_date') - datetime.timedelta(days=ExtractWeekDay(F('delivery_date')) + 1),
output_field=DateField()
)
).last().sunday
但如果我这样做,我会在尝试构建" TypeError: unsupported type for timedelta days component: CombinedExpression
表达式时得到timedelta
。
不使用F
中的Extract
功能也不会产生任何影响:无论是否使用Extract(F('delivery_date'))
或Extract('delivery_date')
,我都会收到同样的错误
这是一个Python 3.4,使用Django 2.0.3而不是MySQL 5.7.21
我知道我总是可以获取Order
对象并在Python中执行此操作(我甚至有一个辅助函数可以执行此操作)但是使用该注释获取对象会很好来自数据库(也用于学习目的)
提前谢谢。
答案 0 :(得分:1)
哦,我忘记了extra
看起来应该这样做(至少对MySQL而言)
orders_q = Order.objects.filter(
delivery_date__isnull=False
).extra(
select={
'sunday': "DATE_ADD(`delivery_date`, interval(1 - DAYOFWEEK(`delivery_date`)) DAY)"
},
).order_by('-id')
似乎有效:
for record in orders_q.values('sunday', 'delivery_date'):
print("date: {delivery_date}, sunday: {sunday} is_sunday?: {is_sunday}".format(
is_sunday=record['sunday'].weekday() == 6, **record)
)
date: 2018-06-04, sunday: 2018-06-03 is_sunday?: True
date: 2018-05-30, sunday: 2018-05-27 is_sunday?: True
date: 2018-05-21, sunday: 2018-05-20 is_sunday?: True
date: 2018-06-04, sunday: 2018-06-03 is_sunday?: True
编辑:显然,extra
正在被弃用/不受支持。至少,不是......嗯...... fondly received由Django开发人员提供。也许最好使用RawSQL
代替。实际上,我在尝试使用sunday
注释进行进一步过滤时遇到了问题extra
我没有使用RawSQL
方法获得...
这似乎更好:
orders_q = orders_q.annotate(
sunday=RawSQL("DATE_ADD(`delivery_date`, interval(1 - DAYOFWEEK(`delivery_date`)) DAY)", ())
)
这让我可以进一步注释...
orders_q.annotate(sunday_count=Count('sunday'))
我不知道为什么,但当我使用extra
时,我会得到Cannot resolve keyword 'sunday' into field