Search code examples
pythonodooodoo-10

How to update the Model's database if it has Many2many relation with other Model's database in Odoo?


I have 2 model "Book" and "Author". I have Many2many relation between them.If one of the Author is deleted from Author database, I should delete all the book that was written from this author.I have tried many ways but I am new in Odoo. So I couldn't. What will be the solution? Thanks.

Book.py

# -*- coding: utf-8 -*-
from odoo import models, fields,api

class Book(models.Model):
    _name = 'about.book'
    _description = 'Book Information'
    _order = 'publication_date desc, name'
    isbn = fields.Char('ISBN',required=True)
    name = fields.Char('Title', required=True)
    publication_date = fields.Date('Publication Date')
    author_ids = fields.Many2many('about.author', select=True, required=True,string='Authors')
    _sql_constraints = [('isbn_uniq', 'unique (isbn)','ISBN already exists!')]



    @api.constrains('publication_date')
    def _check_publication_date(self):
        for r in self:
            if (r.publication_date > fields.Date.today()) and (r.publication_date == False):
                raise models.ValidationError('Publication date must be in the past !')



    @api.constrains('author_ids')    
    def has_author(self):
        for r in self:
            if r.author_ids == False:
                raise models.ValidationError('Book must have at least 1 author!')

    @api.one
    def unlink(self):
        rule = self.env['about.book']
        if rule.search([('author_ids', '=', False)]):
           rule.unlink()

Author.py

from odoo import models, fields,api

class Author(models.Model):
    _name='about.author'
    _inherits = {'res.partner' : 'partner_id'}
    partner_id = fields.Many2one('res.partner', string="Author")
    is_book_author= fields.Boolean('Is Book Author',required=True,default=False)

Solution

  • One thing I don't understand Here what if the books is written by two authors! If this is not the case then the relation should be one2many.

    You said that you have many2many relation between this two models:

    1. You many2many field is declared in books models author_ids.
    # override unlink of Author not book
    class Author(models.Model):
        _name='about.author'
        ......
        ......
    
        @api.multi
        def unlink(self):
            """when delete author we should delete his books"""
            books = self.env['about.book'].search([('author_ids', 'in', self.ids)]
            if books:
                books.unlink()
            return super(Author, self).unlink()
    
    1. Second case for learning, if many2many field is declared in author model let assume : book_ids
    # override unlink of Author not book
    class Author(models.Model):
        _name='about.author'
            
        @api.multi
        def unlink(self):
            """when delete author we should delete his books"""
            # use mapped to return all list of books of all record that
            # will be removed to call unlink one time avoid loop
            books = self.mapped('books_ids')
            if books:
                books.unlink()
            return super(AuthorClass, self).unlink()