简体   繁体   English

Odoo计算字段:无存储的工作= True,不适用于store = True

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

I have a computed field in Odoo with a function. 我在Odoo中有一个带有函数的计算字段。 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. 当我添加store参数时,它根本不执行代码。

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"). 代码未执行(不显示“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. 编辑:我应用了Juan Salcedo的提示。 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 NameError:未定义名称“changeunit”

I also tried putting the unit field below def changeunit(self), but didn't work either. 我也尝试将单位字段放在def changeunit(self)下面,但也没有用。

When we set store=True then we need to specify when we need to compute that function. 当我们设置store=True时,我们需要指定何时需要计算该函数。 Using @api.depends('fields') in that you specify field name when the change the value of the fields then compute method is call. 使用@api.depends('fields')在更改字段值时指定字段名称,然后调用compute方法。

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. 在此示例中,当您更改名称时,将调用get_length函数。

Store=True without @api.depends means it will execute only once while the column/field is going to be created. 没有@ api.depends的Store = True意味着在创建列/字段时它只会执行一次。

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. 因此,如果没有@ api.depends,则无法使用store = True实现每次触发该方法的效果,或者您需要删除store = True,然后每次访问此字段时都会计算。

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. 另一种方式:store = False从未在数据库中存储任何值,因此如果您想将该值存储在数据库中并且不会更新(意味着它在创建或更新记录时已修复),那么您只需要覆盖create / write方法和内部更新此字段的值。

@api.model
def create(self, vals):
    vals.update({'field':value})
    return super(class_name,self).create(vals)

Here's a solution that might work for you, it's not perfect because it will could call the method often yet without real need most of the time. 这是一个可能对您有用的解决方案,它并不完美,因为它可以在大多数时间没有真正需要的情况下经常调用该方法。

First add a new field that is computed.. Add that field to the UI where you need it and also hide it. 首先添加一个计算的新字段。将该字段添加到您需要它的UI中并隐藏它。 It's not necessary to show it. 没有必要展示它。 You have to have it in the ui to force odoo to compute it. 你必须在ui中强制使用odoo来计算它。

When you compute the value of the field, also change the value of the field you really wanted to edit. 计算字段的值时,还要更改您想要编辑的字段的值。 Since a compute method can update multiple fields, it will work. 由于计算方法可以更新多个字段,因此可以使用。

You don't have to make the original field as computed as far as I can say... 根据我的说法,您不必将原始字段计算为...

But since you're modifying some fields using sql which isn't really good as you admitted yourself... Why don't you change that field with SQL at the same time? 但是因为你正在使用sql修改一些字段,这并不是你自己承认的那么好......为什么你不同时用SQL改变那个字段呢? Make it easier on the Odoo side without hacks and make sure that your method that changes SQL kind of changes everything as it should. 在没有hacks的情况下在Odoo端更容易,并确保改变SQL类型的方法改变了应有的一切。 It's like you're editing one half of the problem and expecting odoo to catch data changes on itself. 这就像你正在编辑问题的一半并期望odoo自己捕获数据变化。 In order to achieve that, you'd need to have some way to have the database notify odoo that something changed... unfortunately, Postgresql doesn't do that so make sure that while you're updating something from SQL, that you have consistent data after doing your changes. 为了实现这一点,你需要有一些方法让数据库通知odoo某些东西发生了变化......不幸的是,Postgresql没有这样做,所以确保当你从SQL更新某些东西时,你有完成更改后的一致数据。

i noticed this issue too, but in my case it was not necessary to store it in the database. 我也注意到了这个问题,但在我的情况下,没有必要将它存储在数据库中。 so i kept it as store=false and the computed field worked and it has a value in the view and that's what mattered, only to have the values in the view.. 所以我把它保存为store = false并且计算字段工作,它在视图中有一个值,这是重要的,只有在视图中有值。

so when you set store=true, only new records will have a value in the computed field, while old data won't have values in the computed field 所以当你设置store = true时,只有新记录在计算字段中有一个值,而旧数据在计算字段中没有值

therefore you have to reset the values of the fields used in the computation of the field(depend fields) 因此,您必须重置字段计算中使用的字段的值(依赖字段)

by writing a write statement inside the compute function, to reassign these fields their own values again, as if they are just created 通过在compute函数中编写一个write语句,再次将这些字段重新分配给它们自己的值,就好像它们刚刚被创建一样

for record in self.env['class'].search([]):
    record.field= record.field

record.field ->>> the fields used in field computation or api.depends(fields) record.field - >>>字段计算中使用的字段或api.depends(字段)

This is not an issue, because Store = True (by the way it's recommended) tells odoo that when you compute the field store it's value to the database, so when you call this record next time the framework will retrieve the value from the database, and this value will be recomputed when any of the fields in the depends annotation is updated in the database or the UI. 这不是问题,因为Store = True(按照推荐的方式)告诉odoo当你计算字段时它将值存储到数据库中,所以当你下次调用这条记录时框架将从数据库中检索值,当在数据库或UI中更新depends注释中的任何字段时,将重新计算此值。

so the code is not warking because when you specify the store = True after creating the value the value will be False and odoo will not recompute it until you change one of the fields that trigger the function. 所以代码没有结果,因为在创建值后指定store = True时,值将为False,并且odoo将不会重新计算它,直到您更改触发该函数的其中一个字段。

you need to compute this field manually with a query to set the value for the existing records that you have in the database, don't worry about the new records odoo will compute and store the values. 您需要使用查询手动计算此字段以设置数据库中现有记录的值,不必担心odoo将计算和存储值的新记录。

so store = True. 所以store = True。 means compute and store the value in the database and don't compute it again until one of the field is edited you need to compute the value for the existing records manually for the first time. 表示计算并将值存储在数据库中,并且在编辑其中一个字段之前不再计算它,您需要首次手动计算现有记录的值。

One way to achieve a computed field and the storage into the database is by adding an additional field that is relating to the computed field. 实现计算字段和存储到数据库中的一种方法是添加与计算字段相关的附加字段。

field_name = fields.Monetary(string='Name', compute='_compute_anything')
field_name_store = fields.Monetary(related='field_name', string='Name', store=True)

@api.multi
def _compute_anything(self):
    variable = (field1+field2)
    update({'field_name':variable})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我使用其他模型的字段时,如何使用“ store = True”使工作成为计算字段? - How to make work a computed field with “store=True” when I am using fields from other model? 如何在Odoo 8中为计算字段设置存储触发器? - How to set store trigger for computed fields in Odoo 8? Numba 尝试:如果 array.shape[1] - 错误:元组索引超出范围。 没有 numba 的情况下工作,不适用于 @njit(fastmath=True, nogil=True, cache=True) - Numba try: if array.shape[1] - error: tuple index out of range. works without numba, doesn't work with @njit(fastmath=True, nogil=True, cache=True) django flatpages适用于DEBUG = True,不适用于DEBUG = False - django flatpages works with DEBUG=True, doesn't work with DEBUG=False 如何使用 store = True 更新带有计算字段的旧记录 - how to update old records with computed field with store = True 没有shell = True,Python subprocess.call不起作用 - Python subprocess.call doesn't work without shell=True PATCH (partial=true) 在 Django 中不起作用 - PATCH (partial=true) doesn't work in Django inplace=True 不适用于子集数据 - inplace=True doesn't work for subset data Odoo计算字段无法正常运行 - Odoo Computed fields cant work in function Odoo v10 @onchange(stage_id)无法使用<field name=“stage_id” widget=“statusbar” clickable=“True”/> - Odoo v10 @onchange(stage_id) doesn't work with <field name=“stage_id” widget=“statusbar” clickable=“True”/>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM