Django:“缺少 1 个必需的位置参数:'lookup _name'”当它没有丢失时?

问题描述

我正在使用 Django 3.1 ORM 并且正在运行(使用 pytest一个涉及复杂嵌套查询的测试。我遇到了这个失败:

self = <django.db.models.expressions.Subquery object at 0x0000027CE184D2B0>
lookup = 'lte'

    def get_lookup(self,lookup):
>       return self.output_field.get_lookup(lookup)
E       TypeError: get_lookup() missing 1 required positional argument: 'lookup_name'

调用get_lookup(lookup)django.db.models.query_utils.RegisterLookupMixin 中定义为(据我所知)

def get_lookup(self,lookup_name):
    ...

我的测试对应的源语句涉及到类似

value = Now() - OuterRef(OuterRef('myattr2')) * timedelta(days=1)
queryset2.annotate(has_x=Exists(queryset.filter(myattr__lte=value)))

还有更多的查询构造代码
我的调试器告诉我 self.output_field一个 DateTimeField 对象。

总体来说:

  • 上下文是一个 Exists查询
  • 查找是 'lte'(如预期)。
  • 调用提供 DateTimeField 作为 self(来自 output_field)和 'lte' 作为 lookup_name
  • 调用方法需要 selflookup_name

呼叫应该有效,不是吗?
TypeError 在哪里?

解决方法

@AlexandrTatarinov 的评论是正确的;那也是我的问题; myattr 是这样创建的计算属性:

annotate(myattr=Subquery(queryset3,output_field=DateTimeField))

但出于某种原因,Django 坚定地想要输出字段的字段实例,而不是字段类。 所以 output_field=DateTimeField() 有效,但我的 output_field=DateTimeField 无效。 添加括号,我的问题就解决了。

具有讽刺意味的是,在这种情况下甚至不需要 output_field=!删除它和添加括号一样有效。

反思我的工作过程,这些是我的错误:

  1. 我在调试器中检查了正确的 self 是否存在——但显然不够仔细,将 DateTimeField 类误认为是 DateTimeField 实例。
  2. 我在调试以前的问题时插入了 output_field=DateTimeField 子句,但在没有帮助时没有再次取出它。坏主意。
  3. 当我写下我的问题时,当我写下“我的调试器告诉我 self.output_field 是一个 DateTimeField 对象。” 并问自己 “Do我知道它是一个 DateTimeField 对象而不是 DateTimeField 类?”,但我没有再去调试器中查看,我只记得我已经检查过它并且已经很满意。

所以我带回家的课程是:

  • (来自第 2 点):不要做半生不熟的事情。
  • (来自数字 1 和 3):尽可能少相信自己。