Odoo 8-从python方法启动ir.actions.act_window吗?

edk*_*lel 3 odoo odoo-8

是否可以从模型的Python方法启动ir.actions.act_window?例如,我已经实现了代表课程会话的Session模型(我也有Course模型)。另外,我还有一个openacademy.xml,其中定义了窗体视图以打开会话窗体视图。

<record model="ir.ui.view" id="session_form_view">
      <field name="name">session.form</field>
      <field name="model">openacademy.session</field>
      <field name="arch" type="xml">
        <form>
          <header>
            <button name="draft" type="workflow"
                    string="Reset to draft"
                    states="confirmed,done"/>
            <button name="confirm" type="workflow"
                    string="Confirm" states="draft"
                    class="oe_highlight"/>
            <button name="done" type="workflow"
                    string="Mark as done" states="confirmed"
                    class="oe_highlight"/>
            <button type="object"
                    name="my_method"
                    string="New course"/>
            <field name="state" widget="statusbar"/>
          </header>
          <sheet>
            <group string="General">
              <field name="name" string="Session name"/>
              <field name="course_id" string="Course"/>
              <field name="instructor_id" string="Instructor"/>
            </group>
            <group string="Management">
              <field name="start_date" string="Start date"/>
              <field name="active" string="Active"/>
              <field name="duration" string="Duration (in days)"/>
              <field name="seats"/>
              <field name="percent_taken_seats" widget="progressbar"/>
            </group>
            <label for="attendees"/>
            <field name="attendees"/>
          </sheet>
        </form>
      </field>
    </record>
Run Code Online (Sandbox Code Playgroud)

上面的代码的相关部分如下:

<button type="object" name="my_method" string="New course"/>

当我单击此按钮时,将调用Session模型(Session类)中的方法“ my_method”。

class Session(models.Model):
...

    @api.one
    def my_method(self):
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'openacademy.course',
            'view_type': 'form',
            'view_mode': 'form',
            'target': 'new',
        }
Run Code Online (Sandbox Code Playgroud)

此方法返回一个字典,其中包含窗口动作的不同键和值,但在Odoo 8中不起作用。当我单击“新建课程”按钮时,将执行my_method,但未打开“课程”窗体视图进行创建新的课程记录。

我不知道在Odoo版本8中是否可以执行此操作,或者my_method是否必须返回更多内容。

Loï*_*oix 5

问题出在装饰器上@api.one。一个装饰器将方法的结果包装成这样的字典:

{res_id: result}
Run Code Online (Sandbox Code Playgroud)

这意味着在您的情况下,您实际上正在返回

{res_id: act_window}
Run Code Online (Sandbox Code Playgroud)

或者直接在数组中调用:[act_window]

不幸的是,odoo期望结果本身(有时会返回的实际结果)。

在您的情况下,您应该改用以下方法:

@api.multi
def my_method(self):
    self.ensure_one()
    return {
        'type': 'ir.actions.act_window',
        'res_model': 'openacademy.course',
        'view_type': 'form',
        'view_mode': 'form',
        'target': 'new',
    }
Run Code Online (Sandbox Code Playgroud)

self.ensure_one在这种情况下不是特别必要,但真正重要的是使用@api.multi。它不会将结果包装在任何内容中,而不会像返回的那样完全返回您返回的内容api.one

就个人而言,我更喜欢使用,api.multi因为api.multi在任何情况下都可以保持清洁。当我开始使用时,@api.one我在很多地方遇到了类似以下问题:

val = self._compute_something()[0]
Run Code Online (Sandbox Code Playgroud)

您必须在哪里获得第一个元素,因为odoo将其包装到列表中……同时@api.multi更加灵活,如果您真的想强制使用一个元素来调用它,则可以随时使用ensure_one