简体   繁体   English

将计算字段添加到自定义过滤器作为 ODOO 中的存储字段

[英]Add computed field to custom filter as stored field in ODOO

customer_count = fields.Char(string='Customer Count', compute='cust_count')

class ResBuilding(models.Model):
    _name = "res.partner.building"
    _description = "Customer BUilding"
    _order = "id desc"

    region_id = fields.Many2one('res.state.city', string='Region', required=True, ondelete='cascade')
    city_id = fields.Many2one('city.covered.area', string='Area', required=True, ondelete='cascade')
    name = fields.Char(string='Name', required=True, translate=True, copy=False)
    image = fields.Binary(string="Building image")
    latitude = fields.Char(string='Latitude')
    customer_count = fields.Char(string='Customer Count', compute='cust_count', store=True)
    longitude = fields.Char(string='Longitude')
    active = fields.Boolean(string='Active', default=True, track_visibility='onchange')
    partner_ids = fields.One2many('res.partner', 'building_id', string='Customer List', readonly=True)

    @api.multi
    @api.depends('partner_ids')
    def cust_count(self):
        for record in self:
            count = self.env['res.partner'].search_count([('building_id', '=', record.id)])
            record.customer_count = count

    @api.multi
    def name_get(self):
        result = []
        for route in self:
            name = route.city_id.name + '-' + route.name
            result.append((route.id, name))
        return result

    @api.multi
    def write(self, vals):
        res = super(ResBuilding, self).write(vals)
        print(vals, self.id)
        if vals.get('city_id'):
            customers = self.env['res.partner'].search([('building_id', '=', self.id)])
            for c in customers:
                c.living_area = vals.get('city_id')
        return res

    @api.multi
    @api.depends('latitude', 'longitude')
    def on_change_location(self):
        for li in self:
            if li.latitude and li.longitude:
                self.env.cr.execute("""update res_partner set location_latitude=""" + str(li.latitude) + """,
                                        location_longitude=""" + str(li.longitude) + """where building_id=""" + str(
                    li.id))
        return True

    @api.multi
    def write(self, vals):
        res = super(ResBuilding, self).write(vals)
        self.on_change_region_id()
        return res

    @api.multi
    @api.depends('region_id')
    def on_change_region_id(self):
        for li in self:
            if li.region_id:
                self.env.cr.execute(
                    """update res_partner set city_id=""" + str(li.region_id.id) + """where building_id=""" + str(
                        li.id))
        return True



I want find the customer count in a specific building based on building id.我想根据建筑物 ID 查找特定建筑物中的客户数量。 and want The coustomer_count field to be added to the add custom filter并希望将coustomer_count 字段添加到添加自定义过滤器中

by this code,i am getting count correctly.通过这段代码,我得到了正确的计数。 But the field customer_count does not appear in custom filter但是字段 customer_count 没有出现在自定义过滤器中

when i add store=True, the field is coming in custom filter but the count is coming as 0.当我添加 store=True 时,该字段将进入自定义过滤器,但计数为 0。

Your code is not correct, even with storing the field.您的代码不正确,即使存储该字段也是如此。

customer_count = fields.Char(
    string='Customer Count', compute='cust_count', store=True)

@api.multi
@api.depends()
def cust_count(self):
    for record in self:
        count = self.env['res.partner'].search_count([('building_id', '=', record.id)])
        record.customer_count = count

Always use for each loops in compute methods, because in case of multi relational fields using your building model or just by presenting this computed field in a list of your building model will lead to a multi recordset behind self .始终在计算方法中使用 for each loops,因为如果使用您的建筑物 model 或仅通过在您的建筑物 model 的列表中显示此计算字段,将导致在self后面的多记录集。

But that's not all.但这还不是全部。 There should be a possibility to trigger the recomputation of the field and if easy to do using depends .应该有可能触发该字段的重新计算,并且如果易于使用,请使用depends Right now i don't see any easy possibility, because i don't know all your relations and workflows.现在我看不到任何简单的可能性,因为我不知道你所有的关系和工作流程。 Without storing the field you probably don't need that, but it would work there too.如果不存储该字段,您可能不需要它,但它也可以在那里工作。

So what to do to trigger a recomputation?那么如何触发重新计算呢? Just work up from the other site of the relation: res.partner .只需从关系的另一个站点开始工作: res.partner Override it's write, create and unlink method to trigger the recomputation "manually".覆盖它的 write、create 和 unlink 方法以“手动”触发重新计算。

class ResPartner(models.Model):
    _inherit = "res.partner"

    @api.multi
    def write(self, values):
        old_buildings = self.mapped('building_id')
        res = super(ResPartner, self).write(values)
        if 'building_id' in values:
            new_buildings = self.mapped('building_id')
            trigger_buildings = old_buildins | new_buildings
            trigger_buildings.cust_count()
        return res

    @api.model
    def create(self, values):
        partner = super(ResPartner, self).create(values)
        partner.building_id.cust_count()
        return partner

    @api.multi
    def unlink(self):
        buildings = self.mapped('building_id')
        res = super(ResPartner, self).unlink()
        buildings.cust_count()
        return res

Another way is to use a one2many field on your building model in relation to res.partner and fill depends with it, like depends('partner_ids') .另一种方法是在您的建筑物 model 上使用与res.partner相关的one2many字段,并使用它填充depends它,例如depends('partner_ids') But in my experience one2many fields in such and lot of other situations tend to lead to bad performance.但根据我的经验,在这种情况和许多其他情况下, one2many领域往往会导致性能不佳。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM