This question has been flagged
4 Replies
16831 Views

Hello, I am trying to create a model that have multiple Many2many fields that relates to the "product.product" model. Basically, the model will have four list, each one containing different products.

My model is the following:

class SubscriptionBasket(models.Model):
    _name="subscription.basket"
    name = fields.Char("Nome", required=True)
    legumes = fields.Many2many(
        'product.product',
        string='Legumes',
    )
    frutas = fields.Many2many(
        'product.product',
        string='Frutas',
    )
    verduras = fields.Many2many(
        'product.product',
        string='Verduras',
    )
    temperos = fields.Many2many(
        'product.product',
        string='Temperos',
    )


The problem however is that when I choose a product to one of the fields and then save, all fields get this product as well.

As an example, I overwrote the create function to get logs:

@api.model
def create(self, vals):
    _logger.info("Vals received on creation: %s", vals)
    res = super(SubscriptionBasket, self).create(vals)
    _logger.info("Field temperos on creation response: %s", res.temperos)
    return res


Then, when creating a record, informing a product just to the fields "legumes", I get the following log for the vals I received:

    Vals received on creation: {'name': 'Cesta', 'temperos': [[6, False, []]], 'frutas': [[6, False, []]], 'date_start': '2019-02-05',     'verduras': [[6, False, []]], 'legumes': [[6, False, [6952]]], 'date_end': '2019-02-08'}

And the following log for the field "temperos", which I would expect to be empty, on the creation response:

    Field temperos on creation response: product.product(6952,)

What am I missing here?

Avatar
Discard
Best Answer

Hello Arthur,

Try to define like below:

class SubscriptionBasket(models.Model):
    _name="subscription.basket"

    name = fields.Char("Nome", required=True)
    legumes = fields.Many2many('product.product', 'product_legumes', 'product_id', 'legumes_id', string='Legumes')
    frutas = fields.Many2many('product.product', 'product_frutas', 'product_id', 'frutas_id', string='Frutas')
    verduras = fields.Many2many('product.product', 'product_verduras', 'product_id', 'verduras_id', string='Verduras')
    temperos = fields.Many2many('product.product', 'product_temperos', 'product_id', 'temperos_id',string='Temperos')


Hope it will works for you.

Thanks,

Avatar
Discard
Author

Thank you! 'product_legumes', 'product_id', 'legumes_id' are the name for relation, column1 and column2, respectively, right? How do I know these names?

Best Answer

You can look in the Base Model as well.

the description


class Many2many(_RelationalMulti):
""" Many2many field; the value of such a field is the recordset.


:param comodel_name: name of the target model (string)

The attribute ``comodel_name`` is mandatory except in the case of related
fields or field extensions.


The attribute ``comodel_name`` is mandatory except in the case of related
fields or field extensions.
:param relation: optional name of the table that stores the relation in
the database (string)


the database (string)
:param column1: optional name of the column referring to "these" records
in the table ``relation`` (string)


in the table ``relation`` (string)
:param column2: optional name of the column referring to "those" records
in the table ``relation`` (string)

The attributes ``relation``, ``column1`` and ``column2`` are optional. If not
given, names are automatically generated from model names, provided
``model_name`` and ``comodel_name`` are different!


in the table ``relation`` (string)
The attributes ``relation``, ``column1`` and ``column2`` are optional. If not
given, names are automatically generated from model names, provided
``model_name`` and ``comodel_name`` are different!
:param domain: an optional domain to set on candidate values on the
client side (domain or string)


client side (domain or string)
:param context: an optional context to use on the client side when
handling that field (dictionary)


handling that field (dictionary)
:param limit: optional limit to use upon read (integer)


Avatar
Discard