Python:从函数中分配对象的变量(OpenERP)

时间:2012-10-09 22:49:24

标签: python openerp

我正在开发一个OpenERP环境,但也许我的问题可以从纯Python的角度来回答。我要做的是定义一个类,其“_columns”变量可以从返回相应字典的函数中设置。所以基本上:

class repos_report(osv.osv):
    _name = "repos.report"
    _description = "Reposition"
    _auto = False

    def _get_dyna_cols(self):
        ret = {}
        cr = self.cr
        cr.execute('Select ... From ...')
        pass           #<- Fill dictionary
        return ret

    _columns = _get_dyna_cols()

    def init(self, cr):
        pass    #Other stuff here too, but I need to set my _columns before as per openerp 

repos_report()

我尝试了很多方法,但这些代码反映了我的基本需求。当我执行我的模块进行安装时,我收到以下错误。

TypeError: _get_dyna_cols() takes exactly 1 argument (0 given)

定义_get_dyna_cols函数时,我需要self作为第一个参数(甚至在执行之前)。另外,我需要一个对openerp的'cr'游标的引用,以便查询数据来填充我的_columns字典。那么,我该如何调用此函数以便将其分配给_columns?我可以将哪个参数传递给此函数?

从OpenERP的角度来看,我想我的需求非常明确。所以建议的任何其他方法也是受欢迎的。

2 个答案:

答案 0 :(得分:4)

从OpenERP的角度来看,正确的解决方案取决于您实际尝试做的事情,而且您的描述并不十分清楚。 通常,模型的_columns定义必须是静态的,因为它将由ORM进行内省,并且(除其他外)将导致创建相应的数据库列。您可以在模型的_columns方法(而非__init__ 1 )中设置init,但这没有多大意义,因为结果不得更改随着时间的推移,(无论如何,只有在初始化模型注册表时才会调用它。)

现在“静态列”规则有一些例外:

功能字段

如果您只想动态处理虚拟列的读/写操作,只需使用fields.function类型的列即可。它需要模拟其他字段类型之一,但可以动态地对数据执行任何操作。典型示例将在一些预处理之后将数据存储在其他(实际)列中。官方OpenERP模块中有数百个示例。

动态列设置

当您开发向导模型(TransientModel的子类,以前为osv_memory)时,您通常不关心数据库存储,只是想从用户那里获得一些输入,采取相应的行动。 在这种情况下,需要一个完全动态的列集并不罕见,其中列的数量和类型可能在每次使用模型时都会发生变化。这可以通过覆盖一些关键的API方法来模拟动态列`:

来实现
  • fields_view_get是客户端调用的API方法,用于获取模型的视图(表单/树/ ...)的定义。
  • fields_get包含在fields_view_get的结果中,但可以单独调用,并返回带有模型列定义的dict
  • 客户端调用
  • searchreadwritecreate以访问和更新记录数据,并应优雅地接受或返回列的值在fields_get
  • 的结果中定义的

通过正确覆盖这些方法,您可以完全实现动态列,但是您需要保留API行为,并在真实静态列或其他模型中自行处理数据的持久性(如果有)。

官方插件中有一些此类动态列集的示例,例如survey模块中需要根据调查活动的定义模拟调查表。

1 init()方法仅在安装或更新模型的模块时调用,以便为此模型设置/更新数据库后端。它依赖于_columns来执行此操作。

答案 1 :(得分:2)

当你在类体中编写_columns = _get_dyna_cols()时,那个函数调用就在那里,在类体中,因为Python仍在解析类本身。此时,您的_get_dyn_cols方法只是本地(类体)命名空间中的一个函数对象 - 并且它被调用。

您收到的错误消息是由于缺少self参数,只有在您将函数作为方法访问时才会插入该参数 - 但此错误消息并不是错误:错误的是您正在进行一个简单的函数调用并期待一个特殊的行为,比如延迟执行。

Python中实现您想要的方式 - 即在访问属性colluns时使用自动调用方法的方法是使用内置的“属性”。 在这种情况下,请执行以下操作:_columns = property(_get_dyna_cols) - 这将创建一个名为“columns”的类属性,通过称为“描述符协议”的机制,只要从实例访问该属性,它就会调用所需的方法。

要了解有关内置属性的更多信息,请查看文档:{​​{3}}