简体   繁体   English

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

[英]Django: “missing 1 required positional argument: 'lookup _name'” when it is not missing?

I am working with Django 3.1 ORM and am running (with pytest ) a test involving a complex nested query.我正在使用 Django 3.1 ORM 并且正在运行(使用pytest )一个涉及复杂嵌套查询的测试。 I get this failure:我得到这个失败:

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'

That get_lookup(lookup) to be called is defined (as far as I can see) in django.db.models.query_utils.RegisterLookupMixin as要调用的get_lookup(lookup) ) 在django.db.models.query_utils.RegisterLookupMixin定义(据我所知)为

def get_lookup(self, lookup_name):
    ...

The corresponding source statement of my test involves something like我的测试的相应源语句涉及类似

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

and there is more query construction code around it.并且有更多的查询构造代码围绕它。
My debugger tells me that self.output_field is a DateTimeField object.我的调试器告诉我self.output_field是一个DateTimeField对象。

So overall:所以总的来说:

  • The context is an Exists subquery.上下文是一个Exists子查询。
  • The lookup is 'lte' (as intended).查找是'lte' (如预期)。
  • The call provides a DateTimeField as self (from output_field ) and 'lte' as lookup_name .该调用提供DateTimeField作为self (来自output_field )和'lte'作为lookup_name
  • The method-to-be-called expects self and lookup_name .要调用的方法需要selflookup_name

The call should work, shouldn't it?通话应该有效,不是吗?
Where is the TypeError ? TypeError在哪里?

The comment by @AlexandrTatarinov is right on; @AlexandrTatarinov 的评论是正确的; that was my problem as well;那也是我的问题; myattr is a computed attribute created thusly: myattr是这样创建的计算属性:

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

But for some reason, Django firmly wants a field instance for the output field, not a field class.但出于某种原因,Django 坚定地想要输出字段的字段实例,而不是字段类。 So output_field=DateTimeField() works, but my output_field=DateTimeField does not.所以output_field=DateTimeField()有效,但我的output_field=DateTimeField没有。 Add the parentheses and my problem is solved.添加括号,我的问题就解决了。

Ironically, The output_field= is not even required in this case!具有讽刺意味的是,在这种情况下甚至不需要output_field= Removing it works as well as adding the parens.删除它和添加括号一样有效。

To reflect on my work process, these were my mistakes:回顾我的工作过程,这些是我的错误:

  1. I checked in the debugger that a proper self would be present -- but obviously not carefully enough, mistaking the DateTimeField class for a DateTimeField instance.我在调试器中检查了正确的self会存在——但显然不够仔细,将DateTimeField类误认为是DateTimeField实例。
  2. I had inserted the output_field=DateTimeField clause while I debugged a previous problem, but did not take it out again when it did not help.我在调试以前的问题时插入了output_field=DateTimeField子句,但是当它没有帮助时没有再次取出它。 Bad idea.馊主意。
  3. When I wrote my question, I hesitated when I wrote "My debugger tells me that self.output_field is a DateTimeField object."当我写我的问题时,当我写下“我的调试器告诉我self.output_field是一个DateTimeField对象”时,我犹豫了。 and asked myself "Do I know it is a DateTimeField object and not the DateTimeField class?"并问自己“我知道它是DateTimeField对象而不是DateTimeField类吗?” , but I did not go and look in the debugger again, I only recalled that I had checked it and had been satisfied. ,但我并没有再去调试器里看,我只记得我已经检查过了,已经很满意了。

So my take-home lessons are:所以我带回家的课程是:

  • (from number 2): Don't do half-baked things. (来自第 2 点):不要做半生不熟的事情。
  • (from numbers 1&3): Trust yourself as little as possible. (来自数字 1 和 3):尽可能少相信自己。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM