Explicaion de @api.multi @api.on @api.model

2,482 views
Skip to first unread message

josera...@gmail.com

unread,
Nov 20, 2015, 7:12:45 AM11/20/15
to Usuarios Odoo / OpenERP en España
Buenos tardes Pedro.

Estoy empezando en esto de odoo Tengo una pequeña consulta que realizarte ya que después de leerme toda la documentación que he encontrado, no consigo entenderlo del todo.

No se para que valen el 

@api.multi
@api.one
@api.model.

Y considero que esto es algo básico para empezar a programar en Odoo.

Luego no consigo entender otra cosa, estoy intentando implementar que cuando se cambie un valor pase algo, pero me pasa por el método aunque el campo del que depende no cambie. Pasa varias veces cuando la pagina se esta leyendo.

he puesto

@api.onchange("campo")
def funcion

Pedro Manuel Baeza Romero

unread,
Nov 20, 2015, 7:24:57 AM11/20/15
to Usuarios Odoo / OpenERP en España
José Ramón, esto es un foro público, y no debes dirigirte a mí exclusivamente. Primero, porque puede ser que no te responda yo, bien porque no conozco la respuesta, o bien por que no tengo tiempo para responderla (ya que es algo voluntario). Segundo, porque hay otras personas muy válidas que pueden responder igual que yo, y de hecho responden a otras cuestiones, y descartarlas así es un signo de desprecio hacia ellas.

En cualquier caso, las dudas que planteas son muy básicas, y se pueden resolver leyendo la bibliografía básica de Odoo: https://www.odoo.com/documentation/8.0/reference/orm.html#module-openerp.api, y si con eso no te vale, orientando un poco más la pregunta. Nuestro querido Nhomar siempre apunta hacia un enlace muy bueno, que no pretende ofender, si no educar: http://www.sindominio.net/ayuda/preguntas-inteligentes.html.

Un saludo.

--
Has recibido este mensaje porque estás suscrito al grupo "Usuarios Odoo / OpenERP en España" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a openerp-spain-u...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Jose Ramon Garcia

unread,
Nov 20, 2015, 7:41:50 AM11/20/15
to openerp-s...@googlegroups.com
Perdona Pedro, la verdad ha sido al copiar y pegar el email que habia dirigido hacia ti.

Ya había leído el manual sino, no formaría la pregunta.

De todas formas muchas Gracias, y si he ofendido a alguien por dirigirme directamente a Pedro ( sin querer ) lo siento mucho.


Un saludo




--
Has recibido este mensaje porque estás suscrito a un tema del grupo "Usuarios Odoo / OpenERP en España" de Grupos de Google.
Para anular la suscripción a este tema, visita https://groups.google.com/d/topic/openerp-spain-users/1jStnpR8dLc/unsubscribe.
Para anular la suscripción a este grupo y a todos sus temas, envía un correo electrónico a openerp-spain-u...@googlegroups.com.

javiera...@gmail.com

unread,
Nov 21, 2015, 5:43:28 AM11/21/15
to Usuarios Odoo / OpenERP en España
La api de Odoo v8 (la misma que v9) pasó a usar recordsets en vez de usar sobretodo listas de id's (los identificadores del registro en la base de datos). Un recordset es una colección de elementos, de filas de la base de datos. Api v8 se olvida de estar gestionando listas de id's, lo cual hace la programación mucho más agradable.

@api.multi significa que la función esperará que el recordset pueda contener más de un elemento. Nunca deberías asumir que el recordset es único. Por eso es común en estas funciones ver esta estructura:

    for order in self:
        #codigo

Es decir, por cada elemento en el recordset haz #codigo.

@api.one confunde a mucha gente. No significa que solo se pueda llamar con un recordset único. @api.one es muy parecida a @api.multi en cuanto gestiona un recordset de varios elementos, solo que a la función, internamente, se la llama tantas veces como sea necesaria con una solo elemento del recordset cada vez hasta que se hayan procesado todos. Por ejemplo, si tienes un recordset de 3 elementos y lo usas para llamar a una función @api.one, lo que sucederá es que se llamará a esa función 3 veces, cada vez con un solo elemento. Si la función develueve algo (return res), se guardará cada return en una lista con el mismo orden que el recordset y se devolverá esa lista.

Basicamente @api.multi y @api.one son muy parecidos solo que @api.one es el código que hay dentro del loop for que recorre todos los elementos del recordset de @api.multi. El nombre de @api.one era lioso porque parece que requiera recordsets con un solo elemento, así que en la documentación de Odoo v9 se recomienda no usar y usar solo @api.multi.

Si requieres asegurarte que una función gestione un recordset de un solo elemento, por ejemplo para funciones que interactuan con las views, necesitas usar @api.multi con self.ensure_one(), así:

    @api.multi
    def mi_función(self):
        self.ensure_one()
        #codigo

@api.model es solo para poder interactuar adecuadamente con módulos que usen la API antigua. Básicamente @api.model hace esto:

@api.model
def mi_función(self, var1, var2):

la transforma si es necesario a api antigua de esta manera:

def mi_función(self, cr, uid, var1, var2, context=None):

Notese la diferencia con @api.multi, que equivale a esto:

@api.multi
def mi_función(self, var1, var2):

def mi_función(self, cr, uid, ids, var1, var2, context=None):

@api.multi incluye un recordset que se traduce en api antigua como una lista de id's.

Javier

Jose Ramon Garcia

unread,
Nov 23, 2015, 2:45:10 AM11/23/15
to openerp-s...@googlegroups.com
Muchas Gracias Javier.

La verdad es que es una explicación excepcional, y ahora si, que he entendido para que vale cada anotación.

repito,
Muchas Gracias

Temo Diaz

unread,
Oct 26, 2017, 4:12:05 PM10/26/17
to Usuarios Odoo / OpenERP en España
Hola, he leido las respuestas, y debo aclarar lo siguiente:

api.model indica que solo trabajaremos con el modelo,
@api.model
def mi_función(self, var1, var2):
es equivalente a:

def mi_función(self, cr, uid, var1, var2, context=None):
 pero en este caso, no usaremos seld._context por ejemplo

api.multi sirve para compatibilidad entre la api antigua y la nueva
@api.multi
def mi_función(self, var1, var2):

def mi_función(self, cr, uid, ids, var1, var2, context=None):

es decir, vamos a utilizar los valores que se agregan a self: cr, uids, ids
como self._context.
Reply all
Reply to author
Forward
0 new messages