Register_mixin and rpc call

Hi,
When reviewing my code, @pokoli suggest me to use the register_mixin (https://codereview.tryton.org/276871002/diff/262991002/trytond/trytond/model/unit.py#newcode31) instead of hardcoding class name…

Here’s my mixin (unit.py in trytond/model):

# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.cache import Cache
from trytond.rpc import RPC


class UnitMixin(object):
    __slots__ = ()

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls.__rpc__.update({
                'get_unit_symbol': RPC(cache=dict(days=1)),
                })
        # Do not instantiate more than one Cache
        if not hasattr(cls, '_symbol_cache'):
            cls._symbol_cache = Cache(
                cls.__name__ + '.symbol')

    @classmethod
    def get_unit_symbol(cls, id, value=0):
        'Return the symbol and its position'
        position = 1
        symbol = cls._symbol_cache.get(id)
        if not symbol:
            unit, = cls.search([('id', '=', id)])
            symbol = unit.symbol
            cls._symbol_cache.set(id, symbol)
        return (symbol, position)

In module currency, i’m using this mixin but i need to extend it.

init.py

# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

from trytond.model import UnitMixin
from trytond.pool import Pool
from . import currency


def register():
    Pool.register_mixin(currency.UnitMixin, UnitMixin,
        module='currency')
    Pool.register(
        currency.Currency,
        currency.Rate,
        module='currency', type_='model')

and the code added in currency.py

__all__ = ['Currency', 'Rate']


class UnitMixin:

    @classmethod
    def __setup__(cls):
        super().__setup__()

    @classmethod
    def get_unit_symbol(cls, id, value=0):
        symbol, position = super().get_unit_symbol(id, value)
        p_cs_precedes = Transaction().context.get('p_cs_precedes', True)
        n_cs_precedes = Transaction().context.get('_cs_precedes', True)
        if (value < 0 and n_cs_precedes or p_cs_precedes):
            position = 0
        return (symbol, position)


class Currency(UnitMixin, DeactivableMixin, ModelSQL, ModelView):
    'Currency'
    __name__ = 'currency.currency'
    name = fields.Char('Name', required=True, translate=True,

When testing my code, i get this error:

INFO:tryton.rpc:model.currency.currency.get_unit_symbol(1, Decimal('18.00000'), {'client': '6c74fe34-1130-4e77-8244-c50bb2865019', 'warehouse': None, 'employee': None, 'company': 1, 'company.rec_name': 'Preciball SA', 'language': 'fr', 'language_direction': 'ltr', 'groups': [6, 7, 1, 4, 2, 5, 3, 8, 12, 13, 10, 9, 11], 'p_cs_precedes': 0, 'n_cs_precedes': 1, 'locale': {'date': '%d.%m.%Y', 'grouping': [3, 0], 'decimal_point': ',', 'thousands_sep': ' '}})
ERROR:tryton.common.common:FORBIDDEN
Fault: 403

It was working before doing the register_mixin…
Thanks for help!

Tryton raises a 403 FORBIDEN Error when your session has been expired. Did you have correct session?

P.S: I think ‘_cs_precedes’ should be ‘n_cs_precedes’ on the following line:

I think; i’m correctly connected. Before splitting my mixin code, it was working… now with the register_mixin, it seems i’m loosing execution rights on the rpc_call

Corrected… i think it was a keystroke error :slight_smile:

I do not see the point of using Pool.register_mixin.
You can just use your mixin as other mixin’s (e.g. DeactivableMixin).

You must not do that, it does not work. See Issue 9019: Can not run two tests with dictschema - Tryton issue tracker

Because the currency module should extend the behaviour of the UnitMixin which is defined on trytond.

The point suggested by @pokoli was to avoid to hardcode the class name in my code:

Here’s my previous unit.py file:

# This file is part of Tryton.  The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.cache import Cache
from trytond.rpc import RPC
from trytond.transaction import Transaction


class UnitMixin(object):
    __slots__ = ()

    @classmethod
    def __setup__(cls):
        super().__setup__()
        cls.__rpc__.update({
                'get_unit_symbol': RPC(cache=dict(days=1)),
                })
        # Do not instantiate more than one Cache
        if not hasattr(cls, '_symbol_cache'):
            cls._symbol_cache = Cache(
                cls.__name_+ '.symbol')

    @classmethod
    def get_unit_symbol(cls, id, value=0):
        'Return the symbol and its position'
        symbol = cls._symbol_cache.get(id)
        if not symbol:
            unit, = cls.search([('id', '=', id)])
            symbol = unit.symbol
            cls._symbol_cache.set(id, symbol)
        position = 1
        if cls.__name__ == 'currency.currency':
            p_cs_precedes = Transaction().context.get('p_cs_precedes', True)
            n_cs_precedes = Transaction().context.get('n_cs_precedes', True)
            if (value < 0 and n_cs_precedes or p_cs_precedes):
                position = 0
        return (symbol, position)

For the second point, i’ll check issue 9019.

But there is no need for that.

So this is not a problem for you to keep test

if cls.__name__ == 'currency.currency':

I do not know what you are talking about.
But there is nothing special with this Mixin that define just a method and a cache. The Model inheriting this Mixin can customize/override any of the mixin methods.

Ok… i thought i should use absolutely register_mixin to extend method in the mixin… Then i’ll extend my method in my currency model. Thanks !

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.