如何在状态为confirmed时将表单所有字段设为只读并优化实现
Great question! Adding the same attrs snippet to every field gets tedious fast—here are a few cleaner, more maintainable approaches to handle this in Odoo:
1. Apply Read-Only to a Field Group (View-Level)
This is the most straightforward and recommended method. Wrap all your form fields in a <group> tag, then apply the attrs rule to the group itself. All fields inside the group will inherit the read-only state automatically:
<record id="your_model_form_view" model="ir.ui.view"> <field name="name">your.model.form.view</field> <field name="model">your.model</field> <field name="arch" type="xml"> <form> <!-- Keep state field outside if you need to edit it even when confirmed --> <field name="state"/> <group attrs="{'readonly': [('state', '=', 'confirmed')]}"> <!-- All your other form fields go here --> <field name="name"/> <field name="description"/> <field name="amount"/> <!-- ... --> </group> </form> </field> </record>
Pros: No repetitive code, easy to maintain (update the rule in one place), and you can easily exclude specific fields by moving them outside the group.
2. Batch-Configure Fields at the Model Level (Python)
If you want to enforce this rule at the model level (instead of just the view), you can dynamically set the readonly property for all fields during model setup:
from odoo import models, fields class YourModel(models.Model): _name = 'your.model' _description = 'Your Model' state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], default='draft') name = fields.Char(string='Name') description = fields.Text(string='Description') amount = fields.Float(string='Amount') def _setup_fields(self): super()._setup_fields() # Apply read-only rule to all fields except 'state' for field_name, field in self._fields.items(): if field_name != 'state' and not field.readonly: # Preserve existing readonly settings if any original_readonly = field.readonly field.readonly = lambda self, f=original_readonly: f or self.state == 'confirmed'
Pros: Enforces the rule across all views of the model, not just one. Cons: More complex, and you need to be careful not to override existing field configurations.
3. Make the Entire Form Read-Only (View-Level)
If every single field (including the state field, if needed) should be read-only when confirmed, you can apply the rule directly to the <form> tag:
<form attrs="{'readonly': [('state', '=', 'confirmed')]}"> <field name="state"/> <field name="name"/> <field name="description"/> <!-- ... --> </form>
Pros: Even simpler than the group method. Cons: No way to exclude individual fields without adding overriding attrs to them.
Quick Tip
If you need a specific field to remain editable even when the state is confirmed, just add an overriding attrs rule to that field:
<field name="special_field" attrs="{'readonly': [('state', '!=', 'confirmed')]}"/>
内容的提问来源于stack exchange,提问作者Dayana

