Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Odoo computed fields: works without store=True, doesn't work with store=True

Tags:

python

field

odoo

I have a computed field in Odoo with a function. Everything works fine when I don't add the store argument. When I add the store argument, it doesn't execute the code at all.

My code:

class opc_actuelewaardentags(models.Model):
    _name = 'opc_actuelewaardentags'

    unit = fields.Char(compute='changeunit')

    def changeunit(self):
        print "print"
        allrecords_actwaardent = self.search([])

        obj_taginst = self.env['opc_taginstellingen']
        allrecords_taginst = obj_taginst.search([])


        for i in allrecords_actwaardent:
            for j in allrecords_taginst:
                if i.tagnaam == j.tagnaam and i.unit != j.unit:
                    i.unit = j.unit

So: when I call the code like this:

unit = fields.Char(compute='changeunit')

The code is executed (shows "print").

When I call the code like this:

unit = fields.Char(compute='changeunit', store=True)

The code is not executed (doesn't show "print").

Is there anything wrong in my code? Or is this a bug? It seems so strange to me...

I need to be able to store the values in the database so I can filter on unit in the tree view.

edit: I applied Juan Salcedo's tip. Didn't work...

This is how I did it:

unit = fields.Char(default = changeunit)    

def changeunit(self):
    print "print"
    allrecords_actwaardent = self.search([])

    obj_taginst = self.env['opc_taginstellingen']
    #Hier dan i.p.v. self werken met dat obj_taginst
    allrecords_taginst = obj_taginst.search([])


for i in allrecords_actwaardent:
    for j in allrecords_taginst:
        if i.tagnaam == j.tagnaam and i.unit != j.unit:
            i.unit = j.unit
return i.unit

Gives error:

NameError: name 'changeunit' is not defined

I also tried putting the unit field below def changeunit(self), but didn't work either.

like image 877
RobbeM Avatar asked Aug 11 '15 14:08

RobbeM


People also ask

How do you store computed fields?

Computed field values can also be stored in the database, by setting store = True in their definition. They will be recomputed when any of their dependencies change. Since the values are now stored, they can be searched just like regular fields, and a search function is not needed.

What is the difference between Onchange and compute Odoo?

Onchange is triggered only when one of the given attributes changes its value. 3. Every compute method should assign a value to the computed field therefore, it is necessary to ensure that the compute method will assign a value to the field on every condition.

What is computed fields in Odoo?

The definition of computed fields in Odoo is exactly the same as any other regular fields in Odoo. The only exception is the attribute compute which is used to specify the name of the function used for its computation. Computed fields are dynamically calculated at the runtime.

How do you add a compute field in the filter in Odoo?

There are two ways to store the computed fields in Odoo. We can make the field store by adding store=True. And another method is by using a search function set it on the field.


2 Answers

Store=True without @api.depends means it will execute only once while the column/field is going to be created.

so the effect you want to fire that method everytime will not be achieve with store=True without @api.depends or you need to remove store=True then it will calculate everytime when you access this field.

This are the changes you required to update in your code but before that you need to remove that column from database and after that restart server and upgrade module then it will come to there.

class opc_actuelewaardentags(models.Model):
    _name = 'opc_actuelewaardentags'

    unit = fields.Char(compute='changeunit')

    @api.multi
    def changeunit(self):
      print "print"  
        for obj in self:
            allrecords_actwaardent = self.search([])
            obj_taginst = self.env['opc_taginstellingen']
            allrecords_taginst = obj_taginst.search([])
            for i in allrecords_actwaardent:
                for j in allrecords_taginst:
                    if i.tagnaam == j.tagnaam and i.unit != j.unit:
                       obj.unit = j.unit
                       break

Another way: store = False never stored any value in database so if you want to store that value in database and don't won't to be updated (means it's fixed when create or update record) then you just need to override create/write method and inside update this field's value.

@api.model
def create(self, vals):
    vals.update({'field':value})
    return super(class_name,self).create(vals)
like image 143
Emipro Technologies Pvt. Ltd. Avatar answered Nov 17 '22 14:11

Emipro Technologies Pvt. Ltd.


When we set store=True then we need to specify when we need to compute that function. Using @api.depends('fields') in that you specify field name when the change the value of the fields then compute method is call.

name = fields.Char('name')
length = fields.Integer(compute='get_length','Length',store=True)

@api.depends('name')
def get_length(self):
    self.length=len(name)

In this example when you change the name then get_length function is call.

like image 3
Synodica Solutions Pvt. Ltd. Avatar answered Nov 17 '22 12:11

Synodica Solutions Pvt. Ltd.