Přejít na obsah
Menu
You need to be registered to interact with the community.
This question has been flagged
4 Odpovědi
2853 Zobrazení

Hello,

I am working on a module where I implement a special, simplified version of a task.

Ithis task model, there are a few standard task types and each of those types comes with a specific set of state stages. 

I have created a table where I can store task types and stage names. I have gotten it so that at the time of creation, the task gets assignedd a specific task type.

Now my issue is that I want to use a callable for the selection field which calls on self to finnd out it's own task type, search for the stages corresponding to this task type and assign them to the selection field.

the theory sounds great, but for some reason, when I call self, it appears to be empty. When I try to debug using the console print, I always get 'irig.task()' (the name of the model) but no records in the recordset. 

can anybody help me figure out what am I calling wrong?

state_test = fields.Selection(selection='get_states')
 
def get_states(self):
  ​sel = [
​('1','One'),
​('2','Two')
      ]
​print(self)
​for r in self:
    ​records = self.env['irig.state'].search([('task_type', 'like', 'gear')])
​## It should llok like this, but the r in self is empty:
.search([('task_type', 'like', r.task_type)])

​for rec in records:
        ​sel.append((rec.task_type, rec.name) )
​print(sel)
​return sel

In the above snippet, I have tested individual parts and it all works, the only part that since self shows as empty, then 'r in self' is also empty.

Even after the record is created, when I navigate to it, the 'get_states' method is called, but self is still empty.


Any help will be greatly appreciated!

Avatar
Zrušit

have you overridden the create method to call get_states()?

Autor

@Rithik Sandron
I just tried it, but it still didn't work.

Nejlepší odpověď

In your case use compute instead, because self will always empty when you write seletion="your method"

I have searched across odoo 17 code where they have selection="method" and they do not use self just use something like self.env to search for other module

Avatar
Zrušit
Autor Nejlepší odpověď

O.k. For some reason I cant comment on anybody elses answers or comments. but after trying and playing with this, I can confirm that on the "selection" field, although it can use a callable function to popullate the options, there is no "self" available. so it is basically impossible to reference itself to choose the options based on some parameter of itself. 


However, I ended up solving my ultimate goal by using a Many2one relationship, with a domain based on a parameter of itself and then using the "statusbar" widget on it. Not the most ideal way, but it works. 


Thank you very much for your help and input.

 

-----------------------------------------------

Previous edit

@Rithik Sandron,

thank you very much for the example, however it doesnt really work.

the logic of getting the record after calling super(etc) works great in the sense that I indeed get a record that I can work with.

The problem now is that If I leave the field

state_test = fields.Selection(selection='get_states')

then, the method gets called before I create the record and every time I look at a record, both moments there is no self.

When I call the method from the create method, although now I do get the correct records and I do have a task to get info out of, it doesnt automatically assign the result to the selection field, and when I try to "force" it by doing:

task.state_test = selection_fields

I get an error saying that it is not the right value, even though it is a list of tuples.

the same behaviour happens when I change the state_test field to this:

state_test = fields.Selection([], string="State Test)

The part I still dont understand is how come when I call pretty much any other method, self does exist all the time, except for only this one method

cheers!

Avatar
Zrušit

I have updated my answer. Check out if that helps

Autor

Sadly it still didnt work. However I found out that the 'selection=callable' Method in the selection field doesnt pass 'self'. Dont know if this is a bug or intentional for some reason, but I just tried calling the same 'get_states' method from the seleection field and from a compute on both a selection and a char field and directly from the selection=callable method I never got self, but from the compute I do get self and I can get all the info... However, since the result is a list of tuples, neither the return of a compute nor a direct assignment work.

Thank you very much to both, I will try to go deeper into it tomorrow.

Nejlepší odpověď

If you're overriding the create method, try this:

from odoo import api

state_test = fields.Selection([('1', 'One'),
('2', 'Two'),
('3', 'Three')], string='State Test')

@api.model_create_multi
def create(self, values_list):
​for value in values_list:
// here the record has not been created yet, so the self object does not contain the record. self.get_states() will not work

​line = super(model_class_name, self).create(vals)
// ​here the record has been created. the record object in returned to line
​line.get_states() // this will work
​return line

def get_states(self):
​for record in self:
​record.state_test = '2'

To change selection fields dynamically:

from odoo import models, fields, api


class IrigTask(models.Model):
​_name = "irig.task"
​_description = "irig.task"

​@api.model
def ​_get_selection_items(self):
sel = [('1', 'One'), ('2', 'Two')]​
​return sel

​state_test = fields.Selection(selection=lambda self: self.env['irig.task']._get_selection_items(), string="State Test")

hope this helps. let me know


Avatar
Zrušit
Nejlepší odpověď

Hi,

Please try to use api.model decorator before the function starts, and maybe in the self you may be getting a False value, If you are getting False in the print, then you can search the value.

example:


@api.model

def get_states(self):

      sel = [

        ('1','One'), ('2','Two') ]

         print(self)

         for r in self.env['model.name'].search([]):

         //your balance code



Hope it helps

Avatar
Zrušit

Wrong purpose of using api.model, learn odoo again please.
When using api.model, we will not take into account value in self which mean we won't use self.'field' at al

Related Posts Odpovědi Zobrazení Aktivita
1
bře 24
964
1
pro 23
2464
2
led 23
2737
1
čvc 24
1706
1
říj 24
1719