for-loop
for-loop

Reputation: 57

Check for double records in One2Many field before creating

I want to create a function which takes the new value and compares it with all records in my one2many field. When the same expression was found it should return a ValodationError. But somehow I cant get the one2many value. Also I dont want to modify the create function if possible.

from odoo import models, fields, api
from odoo.exceptions import UserError, AccessError, ValidationError


class MDMSolutions(models.Model):
    _name = 'mdm.solutions'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = "MDM Versions"
    _rec_name = 'name'

    name = fields.Char('Name', tracking=True, required=True)
    mdm_versions_ids = fields.One2many(
        'mdm.solutions.versions', 'mdm_class_id', string="MDM Versions")

    @api.constrains('mdm_versions_ids.version')
    def check_for_doubles(self):
        version = self.mdm_versions_ids.version 
        if version in self.mdm_versions_ids:
            raise ValidationError("This Version already exists!")


class MDMSolutionVersions(models.Model):
    _name = 'mdm.solutions.versions'
    _rec_name = 'version'

    mdm_class_id = fields.Many2one(
        'mdm.solutions', string="MDM Class")
    version = fields.Char(string="Version", required=True)

Upvotes: 0

Views: 475

Answers (2)

Ahrimann Steiner
Ahrimann Steiner

Reputation: 1334

You should put the constrain on the other model:

    class MDMSolutionVersions(models.Model):
        _name = 'mdm.solutions.versions'
        _rec_name = 'version'
    
       version = fields.Char(string="Version", required=True)
       
       @api.constrains('version')
       def _check_version(self):
           rec_for_thisversion = self.env['mdm.solutions.versions'].search(
            [('version', '=', self.version)])
        if rec_for_thisversion:
           raise ValueError(_('This Version already exists!'))

Alternatively, you could use an Sql-constrain on the field "version" in this model:

    class MDMSolutionVersions(models.Model):
        _name = 'mdm.solutions.versions'
        _rec_name = 'version'
    
       version = fields.Char(string="Version", required=True)

       _sql_constraints = [('version', 'unique (version)', 'This version already exists!'),]

Upvotes: 1

reyhane janboori
reyhane janboori

Reputation: 341

You can simply use the onchange decorator on mdm_versions_ids filed in mdm.solutions model and check is there duplicate values then raise error you should only write above function in your mdm.solutions model :

class MDMSolutions(models.Model):
_name = 'mdm.solutions'
_inherit = ['mail.thread', 'mail.activity.mixin']
_description = "MDM Versions"
_rec_name = 'name'

name = fields.Char('Name', tracking=True, required=True)
mdm_versions_ids = fields.One2many(
    'mdm.solutions.versions', 'mdm_class_id', string="MDM Versions")

@api.onchange('mdm_versions_ids')
def check_for_doubles(self):
    num_records = len(self.mdm_versions_ids)
    if not num_records == 0:
        if len(set(self.mdm_versions_ids.version)) != num_records: 
            raise UserError(_('This Version already exists!'))

Notice that set function remove all the repeated values. I hope it works for you :)

Upvotes: 1

Related Questions