【问题标题】:Django - Add Nearest Monday to QuerysetDjango - 将最近的星期一添加到查询集
【发布时间】:2020-12-14 00:27:22
【问题描述】:

我有一个像这样的Order 模型:

class Order(models.Model):

    created_at = models.DateTimeField(...)

可以随时创建订单,但所有订单都会在下周一发货。

如何在我的订单查询集中添加一个名为 assembly_date 的额外字段,以反映下周一(订单应发货的日期)?

我尝试像这样创建自定义OrderManager,但不确定如何正确设置assembly_date

from django.db.models import F, ExpressionWrapper, DateField
from django.db.models.functions import ExtractWeekDay

class OrderManager(models.Manager):

    def get_queryset(): 
    
        # need help with logic here:
        return self.super().get_queryset().annotate(
            assembly_date = ExpressionWrapper(
                F("created_at") - ExtractWeekDay("created_at"),
                output_field = DateField(),
            )
        )

但是这个操作会导致如下错误:

django.db.utils.ProgrammingError: operator does not exist: timestamp with time zone - double precision
LINE 1: ...E NULL END) * 2628000.0) * INTERVAL '1 seconds')) - EXTRACT(...
                                                             ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.

请记住,我希望能够根据它们的组装日期过滤所有订单。

【问题讨论】:

标签: django


【解决方案1】:

基本上你需要在annotate 内部动态生成timedelta。但据我所知,您无法将isoweekday() 应用于annotate 内的日期时间字段。

您可以在模型中添加另一个字段assembly_date,并直接使用它进行查询。

from datetime import timedelta, date

class Order(models.Model):

    created_at = models.DateTimeField(...)
    assembly_date = models.DateTimeField(...)

    def save(self, *args, **kwargs):
       weekday = self.created_at.isoweekday() # 1 is Monday, 2 is Tuesday.
       daysdiff = 8 - weekday
       self.assembly_date = self.created_at + timedelta(days= daysdiff)
       super(Order, self).save(*args, **kwargs)     

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    相关资源
    最近更新 更多