Étape 2 sur 3

Afficher les notes dans Odoo

La liste, le formulaire et les menus sont des fichiers XML. Odoo les relie aux modèles et enregistre les modifications dans PostgreSQL avec son ORM.

1. Donnez les droits minimaux

Une vue ne donne pas le droit de manipuler les données. Pour la formation, les utilisateurs internes peuvent gérer les notes et les catégories. Nous détaillerons les droits plus fins au jour 5.

custom_addons/training_hello/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_training_note_user,training.note user,model_training_note,base.group_user,1,1,1,1
access_training_note_category_user,training.note.category user,model_training_note_category,base.group_user,1,1,1,1
Remplacez le contenu du CSV, ne l'ajoutez pas à la suite

Le module créé au début de la formation peut contenir une ancienne règle d'exemple pour le modèle training_hello.training_hello. Ce modèle n'existe plus lorsque sa classe est commentée : laissez cette ancienne ligne dans le CSV et la mise à niveau échouera, même si les deux lignes de notes sont justes.

security/ir.model.access.csv · ligne d'exemple à supprimer si elle est présente
access_training_hello_training_hello,training_hello.training_hello,model_training_hello_training_hello,base.group_user,1,1,1,1

Gardez la ligne d'en-tête, puis faites en sorte que les deux lignes access_training_note_... ci-dessus soient les seules règles de ce fichier pour cet exercice.

État final du fichier ir.model.access.csv dans VS Code : une ligne de droits pour training.note et une ligne pour training.note.category, toutes deux accordées au groupe base.group_user.
État final attendu : l'en-tête et exactement deux lignes de règles. Les quatre permissions sont à 1 pour les notes comme pour les catégories.

Lire la première ligne, cellule par cellule

La première ligne de données accorde les droits sur les notes. Une virgule sépare chaque cellule :

security/ir.model.access.csv · première ligne de droits
access_training_note_user,training.note user,model_training_note,base.group_user,1,1,1,1
CelluleValeurCe qu'elle désigne
idaccess_training_note_userL'identifiant externe de cette règle d'accès. Il permet à Odoo de retrouver cette même règle lors d'une mise à niveau.
nametraining.note userUn libellé lisible par les personnes qui administrent Odoo. Il n'est pas utilisé pour décider l'accès.
model_id:idmodel_training_notemodel_id est le champ de la règle qui pointe vers la fiche du modèle dans ir.model ; :id demande à Odoo de résoudre la valeur comme un identifiant externe. model_training_note est sa forme courte dans ce module : Odoo la résout en training_hello.model_training_note.
group_id:idbase.group_userLe groupe Odoo des utilisateurs internes. Seuls les membres de ce groupe reçoivent cette règle.
perm_read, perm_write, perm_create, perm_unlink1,1,1,1Quatre indicateurs : lire, modifier, créer et supprimer. 1 autorise l'opération ; 0 la refuse.
Décomposer model_training_note

Le nom technique du modèle, celui que nous avons écrit en Python, est training.note. Sa table PostgreSQL est training_note. Pour référencer la fiche qui décrit ce modèle dans ir.model, Odoo crée l'identifiant externe training_hello.model_training_note : nom du module training_hello, puis model_, puis training.note avec le point remplacé par un tiret bas.

Donc non : model n'est pas la valeur de model_id. C'est seulement le préfixe de cet identifiant externe généré. La valeur de la colonne model_id:id est bien la référence model_training_note, qui mène à la fiche ir.model de training.note.

Conseil d'édition : lire le CSV comme un tableau

Un fichier CSV reste du texte, mais ses nombreuses colonnes sont plus faciles à vérifier dans une vue en tableau. Dans VS Code, vous pouvez installer l'extension facultative CSV de ReprEng depuis le Marketplace, puis rouvrir ir.model.access.csv. Elle aide à repérer les colonnes et les valeurs 1, sans modifier le rôle du fichier dans Odoo.

Gardez le bon réflexe : l'extension n'accorde aucun droit, ne valide pas la sécurité Odoo et ne remplace pas le CSV versionné. Avant d'enregistrer, vérifiez toujours la ligne d'en-tête et chaque identifiant technique dans le texte du fichier.

2. Créez les listes, les fiches et les menus

Un clic dans une liste ouvre la fiche correspondante. Les deux modèles reçoivent leur propre action et leur propre entrée de menu : les catégories sont donc administrables sans SQL.

custom_addons/training_hello/views/training_note_views.xml
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
  <record id="training_note_category_view_list" model="ir.ui.view">
    <field name="name">training.note.category.list</field>
    <field name="model">training.note.category</field>
    <field name="arch" type="xml">
      <list><field name="name"/></list>
    </field>
  </record>

  <record id="training_note_category_view_form" model="ir.ui.view">
    <field name="name">training.note.category.form</field>
    <field name="model">training.note.category</field>
    <field name="arch" type="xml">
      <form><sheet><group><field name="name"/></group></sheet></form>
    </field>
  </record>

  <record id="training_note_view_list" model="ir.ui.view">
    <field name="name">training.note.list</field>
    <field name="model">training.note</field>
    <field name="arch" type="xml">
      <list>
        <field name="title"/>
        <field name="category_id"/>
      </list>
    </field>
  </record>

  <record id="training_note_view_form" model="ir.ui.view">
    <field name="name">training.note.form</field>
    <field name="model">training.note</field>
    <field name="arch" type="xml">
      <form><sheet><group>
        <field name="title"/>
        <field name="category_id"/>
        <field name="body"/>
      </group></sheet></form>
    </field>
  </record>

  <record id="training_note_action" model="ir.actions.act_window">
    <field name="name">Notes</field>
    <field name="res_model">training.note</field>
    <field name="view_mode">list,form</field>
  </record>
  <record id="training_note_category_action" model="ir.actions.act_window">
    <field name="name">Catégories</field>
    <field name="res_model">training.note.category</field>
    <field name="view_mode">list,form</field>
  </record>

  <menuitem id="training_note_menu_root" name="Notes de formation" sequence="30"/>
  <menuitem id="training_note_menu" name="Notes" parent="training_note_menu_root" action="training_note_action" sequence="10"/>
  <menuitem id="training_note_category_menu" name="Catégories" parent="training_note_menu_root" action="training_note_category_action" sequence="20"/>
</odoo>

En Odoo 19, utilisez <list>, pas l'ancien nom <tree>. Le field category_id devient un choix de catégories dans le formulaire : Odoo affiche leur nom, mais enregistre leur identifiant dans la note.

3. Déclarez les fichiers dans le manifeste

Ajoutez ces deux fichiers après les données XML. Conservez toutes les entrées déjà présentes : le manifeste est la liste complète des fichiers qu'Odoo charge.

custom_addons/training_hello/__manifest__.py · repère d'insertion dans data
"data": [
    # ...
    "security/ir.model.access.csv",  # ← ajoutez cette ligne
    "views/training_note_views.xml",  # ← ajoutez cette ligne
    # ...
],

Pour copier uniquement les deux lignes :

custom_addons/training_hello/__manifest__.py · lignes à ajouter
"security/ir.model.access.csv",
"views/training_note_views.xml",
custom_addons/training_hello/__manifest__.py · liste data complète
"data": [
    "views/hello_world_menus.xml",
    "data/partner_category_data.xml",
    "views/partner_category_list.xml",
    "data/training_note_data.xml",
    "data/training_note_category_data.xml",
    "security/ir.model.access.csv",
    "views/training_note_views.xml",
],

4. Rechargez correctement, puis ouvrez l'application

La mise à niveau du module est indispensable : elle importe le CSV des droits et le XML des vues dans la base. Un simple rechargement du navigateur ne suffit pas.

  1. Vous avez ajouté un fichier ou modifié __manifest__.py : redémarrez Odoo si votre lancement ne recharge pas automatiquement les fichiers.
  2. Dans Apps, cherchez Hello Odoo, puis cliquez sur Mettre à niveau.

Si vous avez seulement modifié une ligne dans un CSV ou un XML déjà déclaré, le redémarrage n'est généralement pas nécessaire ; faites tout de même la mise à niveau du module. Dans le lanceur d'applications, ouvrez ensuite Notes de formation. Vous devez voir les deux menus Notes et Catégories.

Diagnostic : « No matching record found for external id model_training_hello_training_hello »

Cette erreur ne désigne pas les notes. Elle indique qu'Odoo lit encore l'ancienne ligne d'exemple ci-dessus : sa référence vise le modèle abandonné training_hello.training_hello. Supprimez cette ligne, enregistrez le CSV, puis mettez à niveau Hello Odoo. En revanche, model_training_note est la bonne référence pour le modèle que nous avons réellement créé : training.note.