Relación many2one/one2many en OpenERP (Odoo), ejemplo

En OpenERP existen distintos tipos de campos propios del sistema, son clases ya formadas que implementan métodos para definir el tipo de campo que guardará un tipo de dato específico en una tabla de la base de datos, dos de los tipos de campos particulares son: many2one y one2many, pudiéramos decir de muchos a uno y de uno a muchos, son campos netamente relacionales.

many2one hace referencia hacia una tabla completa, su sintaxis es la siguiente:

'materia_id': fields.many2one('usuario.materia', 'Materias')

En la vista, el campo mostrará la etiqueta Materias, dejando ver un combo con los name de las materias registradas en la tabla usuario.materia, pero éste campo debe tener un campo relacionado en dicha tabla usuario.materia para que se encadene la relación, por así decirlo.

one2many hace referencia hacia un campo específico de una tabla específica, encadenando la relación iniciada por el campo many2one, su sintaxis se vería de la siguiente manera:

'estudiante_ids': fields.one2many('usuario.estudiante', 'materia_id', 'Estudiante')

Este campo se verá por defecto en la vista como una lista o vista tree cuando es invocado en un formulario, dicha vista puede ser manipulada en un record sugiriendo qué campos se verán y qué campos se quedarán ocultos para la vista, también puede ser manipulado para su respectiva vista form, es cuestión de jugar con lo que se quiere en el momento.

En un aspecto general de la relación pudiera ser de la siguiente manera:

# -*- coding: utf-8 -*-

from openerp.osv import fields, osv

class usuario_estudiante(osv.Model):

    _name = 'usuario.estudiante'
    _description = 'Tabla de usuarios de tipo estudiante'
    _columns = {
        'name': fields.char('Nombre', size=250),
        'direccion': fields.text('Dirección'),
        'email': fields.char('Email'),
        'materia_id': fields.many2one('usuario.materia', 'Materias')
    }
# Fin de la clase usuario_estudiante


class usuario_materia(osv.Model):

    _name = 'usuario.materia'
    _description = 'Tabla de materias de estudiantes'
    _columns = {
        'name': fields.char('Materia'),
        'descripcion': fields.text('Descripción'),
        'nota': fields.float('Nota', digits=(2, 2)),
        'estudiante_ids': fields.one2many('usuario.estudiante', 'materia_id', 'Estudiante')
    }
# Fin de la clase usuario_materia

En donde el campo materia_id se enlaza al campo estudiante_ids y viceversa.

Advertisements

About felixurbina

Humano con todos los defectos y virtudes que vienen de fábrica.
This entry was posted in Odoo, OpenERP. Bookmark the permalink.

15 Responses to Relación many2one/one2many en OpenERP (Odoo), ejemplo

  1. Hola amigo, una pregunta tu sabes como puedo hacer para que un campo many2one muestre 8 elementos, es que por defecto solo esta mostrando siete, muchas gracias

    • felixurbina says:

      Hola qué tal! Si tu many2one va a una vista tree, es probable que tome la que viene por defecto en el módulo, debes hacer una vista tree heredando la original y agregando el campo que quieres agregar, cuando haces clic en el campo many2one debería aparecer tu modificación, procura colocarle un índice de priority alto para que compile de último el cambio que harás.

      Saludos.

  2. Aguzman says:

    Buenas tardes amigo, tengo una tabla llamada alumnos con sus respectivos campos y una tabla llamada eventos a la cual quiero enlazar a los alumnos que asistirán mediante su numero de control. Así es como lo tengo:

    class Register(osv.Model):
    _name = “extraescolares.register”
    _columns = {
    ‘names’: fields.char(string=”Nombres”, size=256, required=True,
    help=”nombres del alumno”),
    ‘surname’: fields.char(string=”Apellidos”, size=256, required=True,
    help=”apellidos del alumno”),
    ‘num_control’: fields.integer(string=”Numero de control”, size=8,
    required=True, help=”numero de control”),
    ‘sexo’: fields.selection(_get_selection_sexo, string=’Sexo’,
    required=True, help=”Seleccionar Sexo”),

    ‘carrera’: fields.selection(_get_selection_carrera, string=”Carrera”,
    required=True,
    help=”Seleccionar nombre de la carrera”),
    ‘semester’: fields.selection(_get_selection_semester, ‘Semestre’,
    required=True, help=”Elegir el semestre”),
    ‘num_telefono’: fields.float(string=”No.Telefono”,
    size=10, digits=(10, 0),
    help=”Numero de telefono”),

    ’email’: fields.char(string=”e-mail”, size=256,
    help=”Correo electronico”)
    #############################################################################
    class Actividad(osv.Model):
    _name = “extraescolares.eventos”

    _columns = {
    ‘name’: fields.char(string=”Nombre”, size=300, required=True,
    help=”Nombre de la actividad”),
    ‘fecha_inicio’: fields.date(string=”Fecha Inicio”, required=True,
    help=”Fecha de incio de la actividad”),
    ‘fecha_fin’: fields.date(string=”Fecha Fin”, required=True,
    help=”Fecha de fin de la actividad”),
    ‘horas’: fields.integer(string=”Horas Asignadas”, required=True,
    size=2, help=”Horas Asignadas”),
    ‘responsable’: fields.char(string=”Responsable”, required=True,
    size=256, help=”Responsable del evento”),
    ‘anotaciones’: fields.text(‘Anotaciones’, help=”Escriba anotaciones”),

    ‘num_control_id’: fields.one2many(‘extraescolares.asistentes’,
    ‘num_control’,
    string=”Alumnos”,
    required=True, ondelete=’cascade’)

    ##########################################################################
    class asistentes(osv.Model):
    _name = “extraescolares.asistentes”

    _columns = {
    ‘num_control’: fields.many2one(‘extraescolares.register’,
    string=”Alumnos”,
    required=True, ondelete=’cascade’)
    }

    como hago para que en la vista eventos, me traiga el num_control del alumno?
    Disculpa mi atrevimiento y si puedes ayudarme te lo agradeceré

    • felixurbina says:

      Qué tal Aguzman,

      Bueno, de hecho ya tienes referenciado el campo en la lista de eventos, es cuestión de que en la vista, muestres el campo como una lista, en alguna parte de tu vista de eventos tendrías que agregar algo parecido a:

      <field name=”num_control_id”>
      <tree string=”Alumnos”>
      <field name=”num_control”/>
      </tree>
      </field>

      Porque básicamente tienes es una lista de asistentes dentro de tu tabla eventos, no mostrará más datos.

      Saludos.

      • Aguzman says:

        Muchas gracias por contestar, de hecho así tengo la vista

        Esto es lo que me trae el campo:
        extraescolares.register,4

        la relación y el id del campo en la tabla register, y lo que yo quiero es que me traiga el num_control.
        Gracias por la ayuda!!

  3. David says:

    Buenas Tardes.

    Yo tengo el mismo problema. Si saben como resolverlo y no les molesta compartirlo me pueden avisar por favor?

    • David says:

      El mismo problema que Aguzman

      • felixurbina says:

        Ya veo, es probable que no está relacionada la vista exactamente hacia donde debe ir relacionada. Es decir, si los campos base de la vista está en la tabla estudiantes.estudiantes y hay otra tabla llamada estudiantes.materias que servirá de vista tree dentro de estudiantes.estudiantes, deben relacionar esa vista a una vista tree aparte, por ejemplo:

        estudiantes.materias.view.tree
        estudiantes.materias

        Esta vista tree puede estar separada en otra parte del archivo, luego dentro de una vista form, llaman al campo que relaciona estudiantes.estudiantes con estudiantes.materias, por ejemplo el materias_ids.

        Haré otro post a ver si me explico un poco mejor con el archivo .py y el archivo .xml que debería llevar la relación.

        Saludos.

  4. David says:

    Buenos días y gracias por contestar felixurbina.

  5. deyocamp says:

    Buenos días.
    No se me mostraba el código por eso le decía que si lo mandaba por correo, pero veo que es por las comillas.

    Lo que pasa es que quiero hacer un combo que me muestre los datos de nombre_modelo, pero solo muestra objeto.tab1.1, objeto.tab1.2, etc. La relación está entre modelo y nombre_modelo y abajo pongo el código y la vista. La primera clase está heredada y es una pestaña que agrego a clientes en contabilidad o ventas. A ver si estoy haciendo algo mal y por su experiencia supiera de que se trata. Si no es mucha molestia.

    Le agradezco la paciencia y disculpe la molestia.

    class objeto_tab2(osv.Model):
    _name = `objeto.tab2`
    _description = `Tabla secundaria guardar los campos de vehiculos`
    _columns = {
    `id_mod`: fields.many2one(`res.partner`, string=`Id Modelo`, ondelete=`cascade`),
    `modelo`: fields.one2many(`objeto.tab1`,`nombre_modelo`, string=`Modelo`, ondelete=`cascade`)
    }
    objeto_tab2()
    class objeto_tab1(osv.Model):
    _name = `objeto.tab1`
    _columns = {
    `nombre_modelo`: fields.many2one(`objeto.tab2`, string=`Modelo`, ondelete=`cascade`),
    }
    objeto_tab1()

    #################################################################################

  6. deyocamp says:

    res.partner.property.form.inherit
    res.partner
    3

    <page string=“Vehículos“ col=“6“ name=“vehiculos“ attrs=“{`invisible`:……….. [(`is_company`,`=`,Fa…………………………………..

  7. deyocamp says:

    Buenos días.
    No se me mostraba el código por eso le decía que si lo mandaba por correo, pero veo que es por las comillas.

    Lo que pasa es que quiero hacer un combo que me muestre los datos de nombre_modelo, pero solo muestra objeto.tab1.1, objeto.tab1.2, etc. La relación está entre modelo y nombre_modelo y abajo pongo el código y la vista. La primera clase está heredada y es una pestaña que agrego a clientes en contabilidad o ventas. A ver si estoy haciendo algo mal y por su experiencia supiera de que se trata. Si no es mucha molestia.

    Le agradezco la paciencia y disculpe la molestia.

    class objeto_tab2(osv.Model):
    _name = `objeto.tab2`
    _description = `Tabla secundaria guardar los campos de vehiculos`
    _columns = {
    `id_mod`: fields.many2one(`res.partner`, string=`Id Modelo`, ondelete=`cascade`),
    `modelo`: fields.one2many(`objeto.tab1`,`nombre_modelo`, string=`Modelo`, ondelete=`cascade`)
    }
    objeto_tab2()
    class objeto_tab1(osv.Model):
    _name = `objeto.tab1`
    _columns = {
    `nombre_modelo`: fields.many2one(`objeto.tab2`, string=`Modelo`, ondelete=`cascade`),
    }
    objeto_tab1()

    #################################################################################

  8. 0rfe0 says:

    Creo haber hecho algo parecido hace un par de años, corrijanme si me equivoco!!!

    El problema es que la tabla a la que enlazamos el one2many no tiene declarada un _rec_name y creo que para este modulo la solucion sera colocar _rec_name = ‘modelo’
    Creo haber solucionado en su momento esto asi, la verdad no lo he probado pero creo estar seguro que era la solucion… pueden visitar tambien mi blog que habla de asuntos parecidos 😀
    https://stickybitshell.wordpress.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s