Enable Dark Mode!
how-to-use-fieldsget-to-modify-field-properties-in-odoo-18.jpg
By: Ashwin T

How to Use fields_get() to Modify Field Properties in Odoo 18

Technical Odoo 18 Odoo Enterprises Odoo Community

In Odoo 18 development, the ability to dynamically modify field properties can significantly improve the adaptability and usability of your modules. The fields_get() method is a powerful tool that enables developers to access metadata of fields defined within any Odoo model.

When you call fields_get(), it returns a dictionary where each key is a field name and the corresponding value is another dictionary containing that field’s attributes. This includes fields inherited through _inherits. Attributes such as string (label), help (description), and selection options (for selection fields) are automatically translated based on the current user’s language settings.

The fields_get() will be useful in scenarios where;

  1. Readonly fields can be controlled based on user roles or workflow states. For example, salary fields can be made readonly for non-HR users, and fields_get() can be used to inspect the readonly attribute and adjust field behavior dynamically in the code.
  2. Debugging and development: Inspect field attributes like type, required status, help text, and selection values to troubleshoot and refine dynamic behavior.
  3. Dynamic selection options: Update selection field choices based on other field values (e.g., cities based on selected country).

To begin, let’s look at a simple example demonstrating how the fields_get() method can be used within an Odoo model.

Example 1: Changing a Field Label

# -*- coding: utf-8 -*-
from odoo import models

class ResPartner(models.Model):
   """
   Inherit the res.partner model to demonstrate customization
   of field properties using fields_get() in Odoo 18.
   """
   _inherit = "res.partner"
   def fields_get(self, allfields=None, attributes=None):
       """
       Override fields_get() to change field metadata dynamically.
       :param allfields: List of field names to retrieve (or None for all fields).
       :param attributes: List of attributes to return (e.g., ['string', 'readonly']).
       :return: Dictionary of field metadata.
       """
       res = super().fields_get(allfields=allfields, attributes=attributes)
       if "email" in res:
           res["email"]["string"] = "Contact Email"
           # Example: make the email field readonly
           # res["email"]["readonly"] = True
       return res

Explanation:

  • Extends the res.partner model using _inherit.
  • Overrides fields_get() to fetch metadata for all or specific fields.
  • Checks if the email field exists.
  • Updates the field label to “Contact Email”.
  • Optionally, can make the field readonly by setting res["email"]["readonly"] = True.

Running in a Server Action

Sometimes, you might want to quickly check how your dynamic field changes work without creating new views or writing extra controllers. In Odoo, a simple way to do this is by using a Server Action. With it, you can run Python code directly from the UI on any model, making it handy for testing what fields_get() returns and instantly seeing your modifications in action.

  1. Navigate to Settings > Technical > Actions > Server Actions (enable Developer Mode).
  2. Create a new Server Action for Contacts (res.partner).
  3. Paste the following code:
# Fetch only the "email" field metadata from res.partner
model_fields = model.fields_get(allfields=['email'])
# Return an action to open a new contact form with this metadata in context
action = {
   "type": "ir.actions.act_window",
   "res_model": "res.partner",
   "view_mode": "form",
   "target": "new",
   "context": {"field_metadata": model_fields},
}
  • Save it, open any Contact record, then run the Server Action.

Example 2: Role-Based Readonly Field

This example shows how to make the phone field readonly for users who are not part of the Sales Manager group.

# -*- coding: utf-8 -*-
from odoo import models, api

class ResPartner(models.Model):
   _inherit = "res.partner"
   @api.model
   def fields_get(self, allfields=None, attributes=None):
       """
       Override fields_get to make 'phone' field readonly for Sales Users
       (Marc Demo) but editable for Sales Managers (Mitchell Admin)
       """
       res = super().fields_get(allfields=allfields, attributes=attributes)
       # Check if the 'phone' field exists
       if "phone" in res:
           # Only Sales Managers can edit phone; others see it as readonly
           if not self.env.user.has_group("sales_team.group_sale_manager"):
               res["phone"]["readonly"] = True
               res["phone"]["help"] = "Only Sales Managers can edit this field."
       return res

Server Action:

# Fetch metadata for the 'phone' field
field_info = model.fields_get(allfields=['phone'])
# Return action to open a new contact form
action = {
   "type": "ir.actions.act_window",
   "res_model": "res.partner",
   "view_mode": "form",
   "target": "new",
   "context": {"field_metadata": field_info},
}

How the code works:

  • The res.partner model is extended using _inherit.
  • The fields_get() method is overridden to access metadata of all fields.
  • fields_get() returns a dictionary with field names as keys and metadata dictionaries as values.
  • The code checks if the phone field exists in the returned metadata.
  • self.env.user.has_group("sales_team.group_sale_manager") determines if the logged-in user is a Sales Manager.
  • If the user is not a Sales Manager:
  • res["phone"]["readonly"] = True makes the field read-only.
  • res["phone"]["help"] adds a small tooltip explaining the restriction.
  • The modified metadata is returned, automatically applying the restriction in the UI.

The fields_get() method in Odoo 18 is a powerful tool for developers to dynamically access and modify field properties. It allows you to control labels, readonly status, selection options, visibility, and other metadata without changing XML views. By using fields_get(), you can implement role-based restrictions, context-aware behavior, and dynamic UI adjustments, making your modules more flexible, user-friendly, and easier to maintain. Server Actions can be used to quickly test these changes, helping developers debug and fine-tune field behavior efficiently. Overall, mastering fields_get() improves both development efficiency and the end-user experience.

To read more about How to Use fields_get() to Modify Field Properties in Odoo 17, refer to our blog How to Use fields_get() to Modify Field Properties in Odoo 17.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message