You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Odoo中追踪员工更新PostgreSQL Modules表的字段变更

Hey there! Let's get this change tracking set up for your Modules model in Odoo. Here's a practical, step-by-step solution that logs every field change whenever an employee updates a record:

1. Create a Change Log Model First

We need a dedicated model to store all change history. This will keep track of who made the change, what was modified, when it happened, and which module record it relates to.

from odoo import models, fields, api
from odoo.tools import html_escape

class ModuleChangeLog(models.Model):
    _name = 'module.change.log'
    _description = 'Module Change History Log'
    _order = 'create_date desc'  # Show latest changes first

    module_id = fields.Many2one('modules', string='Related Module', required=True, ondelete='cascade')
    employee_id = fields.Many2one('employee', string='Updated By', required=True)
    change_details = fields.Html(string='Change Breakdown')
    create_date = fields.Datetime(string='Update Time', default=fields.Datetime.now, readonly=True)
2. Override the write() Method in Your Modules Model

This is where we'll capture the before-and-after values of fields being updated, compare them, and generate a log entry.

class Modules(models.Model):
    _inherit = 'modules'

    def write(self, vals):
        # Capture current field values BEFORE the update
        pre_update_values = {rec.id: {field: rec[field] for field in self.fields_get()} for rec in self}
        
        # Run the original write operation to save changes
        result = super(Modules, self).write(vals)
        
        # Generate change logs for each updated record
        current_employee = self.env.user.employee_id  # Assumes your users are linked to Employee records
        if not current_employee:
            return result  # Skip logging if no employee is linked to the user
        
        for rec in self:
            changes = []
            post_update_values = {field: rec[field] for field in self.fields_get()}
            
            # Compare each modified field's pre and post values
            for field_name in vals.keys():
                field = self._fields[field_name]
                pre_val = pre_update_values[rec.id][field_name]
                post_val = post_update_values[field_name]
                
                # Format values for readability based on field type
                if field.type == 'many2one':
                    pre_display = pre_val.display_name if pre_val else 'None'
                    post_display = post_val.display_name if post_val else 'None'
                elif field.type in ['one2many', 'many2many']:
                    pre_display = ', '.join([item.display_name for item in pre_val]) if pre_val else 'None'
                    post_display = ', '.join([item.display_name for item in post_val]) if post_val else 'None'
                elif field.type == 'datetime':
                    pre_display = fields.Datetime.to_string(pre_val) if pre_val else 'None'
                    post_display = fields.Datetime.to_string(post_val) if post_val else 'None'
                else:
                    pre_display = str(pre_val) if pre_val is not None else 'None'
                    post_display = str(post_val) if post_val is not None else 'None'
                
                # Only log if the value actually changed
                if pre_display != post_display:
                    changes.append(f"<b>{field.string}</b>: {html_escape(pre_display)} → {html_escape(post_display)}")
            
            # Create a log entry if there are actual changes
            if changes:
                self.env['module.change.log'].create({
                    'module_id': rec.id,
                    'employee_id': current_employee.id,
                    'change_details': '<br>'.join(changes)
                })
        
        return result
3. Set Up Security Permissions

Don't forget to add access rules so employees can view and create log entries. Add this to your security/ir.model.access.csv file:

id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_module_change_log_user,module.change.log.user,model_module_change_log,base.group_user,1,0,1,0
access_module_change_log_manager,module.change.log.manager,model_module_change_log,base.group_system,1,1,1,1
4. Optional: Add a Smart Button for Easy Access

To make it simple to view change logs directly from a Modules record, add a smart button to your form view:

<!-- Add this to your views/modules_view.xml -->
<record id="modules_form_view_inherit" model="ir.ui.view">
    <field name="name">modules.form.view.inherit</field>
    <field name="model">modules</field>
    <field name="inherit_id" ref="your_base_module.modules_form_view"/> <!-- Replace with your original form view reference -->
    <field name="arch" type="xml">
        <header position="inside">
            <button name="%(module_change_log_action)d" type="action" icon="fa-history" string="Change Logs"/>
        </header>
    </field>
</record>

<record id="module_change_log_action" model="ir.actions.act_window">
    <field name="name">Module Change History</field>
    <field name="res_model">module.change.log</field>
    <field name="view_mode">tree,form</field>
    <field name="domain">[('module_id', '=', active_id)]</field>
    <field name="context">{'default_module_id': active_id}</field>
</record>

Quick Notes:

  • Ensure your res.users records have a linked employee_id field (you might need to add this if it doesn't exist already).
  • You can extend the field type handling (e.g., add support for selection fields to show human-readable labels instead of raw values).
  • This implementation logs all changes made via the write() method, including bulk updates and individual record edits.

内容的提问来源于stack exchange,提问作者Mingg Lex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:19:33