Django:“缺少1个必需的位置参数:'lookup _name'”,当它没有丢失时?
Posted
技术标签:
【中文标题】Django:“缺少1个必需的位置参数:\'lookup _name\'”,当它没有丢失时?【英文标题】:Django: "missing 1 required positional argument: 'lookup _name'" when it is not missing?Django:“缺少1个必需的位置参数:'lookup _name'”,当它没有丢失时? 【发布时间】:2021-10-02 15:21:49 【问题描述】:我正在使用 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
。
要调用的方法需要self
和lookup_name
。
调用应该有效,不是吗?TypeError
在哪里?
【问题讨论】:
myattr
和 myattr2
是什么?我能够重现类似的错误,问题是 self.output_field
是一个类,而不是应有的实例,因此缺少默认 self
,因此缺少 lookup_name
只是好奇,为什么这里是双 OuterRef
? OuterRef(OuterRef('myattr2'))
@bdbd 内部OuterRef
转义了问题中显示的Exists
。外部OuterRef
转义了另一个Exists
not,它是我提到的“围绕它的更多查询构造代码”的一部分。
【参考方案1】:
@AlexandrTatarinov 的评论是正确的;这也是我的问题; myattr
是这样创建的计算属性:
annotate(myattr=Subquery(queryset3,
output_field=DateTimeField))
但出于某种原因,Django 坚决希望输出字段的字段实例,而不是字段类。
所以output_field=DateTimeField()
有效,但我的output_field=DateTimeField
无效。
添加括号,我的问题就解决了。
具有讽刺意味的是,在这种情况下甚至不需要output_field=
!删除它和添加括号一样有效。
反思我的工作过程,这些是我的错误:
-
我在调试器中检查了正确的
self
是否存在 - 但显然不够仔细,将 DateTimeField
类误认为是 DateTimeField
实例。
我在调试之前的问题时插入了output_field=DateTimeField
子句,但是当它没有帮助时没有再次取出它。坏主意。
当我写下我的问题时,我犹豫了“我的调试器告诉我self.output_field
是一个DateTimeField
对象。” 并问自己“我知道它是DateTimeField
对象而不是 DateTimeField
类?”,但我没有再去调试器中查看,我只记得我检查过它并且很满意。
所以我的带回家的课程是:
(来自第 2 条):不要做半生不熟的事情。 (来自数字 1 和 3):尽可能少相信自己。【讨论】:
以上是关于Django:“缺少1个必需的位置参数:'lookup _name'”,当它没有丢失时?的主要内容,如果未能解决你的问题,请参考以下文章