【问题标题】:'datetime.date' object is not callable'datetime.date' 对象不可调用
【发布时间】:2020-06-17 13:41:11
【问题描述】:

我有一个带有date 字段和以下方法的模型:

class Pm(models.Model):
    mydate = models.DateField()

    @property
    def due_date(self):
        today = timezone.localtime(timezone.now()).date()
        if self.mydate < today:
            return today
        else:
            return self.mydate

如何根据due_date 函数的返回来订购myModel.objects.all()? 我试过了:

qs = sorted(Pm.objects.all(), key=lambda a: a.due_date(), reverse=True)

但它返回错误:

'datetime.date' object is not callable

更新 根据 Sami 的建议:

@staticmethod
    def due_date(obj):
        today = timezone.localtime(timezone.now()).date()
        if obj.pm_date < today:
            return today
        else:
            return obj.pm_date

qs = sorted(Pm.objects.all(), key=Pm.due_date, reverse=True)

似乎工作,除了它返回一个列表而不是一个查询集。

我应该使用什么方法来获取查询集?

【问题讨论】:

  • 好吧,你把它标记为属性,所以不要调用它。
  • 您的错误表明您正在尝试“调用”日期。尝试去掉括号,看看是否可行。

标签: python django


【解决方案1】:

老实说,我不会在 python 中对其进行排序。有两个原因:

  • 数据库应该比 python 做得更好/更快
  • 该属性使许多日期无法排序:比今天更早的所有日期都相等。它没有任何用处,尤其是没有辅助排序字段。

既然你最终想要一个查询集,那就保持简单:

qs = Pm.objects.order_by('-mydate')
# Now we can display the due date property when we render things:
for pm in qs:
   print(pm.due_date)

【讨论】:

    【解决方案2】:

    我认为您需要使您的方法due_date成为静态方法或将其与模型分开,方法获取obj并返回日期,然后在排序方法中使用此方法。像这样的

    def due_date(obj):
            today = timezone.localtime(timezone.now()).date()
            if obj.date < today:
                return today
            else:
                return obj.date
    qs = sorted(Pm.objects.all(), key=due_date, reverse=True)
    

    如果您在 Model 类中将此方法设为静态,则将其用作:

    qs = sorted(Pm.objects.all(), key=PM.due_date, reverse=True)
    

    否则你需要注释然后使用查询集的order_by。 annotation with conditional expressions F-expressions

    这样的事情(它可能不是确切的解决方案,但你需要做这样的事情):

    from django.db.models import Case, DateField, Value, When
    qs = Pm.objects.annotate(
        due_date=Case(
            When(date__lt=today, then=Value(today)),
            default=F("date"),
            output_field=DateField(),
        )
    )
    qs.order_by("due_date")
    

    【讨论】:

    • 那么我认为您需要使用条件表达式在查询集中注释到期日期。然后在due_date使用order_by,我在答案中添加了参考链接。
    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 2021-01-21
    • 1970-01-01
    • 2022-01-21
    • 2020-11-01
    • 2021-10-26
    • 2021-08-21
    • 2018-09-30
    相关资源
    最近更新 更多