La relation Hiérarchie entre les modèles

Introduction

La relation Hiérarchie entre les modèles

Dans l’article précédent, nous avons étudier les trois types de relations entre les modèles différents.   Dans plusieurs cas pratiques, nous aurons besoin de représenter la relation entre un modèle et lui-même, on crée à travers ce type de relation ce qu’on appelle une relation hiérarchique, ou les modèles imbriqués.
Un modèle imbriqué (nested model) , est un concept utilisé par les SGBRO (Système de gestion de base de données relationnel Objet), comme le cas avec le SGBDRO PostgreSQL qu’Odoo utilise par défaut, qui permet de représenter des structures de type complexe et d’étendre les fonctions de base d’une base de données  relationnelle (SGBDR)    
Le présent article, a pour objectif de pouvoir présenter un exemple courant qui est la catégorisation ou le typage d’un modèle, en créant une relation hiérarchie entre le modèle et lui-même.
Pour illustrer les concept nous allons utiliser notre modèle exemple ‘agence.vehicule’ pour définir les catégories des véhicules. 

But d’utilisation d’une hiérarchie à un modèle : 

C’est possible de présenter, une relation entre un modèle et lui-même, en utilisant une relation de type ManyToOne, mais en activant l’option des modèles imbriqués, nous aurons plus de fonctionnalités et de performances avec les requêtes engendrés par l’ORM Odoo.
L’exemple le plus courant, est la catégorisation ou la classification des modèles.  Chaque catégorie peut avoir plusieurs autres sous catégories, et peut elle-même être une sous classe d’une autre catégorie.
L’autre exemple, est la composition ou la relation Composant/Composé. Un Composant peut être composé par plusieurs autres composants, et ainsi de suite.
Le non contrôle de ce type de relations peut engendrer le problème de récursion, et pour éviter ce type de problèmes Odoo dispose d’une fonction de vérification de non existence de récursion lors de l’ajout de nouveaux enregistrements.  

Application à notre exemple Agence de Location de Véhicule :

Afin d’avoir une idée claire sur le concept hiérarchie des modèles, nous revenons à notre exemple Gestion de location de véhicules en lui ajoutant un autre modèle, qui permettra de gérer les catégories des véhicules. 

1.Ajoutez le modèle agence.categorie.vehicule:

 Dans le répertoire des modèles créer le fichier python et appelez le agence_categorie_vehicule.py, Puis mettez dedans le code suivant :
 
from odoo import models,fields,api
from odoo.exceptions import ValidationError 

class AgenceCategVehicule(models.Model):
    _name = 'agence.categorie.vehicule'
    _description = 'Représentation des catégrories des véhicules'
    _parent_store = True
    _parent_name = "parent_id"  # optional if field is 'parent_id'
    parent_path = fields.Char(index=True)
    name=fields.Char('Catégorie')

    parent_id=fields.Many2one(
        'agence.categorie.vehicule',
        ondelete='restrict',
        string='Catégorie Mère',
        Index=True
    )
    child_ids = fields.One2many(
        'agence.categorie.vehicule',
        'parent_id',
        ondelete='restrict',
        string='Sous-Catégorie ,
        Index=True
    )
    @api.constrains('parent_id')
    def _check_hierarchy(self):
            if not self._check_recursion():
                raise models.ValidationError('Error! You cannot create recursive categories.')

Explication des différentes parties du code précédents :

_parent_store , _parent_name et parent_path
En précisant ces trois paramètres, on indique au compilateur qu’il s’agit d’une relation de hiérarchie, en précisant que le catégorie mère sera enregistrée et qui portera le nom de la catégorie mère.
parent_id=fields.Many2one('agence.categorie.vehicule',ondelete='restrict',string='Catégorie Mère',Index=True )
Le champ name portera le nom de la catégorie.
Le champ parent_id, précise une relation Plusieurs à Un ManyToOne, entre le modèle catégorie et lui-même avec l’interdiction de la suppression.
child_ids = fields.One2many( 'agence.categorie.vehicule','parent_id', ondelete='restrict',
string='Sous-Catégorie , Index=True )
Le champ child_ids, définit une relation Un à Plusieurs ou OneToMany , toujours entre le modèle et lui-même, définissant les sous catégories, de la catégorie mère (parent_id) et en interdisant la suppression.
Finalement on trouve la fonction _check_recursion(): , qui est une fonction de base Odoo et qui a pour objectif de vérifier la non existence de non récursion dans les enregistrements de l’objet en cours. Cette vérification se fait lors de sauvegarde, dans le cas d’existence d’une récursion un message d’erreur sera affiché à l’utilisateur.

Erreur Récursion relation hiérarchie

2.Déclarer le nouveau fichier dans le paramètre __init__.py :

    from . import  agence_categorie_vehicule

3.Ajoutez le fichier xml des vues du modèle agence.categorie.vehicule  :

Pour visualiser le champ catégorie et sous catégories, ajouter dans le répertoire views le fichier agence_categorie_vehicule.xml , puis mettez  dedans le code suivant qui permettra d’ajouter les vus nécessaires (sous menu, Vue Formulaire, liste et recherche) du modèle agence.categorie.vehicule: 

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <record id='agence_categorie_vehicule_action' model='ir.actions.act_window'>
        <field name="name"> Gestion des Catégories </field>
        <field name="res_model">agence.categorie.vehicule</field>
        <field name="view_mode">tree,form</field>
    </record>
    <menuitem name="Catégories" id="agence_categorie_veicule_menu"
     parent="agence_base_menu" action="agence_categorie_vehicule_action"/>
    <record id="agence_categorie_vehicule_view_form" model="ir.ui.view">
        <field name="name">Agence Catégorie Vehicules Form</field>
        <field name="model">agence.categorie.vehicule</field>
        <field name="arch" type="xml">
            <form>
            <sheet>
                <group>
                    <group>
                        <field name="name"/>
                        <field name="parent_id"/>
                        <field name="child_ids" widget="many2many_tags"/>
                    </group>
                </group>
            </sheet>
            </form>
        </field>
    </record>
    <record id="agence_categorie_vehicule_tree" model="ir.ui.view">
            <field name="name">Agence Catégorie Lise</field>
            <field name="model">agence.categorie.vehicule</field>
            <field name="arch" type="xml">
                <tree>
                    <field name="name"/>
                </tree>
            </field>
    </record>
    <record id="agence_categorie_vehicule_search" model="ir.ui.view">
            <field name="name">Agence Categorie Recherche</field>
            <field name="model">agence.categorie.vehicule</field>
            <field name="arch" type="xml">
                <search>
                    <field name="name"/>
                </search>
            </field>
    </record>
</odoo>

4.Ajoutez le cham catégorie_id, dans le modèle agence.vehicule 

Pour associer un véhicule à une catégorie, nous devons ajouter le champ category_id dans le modèle agence.vehicule en ajoutant la ligne suivante:
category_id = fields.Many2one('agence.categorie.vehicule', string=’Catégorie’)
Ensuite, on doit déclarer ce champ dans la vue formulaire du véhicule, en ajoutant simplement la ligne de code suivante :
<field name="category_id"/>

5.Ajoutez le group et les droits d’accès au nouveau modèle agence.categorie.vehicule: 

Nous avons ajouté un nouveau modèle, on doit donc ajouter le groupe et les droits d’accès, pour se faire rendez vous sur fichier groups.xml et ajouter le record suivant :
<record id="group_ag_categorie_managers" model="res.groups">
        <field name="name">Agence Categorie Managers</field>
        <field name="users" eval="[(4, ref('base.user_admin'))]"/>
    </record>

Ensuite, dans le fichier ir.model.access.csv
acl_agence_categ_users,agence.categorie.vehicule default,model_agence_categorie_vehicule,,1,0,0,0
acl_agence_categ_admin,agence.categorie.vehicule_admin,model_agence_categorie_vehicule,group_ag_categorie_managers,1,1,1,1

6.Déclarez la nouvelle vue dans le fichier __manifest__.py :

Pour se faire éditer le fichier __manifest__.py et ajouter la ligne suivante dans la section ‘data’ :
,'views/agence_categorie_vehicule.xml'

7.Redémarrez le serveur et mettez à jour de l’application.

  • La relation Hiérarchie entre les modèles
  • La relation Hiérarchie entre les modèles
Pour visualiser les changements effectués, redémarrer Odoo et mettez à jour l’application.
Vous remarquerez l’ajout de l’option de menu Catégorie, et l’ajout du champ catégorie dans le formulaire des véhicules. 

Conclusion

La définition de La relation hiérarchie qui représente une relation entre un modèle et lui-même, permet d’utiliser les outils Odoo dédiés spécialement à ce type de relation, et permet une meilleur performance et clarté de modélisation.
Dans cet article nous avons découvert, comment implémenter le concept de la relation hiérarchie ou les modèles imbriqués (nested models), permettant ainsi d’étendre les autres types de relations (OneToMany, ManyToOne, ManayToMany) qui présentait des limites dans certains cas pratiques, comme la catégorisation et la composition.  

Télécharger gratuitement votre  guide odoo ! 

Télécharger Gratuitement votre guide Odoo

Découvrez comment , Odoo  est une vraie opportunité pour les entreprises et les développeurs !


Télécharger !