• odoo context上下文用法总结


    环境

    odoo-14.0.post20221212.tar

    context用法总结

    获取上下文

    >>> self.env.context # 返回字典数据,等价于 self._context
    {'lang': 'en_US', 'tz': 'Europe/Brussels'}
    >>> self._context
    {'lang': 'en_US', 'tz': 'Europe/Brussels'}
    >>> recordSet.env.context  # 注意,上下文是和记录集绑定的,上述的self也代表记录集
    

    设置上下文

    Model.with_context([context][, **overrides]) -> records[源代码]

    返回附加到扩展上下文的此记录集的新版本。

    扩展上下文是提供的合并了overridescontext,或者是合并了overrides当前context

    # current context is {'key1': True}
    r2 = records.with_context({}, key2=True)
    # -> r2._context is {'key2': True}
    r2 = records.with_context(key2=True)
    # -> r2._context is {'key1': True, 'key2': True}
    

    需要注意的是,上下文是和记录集绑定的,修改后的上下文并不会在其它记录集中共享

    应用场景示例

    用于action,为关联视图添加默认搜索、过滤条件

    视图定义

    为设置action打开的tree列表视图,添加默认搜索,搜索条件为 state字段值等于True

    
    <odoo>
        <record id="link_estate_property_action" model="ir.actions.act_window">
            <field name="name">Propertiesfield>
            <field name="res_model">estate.propertyfield>
            <field name="view_mode">tree,formfield>
            <field name="context">{'search_default_state': True}field>
        record>
    
        <record id="estate_property_search_view" model="ir.ui.view">
            <field name="name">estate.property.searchfield>
            <field name="model">estate.propertyfield>
            <field name="arch" type="xml">
                <search>
                    
                    <field name="name" string="Title" />               
                    <separator/>
                    
                    <filter string="Available" name="state" domain="['|',('state', '=', 'New'),('state', '=', 'Offer Received')]">filter>               
                search>
            field>
        record>
        
    odoo>
    

    说明:

    <field name="context">{'search_default_fieldName': content}field>
    

    search_default_fieldName,其中fieldName 表示过滤器名称,即搜索视图中定义的元素的name属性值

    content 如果fieldName为搜索字段name属性值,那么content表示需要搜索的内容,输入内容是字符串,则需要添加引号,形如'test';如果fieldName为搜索过滤器name属性值,那么content表示布尔值,该值为真,则表示默认开启name所代表的过滤器,否则不开启。

    用于搜索视图,添加分组查询条件

    视图设计
    
    <odoo>
        
        <record id="estate_property_search_view" model="ir.ui.view">
            <field name="name">estate.property.searchfield>
            <field name="model">estate.propertyfield>
            <field name="arch" type="xml">
                <search>                              
                    
                    <group expand="1" string="Group By">
                        <filter string="朝向" name="garden_orientation" context="{'group_by':'garden_orientation'}"/>
                    group>
                search>
            field>
        record>
        
    odoo>
    

    说明:'group_by': '分组字段名称'

    用于视图对象按钮,传递数据给模型方法

    模型设计
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from odoo import models, fields, api
    
    class EstatePropertyType(models.Model):
        _name = 'estate.property.type'
        _description = 'estate property type'
    
        name = fields.Char(string='name', required=True, help='help text')
        property_ids = fields.One2many('estate.property', 'property_type_id')
        offer_ids = fields.One2many('estate.property.offer', 'property_type_id')
        offer_count = fields.Integer(compute='_compute_offer_count')
    
        @api.depends('offer_ids.price')
        def _compute_offer_count(self):
            for record in self:
                record.offer_count = len(record.mapped('offer_ids.price'))
       
        @api.model
        def action_confirm(self, *args):
            print(self, self.env.context, args)
            # ... do something else
    
    视图设计
    
    <odoo>
        
        <record id="estate_property_type_view_form" model="ir.ui.view">
            <field name="name">estate.property.type.formfield>
            <field name="model">estate.property.typefield>
            <field name="arch" type="xml">
                <form string="Property Type">
                    <sheet>
                        
                        <field name="offer_count">
                        <field name="property_ids">
                            <tree string="Properties">
                                <field name="name"/>
                                <field name="expected_price" string="Expected Price"/>
                                <field name="state" string="Status"/>
                            tree>
                        field>
                        <footer>
                           <button name="action_confirm" type="object" context="{'currentRecordID': active_id, 'offer_count':offer_count, 'property_ids': property_ids}" string="确认" class="oe_highlight"/>
                        footer>
                    sheet>
                form>
            field>
        record>
    odoo>
    

    说明:context属性值中的字典的键值如果为模型中定义的字段名称,则该字段名称必须以元素的形式,出现在模型对应的视图(即不能是内联视图,比如内联Tree列表)中,否则会出现类似错误提示:

    Field offer_count used in context.offerCount ({'offerCount': offer_count}) must be present in view but is missing.
    

    点击界面按钮后,服务端打印日志如下

    estate.property.type() {'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 2, 'allowed_company_ids': [1], 'params': {'action': 165, 'cids': 1, 'id': 1, 'menu_id': 70, 'model': 'estate.property.type', 'view_type': 'form'}, 'currentRecordID': 1, 'offer_count': 4, 'property_ids': [[4, 49, False], [4, 48, False]]} ([1],)
    

    说明:args 从日志来看,args接收了当前记录ID

    注意:

    • 如果将def action_confirm(self, *args) 改成def action_confirm(self, arg),服务端控制台会收到类似如下告警(虽然点击按钮后,服务端不会抛异常):

      2023-02-06 01:28:53,848 28188 WARNING odoo odoo.addons.base.models.ir_ui_view: action_confirm on demo.wizard has parameters and cannot be called from a button
      
    • 如果将def action_confirm(self, *args)改成def action_confirm(self),则点击页面确认按钮时,服务端会报错误,如下:

      TypeError: action_confirm2() takes 1 positional argument but 2 were given
      

    用于视图动作按钮,传递数据给动作关联的视图

    视图设计
    
    <odoo>    
        
        <record id="estate_property_view_form" model="ir.ui.view">
            <field name="name">estate.property.formfield>
            <field name="model">estate.propertyfield>
            <field name="arch" type="xml">
                <form string="estate property form">
                    <header>
                        <button name="%(action_demo_wizard)d" type="action" 
                        string="选取offers" context="{'is_force':True}" class="oe_highlight"/>
                             
                    sheet>
                form>
            field>
        record>     
    odoo>
    

    传递数据给视图按钮

    action_demo_wizard action关联视图设计

    
    <odoo>
        <data>
              
            <record id="demo_wizard_view_form" model="ir.ui.view">
                <field name="name">demo.wizard.formfield>
                <field name="model">demo.wizardfield>
                <field name="arch" type="xml">
                    <form>                     
                          
                        <footer>                         
                           <button name="action_confirm" context="{'is_force':context.get('is_force')}" string="确认" class="oe_highlight"/>
                            <button string="关闭" class="oe_link" special="cancel"/>
                        footer>
                    form>
                field>
            record>
    
            
            <record id="action_demo_wizard" model="ir.actions.act_window">
                <field name="name">选取offersfield>
                <field name="res_model">demo.wizardfield>
                <field name="type">ir.actions.act_windowfield>
                <field name="view_mode">formfield>
                <field name="target">newfield>
                <field name="binding_model_id" ref="estate.model_estate_property"/>
                <field name="binding_view_types">formfield>
            record>       
        data>
    odoo>
    

    传递数据给视图关系字段

    
    <odoo>
        <data>
              
            <record id="demo_wizard_view_form" model="ir.ui.view">
                <field name="name">demo.wizard.formfield>
                <field name="model">demo.wizardfield>
                <field name="arch" type="xml">
                    <form>
                        <field name="offer_ids" context="{'is_force':context.get('is_force')}" >
                            <tree>                            
                                 
                            tree>
                        field>
                                              
                    form>
                field>
            record>
    
            
            <record id="action_demo_wizard" model="ir.actions.act_window">
                <field name="name">选取offersfield>
                <field name="res_model">demo.wizardfield>
                <field name="type">ir.actions.act_windowfield>
                <field name="view_mode">formfield>
                <field name="target">newfield>
                <field name="binding_model_id" ref="estate.model_estate_property"/>
                <field name="binding_view_types">formfield>
            record>       
        data>
    odoo>
    

    用于视图关系字段,传递数据给模型方法

    模型设计
    #!/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) 
        property_type_id = fields.Many2one("estate.property.type", string="PropertyType", options="{'no_create_edit': True}")
        offer_ids = fields.One2many("estate.property.offer", "property_id", string="PropertyOffer")
        
        # ...此处代码略  
    
        # 重写父类read方法
        def read(self, fields=None, load='_classic_read'):
            print(self.env.context)
            property_type_id = self.env.context.get('propertyTypeId')
            if property_type_id:
                print('do something you want')
            return super(EstateProperty, self).read(fields, load)   
    
    视图设计
    
    <odoo>
        
        <record id="estate_property_type_view_form" model="ir.ui.view">
            <field name="name">estate.property.type.formfield>
            <field name="model">estate.property.typefield>
            <field name="arch" type="xml">
                <form string="Property Type">
                    <sheet>
                        
                        <field name="property_ids" context="{'propertyTypeId': active_id}">
                            <tree string="Properties">
                                <field name="name"/>
                            tree>
                        field>
                        
                    sheet>
                form>
            field>
        record>
    odoo>
    

    打开上述视图(即加载内联Tree视图)时,会自动调用estate.property模型的read方法,服务端控制台输出如下:

    {'lang': 'en_US', 'tz': 'Europe/Brussels', 'uid': 2, 'allowed_company_ids': [1], 'params': {'action': 165, 'cids': 1, 'id': 1, 'menu_id': 70, 'model': 'estate.property.type', 'view_type': 'form'}, 'propertyTypeId': 1}
    do something you want
    

    更多示例可参考文档:[odoo 为可编辑列表视图字段搜索添加查询过滤条件](odoo 为可编辑列表视图字段搜索添加查询过滤条件.md)

    用于记录集,传递数据给模型方法

    模型设计
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from odoo import models, fields,api
    
    class EstatePropertyTag(models.Model):
        _name = 'estate.property.tag'
        _description = 'estate property tag'
    
        name = fields.Char(string='tag', required=True)
        color = fields.Integer(string='Color')
    
    
        @api.model
        def create(self, vals_list): # 通过重写模型的create或者write方法,调用该方法前修改上下文,然后在方法中通过self.env.context获取上下文中的目标key值,进而实现目标需求
            res = super(EstatePropertyTag, self).create(vals_list)
            # 获取上下文目标key值
            if not self.env.context.get('is_sync', True):
                # do something you need
            return res
    
    >>> self.env['estate.property.tag'].with_context(is_sync=False).create({'name': 'tag4', 'color': 4}).env.context
    {'lang': 'en_US', 'tz': 'Europe/Brussels', 'is_sync': False}
    

    参考连接

    https://www.odoo.com/documentation/14.0/zh_CN/developer/reference/addons/actions.html

  • 相关阅读:
    查找或替换excel换行符ctrl+j和word中的换行符^p,^l
    FPGA 20个例程篇:10.遍历DDR3内存颗粒读写循环校验
    第一章:docker环境安装
    备战蓝桥杯,那你一定得打这场免费且有现金奖励的算法双周赛!
    食品加工行业MES与APS的应用
    js-Date对象
    大数据培训教程Combiner合并
    vue3使用windicss
    1024程序员节|基于Springboot实现运动场馆预约信息管理系统
    linux 使用 navicat 报错的各种问题
  • 原文地址:https://www.cnblogs.com/shouke/p/17135902.html