2

我正在使用 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'(如预期的那样)。
  • 该调用提供DateTimeFieldas self(from output_field) 和'lte'as lookup_name
  • 被调用的方法期望selflookup_name

通话应该有效,不是吗?
在哪里TypeError

4

1 回答 1

0

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

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

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

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

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

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

所以我的带回家的教训是:

  • (从第 2 点开始):不要做半生不熟的事情。
  • (来自数字 1 和 3):尽可能少地相信自己。
于 2021-07-27T10:17:35.760 回答