- Lecture seule et validation d'unicité
La lecture seule peut être définie de deux manières : directement dans la définition du champ ou dans la vue de formulaire.
Reprenons l'exemple précédent. Nous allons rendre le champ name du modèle étudiant tech.student en lecture seule.
Méthode 1 : Définition du champ avec attribut readonly
name = fields.Char(string='Nom', readonly=True)
Méthode 2 : Définition dans la vue XML
<field name="name" readonly="1"/>
Important : Pour les modifications de code Python (hors champs), un redémarrage du service suffit. Les modifications de vues nécessitent une mise à niveau du module.
La validation d'unicité peut être réalisée via _sql_constraints (niveau base de données) ou via le décorateur @api.constrains (niveau code Python).
Méthode A : Utilisation de _sql_constraints
Ajoutons un champ student_id (numéro d'étudiant) avec une contrainte d'unicité :
_sql_constraints = [
('student_id_unique', 'UNIQUE(student_id)', 'Ce numéro d\'étudiant existe déjà.')
]
Format : [(nom, condition SQL, message d'erreur)]. La condition peut être UNIQUE, CHECK, PRIMARY KEY, etc. (référez-vous à la documentation PostgreSQL). Après l'ajout, redémarrez le service et mettez à niveau le module. Si des doublons existent avant la contrainte, celle-ci ne pourra pas être créée.
Méthode B : Utilisation de @api.constrains
Vérifions l'unicité du nom de l'étudiant (nom complet) :
from odoo import api, models
class TechStudent(models.Model):
_name = 'tech.student'
@api.constrains('name')
def _check_name_unique(self):
for record in self:
if self.search([('name', '=', record.name), ('id', '!=', record.id)]):
raise ValidationError("Un étudiant avec ce nom existe déjà.")
Différence : _sql_constraints est plus efficace car il repose sur la base de données, tandis que @api.constrains offre plus de flexibilité (validations complexes, messages personnalisés).
- Introduction aux méthodes ORM (Odoo 8)
Voici les méthodes fondamentales de l'ORM Odoo (version 8).
2.1 browse(ids)
Récupère les enregistrements à partir d'une liste d'identifiants.
Retour : liste d'objets.
Exemple :
sale_order = self.env['sale.order'].browse(1) # Récupère la commande client avec id=1
Dans Odoo 8, les méthodes comme search renvoient déjà des enregistrements, donc browse est moins utilisé qu'en v7.
2.2 search(domain)
Recherche les enregistrements correspondant au domaine.
Retour : liste d'objets.
Exemple :
students = self.search([('name', '=', self.name)]) # Trouve les étudiants ayant le même nom
2.3 create(vals)
Crée un nouvel enregistrement.
Retour : l'objet créé.
Exemple :
new_student = self.create({
'name': 'Jean Dupont',
'age': 22,
'sex': 'm',
'student_id': 'S001',
})
2.4 write(vals)
Met à jour les enregistrements courants.
Retour : True ou False.
Exemple :
self.write({'age': 23}) # Modifie l'âge de l'étudiant courant
2.5 unlink()
Supprime les enregistrements courants.
Exemple :
self.unlink() # Supprime l'enregistrement
Environnement
self.env donne accès à le'nvironnement Odoo. Pour obtenir n'importe quel modèle :
sale_order_obj = self.env['sale.order']
En Odoo 8, on n'utilise plus self.pool.get(...) (v7). Pour obtenir l'tuilisateur connecté : self.env.user.
Pour plus de détails, consultez la documentation officielle.