是否可以覆盖Model或Polymodel的all()方法以包含过滤器?

时间:2013-10-11 23:58:21

标签: python google-app-engine

我正在开发一个由其他人编写(并放弃)的大型项目,需要一种方法来对特定模型的.all()进行每次调用,并检查我添加的布尔值。整个项目总共有成千上万的电话,所以我一直在寻找一种方法来避免重写它们。

我的想法是覆盖.all()方法,使用过滤器调用父.all()。这是我第一次使用Google App Engine,所以我做了大量的猜测工作。

我以为我可以从这样的事情开始:

class Bob(polymodel.PolyModel):
    stuff = db.StringProperty()
    active = db.BooleanProperty(default=False)
    def all(self, keys_only=False):
        super(Bob,self).all()

但是当我尝试这样打电话时:

joes = Bob.all()
    for joe in joes:
        self.response.write(joe.active)

我明白了:

TypeError:必须使用Bob实例作为第一个参数调用unbound方法all()(没有任何内容)

这是我关于stackoverflow的第一篇文章,所以我希望我已经正确完成了这一点。任何帮助将不胜感激。

解决方案(稍后补充)

class Bob(db.Model):
    stuff = db.StringProperty()
    active = db.BooleanProperty(default=False)
    @classmethod
    def all(cls, keys_only=False):
        if keys_only == True:
            qry = super(Bob,cls).all(keys_only=True)
            qry.filter('active =', True)
            return qry
        else:
            qry = super(Bob,cls).all(keys_only=False)
            qry.filter('active =', True)
            return qry

2 个答案:

答案 0 :(得分:1)

首先,你有一个基本的python类/方法问题。由于错误显示为TypeError: unbound method all() must be called with Bob instance as first argument (got nothing instead)

您在类上调用all()而不是实例,但您已将重写的all()定义为实例方法。

应该是

@classmethod
def all(cls, keys_only=False):
    qry = super(Bob,cls).all(keys_only=keys_only)
    qry.filter(<some filter>)
    return qry

另请注意,在您的代码中,您不会返回任何内容。 all()返回一个查询对象,您也可以应用其他过滤器。

我不会覆盖所有并应用过滤器,因为您将有效地阻止您能够使用裸全部()

创建另一个classmethod即。 filtered_all()并使用它,以便你可以保持all()。

e.g。

@classmethod
def filtered_all(cls,keys_only=False) 
    qry = cls.all(keys_only)
    qry.filter('some boolean operation')
    return qry

另外,如果您没有对db的投资,我个人认为您应该切换到ndb。

答案 1 :(得分:0)

Tim的回答是对的,但是因为你只有一个类,或者只有少数几个类,你可以轻松地在Bob.all()上进行搜索和替换,并将其更改为Bob.filter(yournewboolean = True)。

任何体面的文本编辑器或IDE都能在一分钟内为您完成此任务。