Django在对查询使用len()时给出TypeError

2024-10-01 09:36:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个非常简单的应用程序来存储足球比赛的结果,我遇到了以下问题。运行其中一个单元测试时,以下代码:

listCompetition = Competition.objects.filter(compId=competitionId)
if len(listCompetition) == 0:
   #some code here
else:
   #some code here

给出以下错误:

^{pr2}$

但是,如果我将第一行代码替换为:

listCompetition = list(Competition.objects.filter(compId=competitionId))

那么它就完美地工作了。为什么它会表现得这么奇怪?如果我在类Competition的构造函数中只定义了两个参数,那么Django为什么要传递4个参数?如果有帮助的话,下面是类竞争的模型定义:

class Competicion(MultiName):
   def __init__(self, canonicalName, compId):
      super(Competition, self).__init__(canonicalName, compId)

class MultiName(models.Model):
   entId = models.CharField(null=True, max_length=25); 
   canonicalName = models.CharField(max_length=50, primary_key=True);

   def __init__(self, canonicalName, entId=None):
      super(MultiName, self).__init__()
      self.canonicalName = canonicalName;
      self.entId = entId;

非常感谢。在


Tags: 代码selfobjectsinitmodelscodesomefilter
3条回答

它之所以被破坏,是因为您在重写__init__时破坏了Django模型使用的约定。为什么要实现__init__?你正在实施的是……已经实施了。在

你似乎在假设如何使用Django是没有根据的。我建议你在继续之前阅读tutorial。在

若要修复代码,请将其更改为以下内容:

class Competition(MultiName):
    def __init__(self, *args, **kwargs):
        if "compId" in kwargs:
            kwargs["entId"] = kwargs.pop("compId")
        super(Competition, self).__init__(*args, **kwargs)

class MultiName(models.Model):
    entId = models.CharField(null=True, max_length=25); 
    canonicalName = models.CharField(max_length=50, primary_key=True);

这里面有很多great documentation for models的内容。在

简单:在第一个例子中,您得到的是一个queryset对象,而不是一个列表。查询集是迭代器。列表对象也是迭代器,但迭代器不是列表。在

Django这样做是为了优化内存和性能:数据库保留集合,Django每次从queryset请求一个对象时,每次读取一个响应项。使用list()会导致Django读取整个响应并将其打包到一个list对象中。如果返回集非常大,这可能会有问题。在

要知道查询集有多大,请改用Queryset.count()方法。在

而不是

if len(listCompetition) == 0:

使用

^{pr2}$

或者也许

if not listCompetition.exists():

相关问题 更多 >