Odoo 13中JS视图向XML字段传递Context的实现问题
Hey, I see you've spent days trying to pass a context from a JavaScript view to set the default gender value to Male when clicking the create button in Odoo 13. Let's fix this step by step.
What's Wrong With Your Current Code?
First, let's spot the key issues:
- Incorrect default value: Your Python
genderfield uses('male', 'Male')as the option pair, so the value you need to pass in context is'male', not'Male'(you had this wrong in your JS code). - Unfinished JS logic: Your JavaScript didn't properly intercept the default create button behavior, nor did it specify which form action to open—so the context you tried to pass never reached the target form.
Correct Implementation
1. Confirm Your Python Field is Set Up Right
Your existing gender field definition is correct, just keep the value-label mapping in mind:
gender = fields.Selection( [('male', 'Male'), ('female', 'Female'), ('others', 'Others')], string='Gender')
2. Fix the JavaScript Code
We have two reliable ways to implement this with JS. Pick the one that fits your workflow:
Option A: Override the Standard Create Method (Cleanest Approach)
This is the Odoo-native way to modify create behavior by extending the ListController:
odoo.define('student.custom_create_button', function (require) { "use strict"; var ListController = require('web.ListController'); ListController.include({ _createRecord: function () { // Merge the default context with our custom default value this.context = Object.assign({}, this.context, { 'default_gender': 'male' // Use the actual field value, not the label }); // Call the original create method with our updated context return this._super.apply(this, arguments); }, }); });
Option B: Bind to the Create Button Click Event
If you prefer to directly hook into the button's click action:
odoo.define('student.custom_create_button', function (require) { "use strict"; var ListController = require('web.ListController'); ListController.include({ renderButtons: function ($node) { this._super.apply(this, arguments); // Find the create button and re-bind its click event const createBtn = this.$buttons.find('.o_list_button_add'); if (createBtn) { createBtn.off('click').on('click', this.proxy('_onCustomCreate')); } }, _onCustomCreate: function (ev) { ev.preventDefault(); // Stop the default create action // Trigger the form action with our custom context this.do_action({ type: 'ir.actions.act_window', res_model: 'student.student', // Replace with your actual model name views: [[false, 'form']], target: 'current', context: Object.assign({}, this.context, { 'default_gender': 'male' }) }); } }); });
3. Load Your JavaScript File
Don't forget to add the JS file to your module's manifest so Odoo loads it:
# __manifest__.py 'assets': { 'web.assets_backend': [ 'student/static/src/js/custom_create_button.js', // Update the path to your file ], },
Bonus: No JavaScript Needed (Simpler Alternative)
If you don't strictly need to use JavaScript for this, you can set the default directly in the action definition—way easier!
<!-- Add this to your action record --> <record id="action_student_list" model="ir.actions.act_window"> <field name="name">Students</field> <field name="res_model">student.student</field> <field name="view_mode">tree,form</field> <field name="context">{'default_gender': 'male'}</field> </record>
This will automatically set the gender to Male every time you click the create button, no JS required.
内容的提问来源于stack exchange,提问作者Павел Храпун

