2

我正在开发 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 的角度来看,我想我很清楚我的需求。因此,也欢迎任何其他建议的方法。

4

2 回答 2

4

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

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

功能字段

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

动态列集

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

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

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

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

1 The init() method is only called when the model's module is installed or updated, in order to setup/update the database backend for this model. It relies on the _columns to do this.

于 2012-10-10T10:13:50.173 回答
2

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

您收到的错误消息是由于缺少self参数,该参数仅在您将函数作为方法访问时插入 - 但此错误消息不是这里的错误:错误是您正在进行即时函数调用并期望一种特殊行为,例如延迟执行。

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

要了解有关内置属性的更多信息,请查看文档:http ://docs.python.org/library/functions.html#property

于 2012-10-10T03:37:05.517 回答