Search code examples
pythonodooodoo-10odoo-9odoo-11

Looping through objects in model odoo 11


I'd like to create a function on my model 'Artist' to change the field num_albums to the number of albums he created. I imagine that I must use a compute function and filter all of the albums based on the name of the artist. However, I have no idea of how to do it. Please help me if you know how I could do it.

Here's my code:

class Artist(models.Model) :
    _name = 'artist'
    _order = 'name'

    name = fields.Char('Name of Artist')
    age = fields.Integer(string='Age of Artist')
    nationality = fields.Selection([('France', 'France'), ('GB', 'Great Britain'),
    ('USA', 'United States'), ('Russia', 'Russia'), ('China', 'China'),
    ('Other', 'Other')], 'Nationality')
    num_albums = fields.Integer(compute='_get_num_albums', store=False)

    @api.model
    def _get_num_albums(self) :
        **Enter code here**

class Album(models.Model) :
    _name = 'album'
    _order = 'artist.name'

    artist = fields.Many2one('artist', string='Artist')
    name = fields.Char('Name')
    image = fields.Binary('Album Cover')

Solution

  • You could declare a One2many relation from artist to his/her albums and then simply use the number of albums, eg.:

    class Artist(models.Model):
        _name = 'artist'
        _order = 'name'
    
        # ...
        albums = fields.One2many(
            comodel_name='album',
            inverse_name='artist',
            string='Albums',
        )
        num_albums = fields.Integer(compute='_get_num_albums', store=False)
    
        @api.multi
        def _get_num_albums(self):
            for artist in self:
                artist.num_albums = len(artist.albums)
    
        # ...
    

    Or, without adding additional fields, you could use search_count to get the number of albums by an artist:

    class Artist(models.Model):
        _name = 'artist'
        _order = 'name'
    
        # ...
        num_albums = fields.Integer(compute='_get_num_albums', store=False)
    
        @api.multi
        def _get_num_albums(self):
            album_obj = self.env['album']
            for artist in self:
                artist.num_albums = album_obj.search_count([
                    ('artist', '=', artist.id),
                ])
        # ...