odoo17开发教程(12):模型之间的关系-多对多many2many

目录

概述

Many2many多对多关系

添加房地产属性标签表

代码实践


概述

在介绍多对多关系之前,我们先补上上一篇文章缺失的一部分代码

在房地产模块中,我们仍然缺少关于房产的两项信息:买方partner和销售人员salesperson。买方可以是任何个人,但另一方面,销售人员必须是房地产公司的员工(即 Odoo 用户)。

在 Odoo 中,我们有两个模型model我们是经常用到的:

res.partner:合作伙伴是一个物理或法律实体。它可以是公司、个人,甚至是一个联系地址。

res.users:系统用户。用户可以是 "内部 "用户,即他们可以访问 Odoo 后台。也可以是 "门户 "用户,即他们不能访问后台,只能访问前台(例如,在电子商务中访问他们以前的订单)。

下面给我们的estate_property模型加上:

user_id = fields.Many2one("res.users", string="Salesperson", default=lambda self: self.env.user)
partner_id = fields.Many2one("res.partner", string="Partner", copy=False)

注意user_id的默认值必须是当前用户。合作伙伴应该不能被复制。

备注

  • 对象 self.env 允许访问请求参数和其他有用信息:
  • self.env.cr 或 self._cr 是数据库游标对象;用于查询数据库
  • 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] 返回给定模型的实例

Many2many多对多关系

在房地产模块中,我们要定义房产标签的概念。例如,"舒适 "或 "装修 "的房产就是房产标签。

一个房产可以有多个标签,一个标签可以分配给多个房产。这可以通过 many2many 概念来实现。

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

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

按照惯例,many2many 字段的后缀是 _ids。这意味着我们可以在测试模型中添加多个税项。它的行为就像一个记录列表,这意味着必须在循环中访问数据:

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

记录列表被称为记录集,即记录的有序集合。它支持标准的 Python 集合操作,如 len() 和 iter(),以及额外的集合操作,如 recs1 | recs2。

添加房地产属性标签表

class EstatePropertyTag(models.Model):
    _name = "estate_property_tag"
    _description = "Estate Property Tag"

    name = fields.Char(required=True)

提示:在视图中,使用 widget="many2many_tags" 属性,如以下代码所示。widget 属性将在后面的培训章节中详细讲解。现在,你可以尝试添加或删除它,看看效果如何;-) 

我们现在新增了settings菜单。

还在房产的详情中新增了tag_ids(毛坯,精装修) 

代码实践

以下是我们现在的estate_property_views.xml的完整代码:

<?xml version="1.0"?>
<odoo>
    <record id="estate_property_action" model="ir.actions.act_window">
        <field name="name">房产列表</field>
        <field name="res_model">estate_property</field>
        <field name="view_mode">tree,form</field>
    </record>
    
    <record id="estate_property_type_action" model="ir.actions.act_window">
        <field name="name">房产类型</field>
        <field name="res_model">estate_property_type</field>
        <field name="view_mode">tree,form</field>
    </record>
    
    <record id="estate_property_tag_action" model="ir.actions.act_window">
        <field name="name">房产标签</field>
        <field name="res_model">estate_property_tag</field>
        <field name="view_mode">tree,form</field>
    </record>

    <record id="estate_property_view_tree" model="ir.ui.view">
        <field name="name">房产列表</field>
        <field name="model">estate_property</field>
        <field name="arch" type="xml">
            <tree string="房产列表">
                <field name="name"/>
                <field name="bedrooms"/>
                <field name="living_area"/>
                <field name="expected_price"/>
                <field name="selling_price"/>
                <field name="date_available"/>
            </tree>
        </field>
    </record>

    <record id="estate_property_view_form" model="ir.ui.view">
        <field name="name">房产详情</field>
        <field name="model">estate_property</field>
        <field name="arch" type="xml">
            <form string="详情">
                <sheet>
                    <div class="oe_title">
                        <h1>
                            <field name="name"/>
                        </h1>
                    </div>
                    <field name="tag_ids" widget="many2many_tags"/>
                    <group name="estate_property_header">
                        <group name="estate_property_details">
                            <group col="2">
                                <field name="property_type_id"/>
                                <field name="postcode"/>
                                <field name="expected_price"/>
                            </group>
                            <group col="2">
                                <field name="date_available"/>
                                <field name="selling_price"/>
                            </group>
                        </group>
                        <notebook>
                            <page string="Description">
                                <group name="estate_property_details">
                                    <field name="description"/>
                                    <field name="bedrooms"/>
                                    <field name="living_area"/>
                                    <field name="facades"/>
                                    <field name="garage"/>
                                    <field name="garden_area"/>
                                    <field name="garden_orientation"/>
                                    <field name="state"/>
                                </group>
                            </page>
                            <page string="Other info">
                                <group name="estate_property_details">
                                    <field name="user_id"/>
                                    <field name="partner_id"/>
                                </group>
                            </page>
                        </notebook>
                    </group>
                </sheet>
            </form>
        </field>
    </record>

    <record id="view_estate_property_search" model="ir.ui.view">
        <field name="name">estate_property</field>
        <field name="model">estate_property</field>
        <field name="arch" type="xml">
            <search string="estate_property">
                <field name="bedrooms" />
                <field name="postcode" />
                <field name="living_area" />
                <field name="property_type_id" />
                <separator/>
                <filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
                <filter string="New or Offer Accepted" name="new_offer_accepted" domain="[('state', 'in', ['new', 'offer_accepted'])]"/>
                <group expand="1" string="Group By">
                    <filter string="邮编分组" name="postcode" context="{'group_by':'postcode'}"/>
                </group>
            </search>
        </field>
    </record>
</odoo>

我们的model模型文件estate_property.py的完整代码如下:

from odoo import models, fields, api
from dateutil.relativedelta import relativedelta

class EstateProperty(models.Model):
    _name = "estate_property"
    _description = "Estate Property"

    def _get_default_date_available(self):
        # 使用 fields.Date.today() 获取当前日期,并添加三个月
        return fields.Date.today() + relativedelta(months=+3)
    
    name = fields.Char(required=True, default="Unknown")
    description = fields.Text()
    postcode = fields.Char()
    date_available = fields.Date(copy=False, default=_get_default_date_available)
    expected_price = fields.Float(required=True)
    selling_price = fields.Float(readonly=True, copy=False)
    bedrooms = fields.Integer()
    living_area = fields.Integer()
    facades = fields.Integer()  # 外墙
    garage = fields.Boolean()
    garden = fields.Boolean()
    garden_area = fields.Integer()
    garden_orientation = fields.Selection([
        ("north", "North"),
        ("south", "South"),
        ("east", "East"),
        ("west", "West"),
    ])
    active = fields.Boolean(default=True)
    state = fields.Selection([
        ("new", "New"),
        ("offer_received", "Offer Received"),
        ("offer_accepted", "Offer Accepted"),
        ("sold", "Sold"),
        ("canceled", "Canceled"),
    ], default="new", copy=False)
    property_type_id = fields.Many2one("estate_property_type", string="Property Type")
    user_id = fields.Many2one("res.users", string="Salesperson", default=lambda self: self.env.user)
    partner_id = fields.Many2one("res.partner", string="Partner", copy=False)
    tag_ids = fields.Many2many("estate_property_tag", string="Tags")


class EstatePropertyType(models.Model):
    _name = "estate_property_type"
    _description = "Estate Property Type"

    name = fields.Char(required=True)

class EstatePropertyTag(models.Model):
    _name = "estate_property_tag"
    _description = "Estate Property Tag"

    name = fields.Char(required=True)

根据之前文章所学的知识,自己修改estate_menus.xml和ir.model.access.csv以达到添加菜单的目的,快自己试试吧!

上一篇 odoo17开发教程(11):模型之间的关系-多对一-CSDN博客

下一篇 odoo17开发教程(13):模型之间的关系-One2many一对多-CSDN博客

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值