Search code examples
python-3.xodooodoo-11

Unique constraints cause error when duplicating record in Odoo 11


I have an unique constraint for my code field. When I click on the 'duplicate' option in the dropdown action I'm getting the validate error. Is there any way to use 'duplicate' even if the field code is unique?

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

    code=fields.Char('Code',required=True)
    name=fields.Char('Name',required=True)

    _sql_constraints = [
        ('code_uniq', 'unique (code)', 'The code must be unique !')
    ]

Solution

  • Yes, it is. You have two ways to do this. When you duplicate a record, copy method is called, and it creates a new record with the values of the original record (it only copies the values of the fields whose argument copy=True -by default is True-). So you can change that argument in the code field declaration, or modify the copy method to avoid the identical replication.

    Way 1: modifying the copy argument of the code field

    This way would be the easiest one, but it will give you an error if code field is required.

    class sample(models.Model):
        _name = 'sample'
    
        code = fields.Char('Code', required=False, copy=False)
        name = fields.Char('Name', required=True)
    
        _sql_constraints = [
            ('code_uniq', 'unique (code)', 'The code must be unique !')
        ]
    

    Way 2: modifying the copy method of the model sample

    This is the way you're looking for if code must be required.

    class sample(models.Model):
        _name = 'sample'
    
        code = fields.Char('Code', required=True)
        name = fields.Char('Name', required=True)
    
        _sql_constraints = [
            ('code_uniq', 'unique (code)', 'The code must be unique !')
        ]
    
        @api.one
        def copy(self, default=None):
            if default is None:
                default = {}
            new_code = (self.code + ' (copy)') if self.code else ''
            default.update({
                'code': new_code,
            })
            new_sample = super(sample, self).copy(default=default)
            return new_sample