8

odoo 开发入门教程系列-模型之间的关系(Relations Between Models) - 授客

 1 year ago
source link: https://www.cnblogs.com/shouke/p/17253352.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

模型之间的关系(Relations Between Models)

上一章介绍了为包含基本字段的模型创建自定义视图。然而,在任何真实的业务场景中,我们都需要不止一个模型。此外,模型之间的链接是必要的。人们可以很容易地想象一个模型包含客户,另一个模型则包含用户列表。你可能需要参考任何现有业务模型上的客户或用户。

在我们的estate模块中,我们需要有关房产的以下信息:

  • 购买房产的客户
  • 出售房产的真实重述代理人
  • 房产类型:房子、公寓、顶层公寓、城堡…
  • 显示了该酒店特色的一系列标签:舒适、翻新…
  • 收到的报价清单

Many2one

参考: 本主题相关文档可查阅 Many2one

在我们的房地产模块中,我们想定义房地产类型的概念,例如,房屋或公寓。根据的类型对房地产进行分类是一种标准的业务需求,尤其是为了优化过滤。

一个房产可以有一个类型,但同一类型可以分配给多个房产。这得到了many2one概念的支持。

many2one是指向另一个对象的简单链接。例如,为了在我们的测试模型中定义到 res.partner的连接,我们可以这样写:

partner_id = fields.Many2one("res.partner", string="Partner")

按约定,many2one 字段以_id 后缀。可通过以下方式轻松的访问partner中的数据:

print(my_test_object.partner_id.name)

foreign keys

添加房地产类型表

  • 创建estate.property.type 模型,并添加以下字段:
Field Type Attributes
name Char required
  • 1569452-20230324210205898-403114275.png
  • 添加property_type_idestate.property 模型和表单,树,搜索视图

    1569452-20230324210147919-1875878246.png

该练习是对前几章很好的扼要重述:你需要创建一个 model,设置 model,添加 动作和菜单,并且创建视图.

提示: 别忘记在 __init__.py导入新的Python模块文件,并在__manifest.py__中添加数据或者访问权限。

新增odoo14/custom/estate/models/estate_property_type.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from odoo import models, fields

class EstatePropertyType(models.Model):
    _name = 'estate.property.type'
    _description = 'estate property type'

    name = fields.Char(string='type', required=True)

修改odoo14/custom/estate/models/__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import estate_property
from . import estate_property_type # 新增内容

修改odoo14/custom/estate/security/ir.model.access.csv

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate_model,access_estate_model,model_estate_property,base.group_user,1,1,1,1
access_estate_property_type_model,access_estate_property_type_model,model_estate_property_type,base.group_user,1,1,1,1

修改odoo14/custom/estate/views/estate_menus.view

<?xml version="1.0"?>
<odoo>
    <menuitem id="test_menu_root" name="Real Estate">
        <menuitem id="test_first_level_menu" name="Advertisements">
            <menuitem id="estate_property_menu_action" action="link_estate_property_action"/>
        </menuitem>
        <menuitem id="property_type_first_level_menu" name="Settings">
            <menuitem id="property_type_action" action="estate_property_type_action"/>
        </menuitem>
    </menuitem>
</odoo>

新增odoo14/custom/estate/views/estate_property_type_views.xml

<?xml version="1.0"?>
<odoo>
    <record id="estate_property_type_action" model="ir.actions.act_window">
        <field name="name">Property Types</field>
        <field name="res_model">estate.property.type</field>
        <field name="view_mode">tree,form</field>
    </record>

    <record id="estate_property_type_view_tree" model="ir.ui.view">
        <field name="name">estate.property.type.tree</field>
        <field name="model">estate.property.type</field>
        <field name="arch" type="xml">
            <tree string="PropertyTypes">
                <field name="name" string="Title"/>
            </tree>
        </field>
    </record>
</odoo>

修改odoo14/custom/__manifest__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
    'name': 'estate',
    'depends': ['base'],
    'data':['security/ir.model.access.csv',
            'views/estate_property_views.xml',
            'views/estate_property_type_views.xml', # 新增内容
            'views/estate_menus.xml',
            ]
}

再次重启服务,并刷新查看结果。

1569452-20230324210123736-1723673743.png

新增一条记录

1569452-20230324210111836-724232371.png

修改odoo14/custom/estate/models/estate_property.py ,添加property_type_id

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from odoo import models,fields

class EstateProperty(models.Model):
    _name = 'estate.property'
    _description = 'estate property table'

    name = fields.Char(size=15, required=True)
    description = fields.Text()
    postcode = fields.Char(size=15)
    date_availability = fields.Datetime('Availability Date', copy=False, default= lambda self: fields.Datetime.today())
    expected_price = fields.Float('expected price', digits=(8, 2),  required=True) # 最大8位,小数占2位
    selling_price = fields.Float('selling price', digits=(8, 2), readonly=True, copy=False)
    bedrooms = fields.Integer(default=2)
    living_area = fields.Integer()
    facades = fields.Integer()
    garage = fields.Boolean('garage')
    garden = fields.Boolean('garden')
    garden_area = fields.Integer()
    garden_orientation = fields.Selection(
        string='Orientation',
        selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('West','West')],
        help="garden orientation"
    )
    active = fields.Boolean('Active', default=True, invisible=True)
    state = fields.Selection(
        string='State',
        selection=[('New','New'),
                   ('Offer Received','Offer Received'),
                   ('Offer Accepted', 'Offer Accepted'),
                   ('Sold','Sold'),
                   ('Canceled', 'Canceled')],
        copy=False
    )
    property_type_id = fields.Many2one("estate.property.type", "PropertyType")

修改odoo14/custom/estate/views/estate_property_views.xml treeform视图

<?xml version="1.0"?>
<odoo>
    <record id="link_estate_property_action" model="ir.actions.act_window">
        <field name="name">Properties</field>
        <field name="res_model">estate.property</field>
        <field name="view_mode">tree,form</field>
    </record>

    <record id="estate_property_view_tree" model="ir.ui.view">
        <field name="name">estate.property.tree</field>
        <field name="model">estate.property</field>
        <field name="arch" type="xml">
            <tree string="Tests">
                <field name="name" string="Title"/>
                <field name="postcode" string="Postcode"/>
                <field name="bedrooms" string="Bedrooms"/>
                <field name="living_area" string="Living Area"/>
                <field name="expected_price" string="Expected Price"/>
                <field name="selling_price" string="Selling Price"/>
                <field name="date_availability" string="Avalilable Form"/>
                <field name="property_type_id" string="Property Type"/>
            </tree>
        </field>
    </record>

    <record id="estate_property_view_form" model="ir.ui.view">
        <field name="name">estate.property.form</field>
        <field name="model">estate.property</field>
        <field name="arch" type="xml">
            <form string="estate property form">
                <sheet>
                    <h1>
                        <field name="name"/>
                    </h1>
                    <group>
                        <group>
                            <field name="property_type_id" string="Property Type"/>
                            <field name="postcode" string="Postcode" ></field>
                            <field name="date_availability" string="Available From"></field>
                        </group>
                        <group>
                            <field name="expected_price" string="Expected Price"></field>
                            <field name="selling_price" string="Selling Price"></field>
                        </group>
                    </group>
                    <notebook>
                        <page string="Description">
                            <group>
                                <field name="description"></field>
                                <field name="bedrooms"></field>
                                <field name="living_area"></field>
                                <field name="facades"></field>
                                <field name="garage"></field>
                                <field name="garden"></field>
                                <field name="garden_area"></field>
                                <field name="garden_orientation"></field>
                            </group>
                        </page>
                    </notebook>
                </sheet>
            </form>
        </field>
    </record>

    <record id="estate_property_search_view" model="ir.ui.view">
        <field name="name">estate.property.search</field>
        <field name="model">estate.property</field>
        <field name="arch" type="xml">
            <search string="Estate Property">
                <!-- 搜索 -->
                <field name="name" string="Title" />
                <field name="postcode" string="Postcode"></field>
                <separator/>
                <!-- 筛选 -->
                <filter string="Available" name="state" domain="['|',('state', '=', 'New'),('state', '=', 'Offer Received')]"></filter>
                <filter name="bedrooms" domain="[('bedrooms', '>', 3)]"></filter>
                <filter name="bedrooms and selling_price" domain="[('bedrooms', '>', 2),('selling_price', '>=', 1000)]"></filter>
                <!-- 分组 -->
                <group expand="1" string="Group By">
                    <filter string="朝向" name="garden_orientation" context="{'group_by':'garden_orientation'}"/>
                </group>
            </search>
        </field>
    </record>
</odoo>

重启服务,刷新浏览器验证

1569452-20230324210054760-102745084.png
1569452-20230324210042402-1260201777.png
1569452-20230324210030212-1757920287.png

在房地产模块中,我们仍然缺失两条关于房产的信息:买家和销售人员。买家可以是任何个人,然而,销售人员必须是房产机构的员工(即odoo用户)。

在odoo中,有两种我们经常引用的两种模型:

  • res.partner: 一个partner为一个物理实体或者法人实体。可以是一个公司,个人,甚至是一个联系地址。
  • res.users: 系统用户。可以是内部(internal)用户,也就是说有odoo后端的访问权限,可以是门户(portal)用户,仅可以访问前端(比如访问他们之前的电子商务订单) ,不可以访问后端。

会用上述提到的两种常用model添加买家和销售人员到estate.property模块。将它们添加到form视图中新tab页面。

销售人员的默认值必须是当前用户。买家不能被复制。

提示:要获取默认值,请查看下面的注解或查看示例

user_id = fields.Many2one('res.users', string='Salesperson', index=True, tracking=True, default=lambda self: self.env.user)

self.env 对象为其它请求参数和其它有用的东西提供了访问权限:

  • self.env.cr 或者self._cr 为数据库游标(cursor)对象。用于查询数据库
  • self.env.uid 或者self._uid 当前用户数据库ID
  • self.env.user 当前用户记录
  • self.env.context 或者self._context 上下文字典
  • self.env.ref(xml_id) 返回和XML id对应的记录
  • self.env[model_name] 返回给定模型的实例

修改odoo14\custom\estate\models\estate_property.py,内容如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from odoo import models,fields

class EstateProperty(models.Model):
    _name = 'estate.property'
    _description = 'estate property table'

    name = fields.Char(required=True)
    description = fields.Text()
    postcode = fields.Char(size=15)
    date_availability = fields.Datetime('Availability Date', copy=False, default= lambda self: fields.Datetime.today())
    expected_price = fields.Float('expected price', digits=(8, 2),  required=True) # 最大8位,小数占2位
    selling_price = fields.Float('selling price', digits=(8, 2), readonly=True, copy=False)
    bedrooms = fields.Integer(default=2)
    living_area = fields.Integer()
    facades = fields.Integer()
    garage = fields.Boolean('garage')
    garden = fields.Boolean('garden')
    garden_area = fields.Integer()
    garden_orientation = fields.Selection(
        string='Orientation',
        selection=[('north', 'North'), ('south', 'South'), ('east', 'East'), ('West','West')],
        help="garden orientation"
    )
    active = fields.Boolean('Active', default=True, invisible=True)
    state = fields.Selection(
        string='State',
        selection=[('New','New'),
                   ('Offer Received','Offer Received'),
                   ('Offer Accepted', 'Offer Accepted'),
                   ('Sold','Sold'),
                   ('Canceled', 'Canceled')],
        copy=False
    )
    property_type_id = fields.Many2one("estate.property.type", string="PropertyType")
    # 以下为本次新增内容
    salesman_id = fields.Many2one("res.users", string="Salesman")
    buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False, default=lambda self: self.env.user)

修改odoo14\custom\estate\views\estate_property_views.xmlnotebook内容为如下:

                    <notebook>
                        <page string="Description">
                            <group>
                                <field name="description"></field>
                                <field name="bedrooms"></field>
                                <field name="living_area"></field>
                                <field name="facades"></field>
                                <field name="garage"></field>
                                <field name="garden"></field>
                                <field name="garden_area"></field>
                                <field name="garden_orientation"></field>
                            </group>
                        </page>
                        <page string="Other info">
                            <group>
                                <field name="salesman_id" string="Salesman"></field>
                                <field name="buyer_id" string="Buyer"></field>
                            </group>
                        </page>
                    </notebook>

重启服务,浏览器中验证

1569452-20230324210007769-816669312.png

Many2many

参考:和本主题关联的文档可参考Many2many.

在我们的房地产模块中,我们想定义房产标签的概念。例如,房地产是“舒适”或是“翻新”的

一个地产可以有多个标签,一个标记可以分配给多个房产。这得到了many2many概念的支持。

many2many是一种双向多重关系:一侧的任何记录都可以与另一侧的任何数量的记录相关。例如,为了在我们的测试模型中定义到 account.tax的链接,我们可以这样写:

tax_ids = fields.Many2many("account.tax", string="Taxes")

按约定,many2many字段拥有_ids 后缀。这意味着可以将多个"tax"添加到我们的测试模型。它表现为一个记录列表,意味着必须通过循环访问数据:

for tax in my_test_object.tax_ids:
    print(tax.name)

记录列表即为众所周知的recordset,即记录的有序集合。它支持标准Python的集合操作,如len()iter(),以及recs1 | recs2等额外的集合操作。

添加房产标签表

  • 创建estate.property.tag 模型和并添加以下字段:
Field Type Attributes
name Char required
1569452-20230324205948808-596271488.png
  • 添加 tag_idsestate.property 模型,表单和列表视图
1569452-20230324205932585-1078038027.png

提示: 视图中,使用 widget="many2many_tags"属性正如这里展示的一样。

<group string="Website Traffic Conditions">
    <field name="country_ids" widget="many2many_tags"/>
    <field name="website_id" options="{'no_open': True, 'no_create_edit': True}" groups="website.group_multi_website"/>
    ...
</group>

添加odoo14\custom\estate\models\estate_property_tag.py,内容如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from odoo import models, fields

class EstatePropertyTag(models.Model):
    _name = 'estate.property.tag'
    _description = 'estate property tag'

    name = fields.Char(string='tag', required=True)

修改odoo14\custom\estate\models\__init__.py,内容如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import estate_property
from . import estate_property_type
from . import estate_property_tag # 本次新增内容

修改odoo14\custom\estate\security\ir.model.access.csv,内容如下:

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate_model,access_estate_model,model_estate_property,base.group_user,1,1,1,1
access_estate_property_type_model,access_estate_property_type_model,model_estate_property_type,base.group_user,1,1,1,1
access_estate_property_tag_model,access_estate_property_tag_model,model_estate_property_tag,base.group_user,1,1,1,1

修改odoo14/custom/estate/views/estate_menus.view

<?xml version="1.0"?>
<odoo>
    <menuitem id="test_menu_root" name="Real Estate">
        <menuitem id="test_first_level_menu" name="Advertisements">
            <menuitem id="estate_property_menu_action" action="link_estate_property_action"/>
        </menuitem>
        <menuitem id="settings_menu" name="Settings">
            <menuitem id="property_type_action" action="estate_property_type_action"/>
            <!-- 本次新增内容 -->
            <menuitem id="property_tag_action" action="estate_property_tag_action"/>
        </menuitem>        
    </menuitem>
</odoo>

新增odoo14/custom/estate/views/estate_property_tag_views.xml

<?xml version="1.0"?>
<odoo>
    <record id="estate_property_tag_action" model="ir.actions.act_window">
        <field name="name">Property Tags</field>
        <field name="res_model">estate.property.tag</field>
        <field name="view_mode">tree,form</field>
    </record>

    <record id="estate_property_tag_view_tree" model="ir.ui.view">
        <field name="name">estate.property.tag.tree</field>
        <field name="model">estate.property.tag</field>
        <field name="arch" type="xml">
            <tree string="PropertyTags">
                <field name="name" string="tag"/>
            </tree>
        </field>
    </record>
</odoo>

修改odoo14/custom/estate/__manifest__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
    'name': 'estate',
    'depends': ['base'],
    'data':['security/ir.model.access.csv',
            'views/estate_property_views.xml',
            'views/estate_property_type_views.xml',
            'views/estate_property_tag_views.xml', # 本次新增内容
            'views/estate_menus.xml',
            ]
}

重启服务,刷新浏览器验证,效果如下

1569452-20230324205911698-628372524.png

添加2条记录,供下文使用

1569452-20230324205858943-490357001.png

修改odoo14/custom/estate/models/estate_property.py ,末尾添加property_tag_id

    tag_ids = fields.Many2many("estate.property.tag")

修改odoo14\custom\estate\views\estate_property_views.xmlestate_property_view_form视图

    <record id="estate_property_view_form" model="ir.ui.view">
        <field name="name">estate.property.form</field>
        <field name="model">estate.property</field>
        <field name="arch" type="xml">
            <form string="estate property form">
                <sheet>
                    <h1>
                        <field name="name"/>
                    </h1>
                    <!--<p>元素为本次添加内容-->
                    <p>
                        <field name="tag_ids" widget="many2many_tags"/>
                    </p>
                    <group>
                        <group>
                            <field name="property_type_id" string="Property Type"/>
                            <field name="postcode" string="Postcode" ></field>
                            <field name="date_availability" string="Available From"></field>
                        </group>
                        <group>
                            <field name="expected_price" string="Expected Price"></field>
                            <field name="selling_price" string="Selling Price"></field>
                        </group>
                    </group>
                    <notebook>
                        <page string="Description">
                            <group>
                                <field name="description"></field>
                                <field name="bedrooms"></field>
                                <field name="living_area"></field>
                                <field name="facades"></field>
                                <field name="garage"></field>
                                <field name="garden"></field>
                                <field name="garden_area"></field>
                                <field name="garden_orientation"></field>
                            </group>
                        </page>
                        <page string="Other info">
                            <group>
                                <field name="salesman_id" string="Salesman"></field>
                                <field name="buyer_id" string="Buyer"></field>
                            </group>
                        </page>
                    </notebook>
                </sheet>
            </form>
        </field>
    </record>

重启服务,验证效果

1569452-20230324205837882-1160327704.png
1569452-20230324205815677-620327033.png

One2many

参考:主题关联文档可以参考One2many

在我们的房地产模块中,我们想定义房产报价的概念。房地产报价是潜在买家向卖家提供的金额。报价可能低于或高于预期价格。

报价适用于一个房产,但同一个房产可以有多个报价。many2one的概念再次出现。然而,在本例中,我们希望显示给定地产的报价列表,因此我们将使用one2many概念。

one2manymany2one的反向实现。例如,我们通过partner_id字段,在测试模型上定义了到res.partner模型的链接。我们可以定义反向关系,即与partner链接的测试模型列表:

test_ids = fields.One2many("test.model", "partner_id", string="Tests")

第一个参数叫做comodel,第二个参数是我们用于反向查询的字段。

按照惯例,one2many字段都有_ids后缀。它们表现为记录列表,这意味着访问数据必须在循环中完成:

for test in partner.test_ids:
    print(test.name)

注意

One2many 是一种虚拟的关系,必须在comodel,必须在comodel中定义Many2one 字段

添加房地产报价表

  • 创建 estate.property.offer 模型,并添加以下字段:
Field Type Attributes Values
price Float
status Selection no copy Accepted, Refused
partner_id Many2one (res.partner) required
property_id Many2one (estate.property) required
  • 使用pricepartner_idstatus字段创建列表和表单视图 ,不必创建动作和菜单

  • 添加offer_ids字段到estate.property 模型极其表单视图

这里有几件重要的事情需要注意。首先,我们不需要所有模型的操作或菜单。某些模型只能通过另一个模型访问。在我们的练习中就是这样的:报价总是通过房产获得的。

其次,尽管property_id字段是必需的,但我们没有将其包含在视图中。odoo如何知道我们的报价与哪个房产相关?这就是使用odoo框架的一部分魔力:有时候事情是隐式定义的。当我们通过one2many字段创建记录时,为了方便,会自动填充相应的many2one

添加odoo14\custom\estate\models\estate_property_offer.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from odoo import models, fields

class EstatePropertyOffer(models.Model):
    _name = 'estate.property.offer'
    _description = 'estate property offer'

    price = fields.Float(string='Price')
    status = fields.Selection(string='Status',
                              selection=[('Accepted', 'Accepted'), ('Refused', 'Refused')],
                              copy=False
                              )
    partner_id = fields.Many2one('res.partner', required=True)
    property_id = fields.Many2one('estate.property', required=True)

添加odoo14\custom\estate\views\estate_property_offer_views.xml

<?xml version="1.0"?>
<odoo>
    <record id="estate_property_offer_view_tree" model="ir.ui.view">
        <field name="name">estate.property.offer.tree</field>
        <field name="model">estate.property.offer</field>
        <field name="arch" type="xml">
            <tree string="PropertyOffers">
                <field name="price" string="Price"/>
                <field name="partner_id" string="partner ID"/>
                <field name="validity" string="Validity(days)"/>
                <field name="deadline" string="Deadline"/>
                <field name="status" string="Status"/>
            </tree>
        </field>
    </record>
    <record id="estate_property_offer_view_form" model="ir.ui.view">
        <field name="name">estate.property.offer.form</field>
        <field name="model">estate.property.offer</field>
        <field name="arch" type="xml">
            <form string="estate property offer form">
                <sheet>
                    <group> 
                        <field name="price" string="Price"/>
                        <field name="validity" string="Validity(days)"/>
                        <field name="deadline" string="Deadline"/>
                        <field name="partner_id" string="partner ID"/>
                        <field name="status" string="Status"/>
                    </group>
                </sheet>
            </form>
        </field>
    </record>
</odoo>

修改odoo14\custom\estate\__manifest__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-
{
    'name': 'estate',
    'depends': ['base'],
    'data':['security/ir.model.access.csv',
            'views/estate_property_views.xml',
            'views/estate_property_type_views.xml',
            'views/estate_property_tag_views.xml',
            'views/estate_property_offer_views.xml', # 本次新增内容
            'views/estate_menus.xml',
            ]
}

修改odoo14\custom\estate\models\__init__.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

from . import estate_property_type
from . import estate_property_tag
from . import estate_property_offer
from . import estate_property

修改odoo14\custom\estate\security\ir.model.access.csv

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate_model,access_estate_model,model_estate_property,base.group_user,1,1,1,1
access_estate_property_type_model,access_estate_property_type_model,model_estate_property_type,base.group_user,1,1,1,1
access_estate_property_tag_model,access_estate_property_tag_model,model_estate_property_tag,base.group_user,1,1,1,1
access_estate_property_offer_model,access_estate_property_offer_model,model_estate_property_offer,base.group_user,1,1,1,1

修改odoo14\custom\estate\models\estate_property.py,最末尾添加offer_ids字段,如下

    offer_ids = fields.One2many("estate.property.offer", "property_id", string="PropertyOffer")

修改odoo14\custom\estate\views\estate_property_views.xmlestate_property_view_form表单视图

    <record id="estate_property_view_form" model="ir.ui.view">
        <field name="name">estate.property.form</field>
        <field name="model">estate.property</field>
        <field name="arch" type="xml">
            <form string="estate property form">
                <sheet>
                    <h1>
                        <field name="name"/>
                    </h1>
                    <p>
                        <field name="tag_ids" widget="many2many_tags"/>
                    </p>
                    <group>
                        <group>
                            <field name="property_type_id" string="Property Type"/>
                            <field name="postcode" string="Postcode" ></field>
                            <field name="date_availability" string="Available From"></field>
                        </group>
                        <group>
                            <field name="expected_price" string="Expected Price"></field>
                            <field name="selling_price" string="Selling Price"></field>
                        </group>
                    </group>
                    <notebook>
                        <page string="Description">
                            <group>
                                <field name="description"></field>
                                <field name="bedrooms"></field>
                                <field name="living_area"></field>
                                <field name="facades"></field>
                                <field name="garage"></field>
                                <field name="garden"></field>
                                <field name="garden_area"></field>
                                <field name="garden_orientation"></field>
                            </group>
                        </page>
                        <page>
                            <field name="offer_ids" />
                        </page>
                        <page string="Other info">
                            <group>
                                <field name="salesman_id" string="Salesman"></field>
                                <field name="buyer_id" string="Buyer"></field>
                            </group>
                        </page>
                    </notebook>
                </sheet>
            </form>
        </field>
    </record>

重启服务,浏览器中验证

1569452-20230324205745684-1148728902.png

点击"Add a line" 添加记录

1569452-20230324205722560-931406416.png
1569452-20230324205621464-1945900808.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK