Enable Dark Mode!
how-to-create-a-dynamic-view-using-python-in-odoo-16.jpg
By: Saneen K

How to Create a Dynamic View Using Python in Odoo 16

Technical Odoo 16 Odoo Community

In Odoo, we have different views for different purposes. Each of these views has its own importance. We use these views in different scenarios for specific purposes.

Normally we create a view using XML. We have a lot of examples of creating a view. It is difficult to create a view from the Python side for an end user. In this blog, we will see how we can create a view using Python code.

Let's check this case using an example. Consider the scenario of the creation of tags. While we create a tag from the UI by an end user, we cannot get the record in the filter. For getting this record in the filter dynamically, we can add some Python codes.

Now we can create a new model for creating the tags in invoices. For that, we use the following codes.

class InvoiceTag(models.Model):
   """class for creating tags"""
   _name = "invoice.tag"
   _description = "Invoice Tag" 
   name = fields.Char(string='Tag Name', required=True, translate=True, help="Invoice tags")

Here we create a new model named ‘IvoiceTag’ with the model name ‘invoice.tag’. Then we can create a new field ("name") for storing the record of the tags. Now we create the view for this field. For that, we can use the following code.

<record id="invoice_tag_view_form" model="ir.ui.view">
   <field name="name">invoice.tag.view.form</field>
   <field name="model">invoice.tag</field>
   <field name="arch" type="xml">
       <form string="Tags">
           <sheet>
               <div class="oe_title">
                   <label for="name"/>
                   <h1><field name="name" placeholder="e.g. Services"/></h1>
               </div>
           </sheet>
       </form>
   </field>
</record>

Now we have created a field as well as a view.

Now let's see how we can dynamically add these created tags into the filter. Ie, whenever we create a tag from the UI,  the tag will appear in the filter. For that, we use some Python code.

@api.model
def create(self, vals):
   """Create filtering option in accordance with tags that are created"""
   result = super(InvoiceTag, self).create(vals)
   inherit_id = self.env.ref('account.view_account_invoice_filter')
   arch_base = _("""<?xml version="1.0"?>
                     <xpath expr="//filter[@name='draft']"
                       position="before">
                       <separator/>
                     <filter string="%s" name="%s"
                       domain="[('invoice_tag_ids','=','%s')]"/>
                       <separator/>
                     </xpath>
                     """) % (result.name, result.name, result.name)
   value = {'name': 'filter.%s' % result.name,
            'type': 'search',
            'model': 'account.move',
            'mode': 'extension',
            'inherit_id': inherit_id.id,
            'arch_base': arch_base,
            'active': True}
   self.env['ir.ui.view'].sudo().create(value)
   return result

Here we inherit the create function of the model using the keyword ‘super.’

result = super(InvoiceTag, self).create(vals)

We want to create the new record in a filter corresponding tags that are created from the UI. For that, we want to get the template id of the filter. By using the ‘ref’ keyword, we store the template id of the filter in the variable ‘inherit_id’.

inherit_id = self.env.ref('account.view_account_invoice_filter')

Now we can pass the data that needs to be specified in the field ‘arch’ of type xml. So we should pass the data directly as xml tags to the variable ‘arch_base’ in the create function. Here we set the view in xml using the ‘arch_base.’

Here we specify the position of the tags that need to be displayed in the filter. For that, we use the ‘<xpath>’ tag. Here in this example, we add the newly created tags are displayed in the filter, just before the ‘draft.’

arch_base = _("""<?xml version="1.0"?>
                 <xpath expr="//filter[@name='draft']"
                   position="before">
                   <separator/>
                 <filter string="%s" name="%s"
                   domain="[('invoice_tag_ids','=','%s')]"/>
                   <separator/>
                 </xpath>
                 """) % (result.name, result.name, result.name)

Then we want to specify the data that is required for the creation of the view.

value = {'name': 'filter.%s' % result.name,
        'type': 'search',
        'model': 'account.move',
        'mode': 'extension',
        'inherit_id': inherit_id.id,
        'arch_base': arch_base,
        'active': True}

Now we create a record in the model “ir.ui.view” by using these data.

self.env['ir.ui.view'].sudo().create(value)

So by using these Python codes, we can create a view dynamically in Odoo. The view can be customized dynamically based on our requirements.

Now we can check how this works on the user interface.

Firstly, we can create new tags in the model ‘invoice.tag’.

how-to-create-a-dynamic-view-using-python-in-odoo-16-1-cybrosys

We can see the created tags on the filter tab.

how-to-create-a-dynamic-view-using-python-in-odoo-16-2-cybrosys

So in this way, we can create a dynamic view from python. When ever we create a new tag, the tag will appear on the filter. By adding additional codes, we can remove the tag from the filter while we are deleting the tags.

For that, we can use the following codes. Here we inherit the unlink function for deleting the view from the model.

def unlink(self):
   """Unlink the tags from filtering"""
   for rec in self:
       tag_name = self.env['ir.ui.view'].sudo().search([('name', '=', 'filter.%s' % rec.name)])
       tag_name.active = False
       tag_name.unlink()
   return super(InvoiceTag, self).unlink()


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



1
Comments

Saschaya Pranev

Fantastic article! Now I can create dynamic views in Odoo 16 with confidence. Thanks a bunch!

04/10/2023

-

1:01PM



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