动态显示不同域的多个one2many字段?

时间:2017-04-12 10:39:26

标签: openerp odoo-8

我有一个模型(modelA),其中one2many字段与另一个模型(modelB)相关,而modelB中的一个字段是category字段,这是一个many2one字段。要求是为每个类别显示一个one2many字段。因此,如果有2个名为'category1'和'category2'的类别,modelA的表单视图应该有2个one2many字段,一个显示category1的记录,另一个显示category2的记录(可能使用domain)。

例如modelA和modelB具有以下结构。

class classA(models.Model):
    _name = 'modelA'

    modelA_one2manyfield = fields.One2many('modelB', 'modelB_many2onefield')

class classB(models.Model):
    _name = 'modelB'

    name = fields.Char()
    category = fields.Many2one('modelC')
    modelB_many2onefield = fields.Many2one('modelA')

我如何实现modelA的表单视图,以便每个类别(可以由用户添加,因此可以有任意数量的类别)存在单独的one2many字段。

3 个答案:

答案 0 :(得分:1)

你所要求的是花费大量时间给出一个非常好的答案我认为你需要尝试的方法是覆盖fields_view_get,因为这是一种可以检索视图的方法,你可以在这里更改arch字段以添加costum字段,请查看本教程:

Tutorial for dynamic view

但我认为你会遇到问题,因为即使你把域放在XML中的one2many字段上,odoo也不会过滤 加载发生在视图上的记录:

<!-- here all record are shown but the expected behavior is the one2many should be empty -->
<field name="one2many_field_name" readonly="1" nolabel="1" domain="[('id', '=', False)]">

但是当我将此字段添加到python声明

# here no record will be shown on the view and that's what was expected 
one2many_field_name = fields.One2many(..., domain=[('id', '=', False)]) 

所以通过fields_view_get向one arch添加one2many字段的问题很简单,但问题是过滤数据!!

答案 1 :(得分:1)

技术上不可行。因为在同一视图中不能有相同字段的2倍。

但您可以创建一个特定的小部件来显示您想要的内容。如何在时间表视图中查看(我的当前时间表菜单)。

这是一个创建小部件的小教程。 https://www.odoo.com/documentation/10.0/howtos/web.html#widgets-basics

答案 2 :(得分:1)

这不是答案,但您可以说动态视图的教程示例: 模块结构:

->dynamic_view
    --> __ini__.py
    --> models.py
    --> views.xml
    --> __manifest__.py

__manifest__.py

# -*- coding: utf-8 -*-
        {
            'name' : 'Dynamic view',
            'version' : '1.0',
            'summary': 'Tutorial for Dynamic view',
            'sequence': 30,
            'description': """
             This Module is for showing that you can update the code of the view
             when it's called and even create new field without having to use python
             code at all
            """,
            'category': 'StackOverFlow',
            'depends' : ['base_setup',],
            'data': [
                'views.xml'
            ],
            'installable': True,
            'application': True,
            'auto_install': False,
        }

__init__.py

        # -*- coding: utf-8 -*-
        from . import models

models.py

# -*- coding: utf-8 -*-

        from odoo import models, fields, api


        class Person(models.Model):
            _name = "training.person"

            name = fields.Char("Full name")


        class Car(models.Model):
            _name = "training.car"
            name = fields.Char("Car name")
            mark_id = fields.Many2one(comodel_name="training.mark", string="Mark")
            owner_id = fields.Many2one(comodel_name="training.person", string="Owner")


        person_view_id = "dynamic_view.dgapr_form_person"
        # here default arch value body in the view contains only
        # name field but as we create new mark we add others field
        person_view_arch = """
                <group>
                    <field name="name"/>
                </group>
        """


        class Mark(models.Model):

            _name = "training.mark"

            name = fields.Char("Mark")

            @api.model
            def create(self, values):
                """
                   when we create a category we add one2many field to person view
                   TODO: when we unlink a category we need to remove the one2many
                         name of field is : x_mark_{id of deleted record}
                """
                rec_id = super(Mark, self).create(values)
                o2m_field = {
                    # fields created using orm method must start with x_
                   "name": "x_mark_%s"% rec_id.id,
                   "field_description": "Mark %s" % rec_id.name,
                   "ttype": "one2many",
                   "relation": "training.car",
                   "relation_field": "owner_id",
                   "stored": True,
                   "domain": "[('mark_id','=', %s)]"%rec_id.id,
                   "model_id": self.env.ref("dynamic_view.model_training_person").id,
                }
                # add on2many field to ir.model.fields
                self.env["ir.model.fields"].create(o2m_field)
                self.update_arch()
                return rec_id

            def update_arch(self):
                """
                when ever we create or delete a mark record
                we need to update the the view to add new one2many field
                if we want to hide the one2many field in view that don't have
                any record we should create compute field to use attrs features
                """
                view_id = self.env.ref(person_view_id)
                o2m_fields_ids = self.env['ir.model.fields'].search(
                    [
                        ('model_id', '=', self.env.ref("dynamic_view.model_training_person").id),
                        ('ttype', 'like', 'one2many'),
                        ('relation_field', 'like', 'owner_id')
                     ])
                o2many_arch = ""
                for o2m_id in o2m_fields_ids:
                    o2many_arch = o2many_arch + """

                        <group col="1" string="%s">
                            <field name="%s" noloable="1" />
                        </group>

                        """ % (o2m_id.field_description, o2m_id.name,)

                arch_begin = """
                     <form>
                        <sheet>
                    """
                arch_close = """
                        </sheet>
                     </form>
                     """
                arch_body = person_view_arch + o2many_arch
                new_arch = arch_begin + arch_body + arch_close

                # update the arch of the view in database
                view_id.arch = new_arch

views.xml:

<?xml version="1.0" encoding="utf-8" ?>
        <odoo>
            <data>

                <record id="dgapr_form_car" model="ir.ui.view">
                    <field name="name">car.form</field>
                    <field name="model">training.car</field>
                    <field name="arch" type="xml">
                        <form >
                            <sheet>
                                <group>
                                    <field name="name"/>
                                    <field name="mark_id"/>
                                    <field name="owner_id"/>
                                </group>
                            </sheet>
                        </form>
                    </field>
                </record>

                <record id="dgapr_action_car" model="ir.actions.act_window">
                    <field name="name">Cars</field>
                    <field name="res_model">training.car</field>
                    <field name="view_type">form</field>
                    <field name="view_mode">tree,form</field>
                </record>

                <menuitem id="menu_root_training" name="Training"/>
                <menuitem id="menu_ch_car" name="Cars" parent="menu_root_training" action="dgapr_action_car"/>


                <record id="dgapr_form_person" model="ir.ui.view">
                    <field name="name">dgapr.form.person</field>
                    <field name="model">training.person</field>
                    <field name="arch" type="xml">
                        <form>
                            <sheet>
                                <group>
                                    <field name="name"/>
                                </group>
                            </sheet>
                        </form>
                    </field>
                </record>


            </data>
        </odoo>

我发现你可以使用ORM方法甚至计算字段创建字段。我认为创建一个小部件更好,但很高兴知道wen可以创建costum字段。

希望这有助于你

注意我没有为人员记录创建菜单,但如果新的one2many字段未显示只是刷新页面,则可以通过点击车窗体中的owner_id来查看视图。

Person Form after adding two category and 3 car to charif