Einführung
Wenn Sie mit der Odoo-Entwicklung beginnen, taucht ein Konzept immer wieder auf: Vererbung. Das ORM von Odoo basiert auf der Idee, dass Modelle die Felder anderer Modelle erweitern, teilen und wiederverwenden können, ohne Daten zu duplizieren oder redundanten Code zu schreiben.
Vererbte Felder sind zentral für dieses System. Sie ermöglichen es Odoo, einem Modell den transparenten Zugriff auf und die Offenlegung von Feldern zu ermöglichen, die physisch auf einem anderen Modell definiert und gespeichert sind. Sobald Sie diesen Mechanismus verstanden haben, beginnen viele Dinge im Odoo-Datenmodell Sinn zu machen.
Dieser Leitfaden erklärt, was vererbte Felder sind, die drei Arten von Modellvererbung, die sie erzeugen, wie sie sich in der Datenbank verhalten und wie Sie sie in realen Odoo-Anpassungsprojekten verwenden können.
Was ist ein vererbtes Feld in Odoo?
Im ORM-Framework von Odoo wird ein Feld als vererbt betrachtet, wenn ein Modell Zugriff auf Felder erhält, die in einem anderen Modell über einen der drei unterstützten Vererbungsmechanismen definiert sind. Anstatt diese Felder von Grund auf neu zu definieren, verwendet das Kindmodell sie einfach wieder.
Das ist ein Teil dessen, was das Odoo-Datenmodell so kompakt und konsistent macht. Das gleiche name-Feld in einem Partnerdatensatz erscheint in Verkaufsaufträgen, CRM-Leads und Rechnungen, da all diese Modelle letztendlich aus derselben Quelle lesen.
Die drei Arten der Vererbung in Odoo
Odoo unterstützt drei verschiedene Arten der Modellvererbung, und jede behandelt Felder unterschiedlich.
1. Klassische Vererbung
Dies ist das häufigste Muster in der Odoo-Entwicklung. Sie verwenden _inherit, ohne ein neues _name zu definieren. Dies erweitert ein bestehendes Modell direkt und fügt neue Felder oder Methoden hinzu. Es wird keine neue Datenbanktabelle erstellt. Die neuen Felder erscheinen einfach im ursprünglichen Modell.
So fügen die meisten Odoo-Module Felder zu Standardmodellen hinzu. Wenn Sie das CRM-Modul installieren, fügt es Felder zu res.partner durch klassische Vererbung hinzu. Diese Felder werden in der Partner-Tabelle zusammen mit den Kernfeldern gespeichert.
2. Prototyp-Vererbung
Dies ist der Fall, wenn Sie _inherit und _name zusammen kombinieren. Das neue Modell beginnt als Kopie der Struktur des Elternmodells, erhält jedoch seine eigene Datenbanktabelle. Alle Elternfelder werden in das neue Modell dupliziert. Änderungen am Kindmodell wirken sich nicht auf das Elternmodell aus.
Dieses Muster ist im Alltag weniger verbreitet, wird jedoch verwendet, um völlig neue Modelle zu erstellen, die die Struktur eines bestehenden Modells teilen.
3. Delegationsvererbung
Dies ist die markanteste Art, die mit _inherits definiert wird. Das Kindmodell verknüpft sich über ein Many2one-Feld mit einem Elternmodell. Das Kindmodell gibt dann alle Felder des Elternmodells transparent als wären sie eigene aus. Die Daten leben in der Tabelle des Elternmodells, nicht in der Tabelle des Kindmodells.
Dies ist, was die meisten Entwickler meinen, wenn sie im strengen Sinne von vererbten Feldern sprechen. Die Felder werden nicht dupliziert. Sie werden über die relationale Verbindung zur Lese- und Schreibzeit zugegriffen.
Das bekannteste Beispiel in standard Odoo ist die Beziehung zwischen res.users und res.partner. Jeder Benutzer ist auch ein Partner. Der Name, die E-Mail-Adresse und die Telefonnummer des Benutzers werden im Partnerdatensatz gespeichert und vom Benutzer über die Delegationsvererbung abgerufen.
Wie das Feld funktioniert
Delegationsvererbung im Hintergrund
Wenn ein Modell _inherits verwendet, erstellt Odoos ORM eine transparente Brücke zwischen zwei Datenbanktabellen. Wenn Sie ein vererbtes Feld im Kinddatensatz lesen, folgt Odoo automatisch dem Many2one-Link zum Eltern-Datensatz und gibt den dort gespeicherten Wert zurück.
Wenn Sie in ein vererbtes Feld aus dem Kindmodell schreiben, schreibt Odoo direkt in den Eltern-Datensatz. Aus der Perspektive des Entwicklers fühlt sich das Feld nativ an. Aus der Perspektive der Datenbank lebt die Daten in der Elterntabelle.
Dies hat eine wichtige Konsequenz: Es gibt keine Datenverdopplung. Wenn Sie den Namen eines Partners aktualisieren, spiegelt sich diese Änderung sofort überall wider, wo der Partner referenziert wird, einschließlich im Benutzerdatensatz, der davon erbt.
Klassische Vererbung und die Datenbank
Bei der klassischen Vererbung werden neue Felder zur Datenbanktabelle des ursprünglichen Modells hinzugefügt. Es ist keine zweite Tabelle beteiligt. Das erweiterte Modell und das ursprüngliche Modell sind im Datenbank dasselbe. Dies ist der sauberste und gebräuchlichste Weg, um Felder in Odoo-Anpassungsprojekten hinzuzufügen.
Verwandte Felder als leichte Vererbung
Ein related Feld ist eine spezielle Art von berechnetem Feld im Odoo ORM, das einen Wert aus einem verknüpften Datensatz über eine Kette relationaler Felder liest. Es ist nicht strikt dasselbe wie die Modellvererbung, wird jedoch häufig verwendet, um vererbte Daten auf einem Modell anzuzeigen, ohne die Struktur des Modells zu ändern.
Zum Beispiel könnten Sie ein partner_country_id Feld auf einem Verkaufsauftrag definieren, das partner_id.country_id liest. Das Feld verhält sich wie ein natives Feld auf dem Verkaufsauftrag, aber der Wert stammt vom Partner.
Verwandte Felder können optional in der Datenbank mit store=True gespeichert werden, was die Such- und Filterleistung verbessert, aber zusätzlichen Speicheraufwand verursacht und eine Neuberechnung erfordert, wenn die Quelle sich ändert.
Wie Felder zur Laufzeit aufgelöst werden
Wenn Odoo eine Modelldefinition lädt, wird die vollständige Feldzuordnung aufgelöst, einschließlich aller geerbten Felder. Bis ein Modell zur Verwendung bereit ist, hat Odoo bereits jedes zugängliche Feld seiner Quelle zugeordnet, unabhängig davon, ob diese Quelle die eigene Tabelle des Modells, eine über Delegation verbundene Elterntabelle oder eine verwandte Kette ist. Diese Auflösung erfolgt einmal beim Serverstart und wird zur Leistungssteigerung zwischengespeichert.
Geschäftsanwendungsfälle
Geerbte Felder sind nicht nur ein technisches Konzept. Sie lösen echte Geschäftsprobleme, indem sie die Daten über verschiedene Teile von Odoo hinweg konsistent halten, ohne Duplikate zu erzeugen.
1. CRM und Vertrieb: Kontaktinformationen
Wenn ein Verkäufer im CRM-Modul einen Lead erstellt, stammen der Kundenname, die Telefonnummer und die E-Mail-Adresse über einen Many2one-Link aus dem Partnerdatensatz. Wenn sich die Details des Partners ändern, spiegelt jeder Lead, jedes Angebot und jede Bestellung, die mit diesem Partner verknüpft sind, die Aktualisierung sofort wider.
Dies ist klassische Vererbung und verwandte Felder, die zusammenarbeiten. Das CRM-Modul erweitert res.partner mit CRM-spezifischen Feldern (wie Lead-Anzahl und Verkaufschance-Stadium), und Verkaufsbestellungen zeigen die Kontaktdaten des Partners über verwandte Felder an.
2. Produkte und Varianten
Das Produktmodell von Odoo verwendet die Delegationsvererbung, um Produktvarianten sauber zu handhaben. Das product.product-Modell (eine spezifische Variante) verwendet _inherits, um mit product.template zu verknüpfen. Felder, die über alle Varianten hinweg geteilt werden, wie Produktname, Kategorie, Verkaufspreis und Beschreibung, befinden sich auf der Vorlage. Variantenspezifische Felder wie Barcode oder interne Referenz befinden sich im Variantendatensatz selbst.
Dieses Design bedeutet, dass Sie 50 Farbvarianten eines Shirts haben können, die alle denselben Namen und dieselbe Beschreibung teilen, ohne diese Werte 50 Mal in der Datenbank speichern zu müssen.
3. Benutzer und Partner
Jeder Odoo-Benutzer ist auch ein Kontakt. Das res.users-Modell verwendet _inherits = {'res.partner': 'partner_id'}, was bedeutet, dass der Benutzer automatisch alle Partnerfelder erbt, einschließlich Name, E-Mail, Telefon, Adresse und Profilbild. Wenn Sie die E-Mail-Adresse eines Mitarbeiters aktualisieren, wird sie gleichzeitig in den Benutzereinstellungen und im Adressbuch aktualisiert.
4. Inventar: Bestandsbewegungen und Produktinformationen
Die Bestandsbewegungen im Modul "Inventar" zeigen Produktbeschreibungen, die über eine Kette verwandter Felder aus der Produktvorlage stammen. Lagerverwalter sehen genaue, aktuelle Produktinformationen direkt in ihren Kommissionierlisten, ohne dass das Inventarmodul Produktdaten duplizieren muss.
5. Buchhaltung: Rechnungszeilen
Buchungszeilen beziehen sich auf Produkte und Partner. Der Produktname, die Kontencodes und die Steuerkonfigurationen, die auf einer Rechnungszeile angezeigt werden, stammen über relationale Links und verwandte Felder aus den Produkt- und Partnermodellen. Buchhalter sehen konsistente Daten, die mit dem übereinstimmen, was die Vertriebsteams für das Produkt konfiguriert haben, da sie aus derselben Quelle lesen.
Erstellen oder Anpassen von vererbten Feldern
Odoo Studio verwenden
Odoo Studio ist die No-Code-Oberfläche zur Anpassung von Odoo-Modellen und -Ansichten. Über Studio können Sie neue Felder zu jedem Modell hinzufügen, ohne Python-Code zu schreiben. Was Studio im Hintergrund tut, ist klassische Vererbung: Es erweitert das Modell, indem es ein neues Feld zu seiner Definition hinzufügt.
Studio ermöglicht es Ihnen auch, verwandte Felder zu erstellen. Wenn Sie "Verwandtes Feld" als Feldtyp wählen, können Sie auf jedes Feld verweisen, das über eine relationale Kette vom aktuellen Modell aus zugänglich ist. Zum Beispiel können Sie im Verkaufsauftragsmodell ein verwandtes Feld erstellen, das das Land oder die USt-IdNr. des Kunden direkt aus dem Partnerdatensatz liest.
Für die meisten Geschäftsanwender und funktionalen Berater ist Studio das richtige Werkzeug, um Felder zu Odoo hinzuzufügen. Es kümmert sich automatisch um die Benennung der Felder, die Datenbankmigration und die Platzierung in der Ansicht.
Technische Anpassung mit Python
Für Entwickler, die Odoo-Module erstellen, werden vererbte Felder in Python unter Verwendung der models.Model-Klasse aus dem Odoo ORM definiert.
Klassische Vererbung, um ein benutzerdefiniertes Feld zu einem bestehenden Modell hinzuzufügen:
class CrmLead(models.Model):
_inherit = 'crm.lead'
x_contract_value = fields.Float(
string='Geschätzter Vertragswert'
)
Delegationsvererbung, um ein neues Modell zu erstellen, das Felder von einem bestehenden teilt:
class EmployeeProfile(models.Model):
_name = 'hr.employee.profile'
_inherits = {'res.partner': 'partner_id'}
partner_id = fields.Many2one(
'res.partner',
required=True,
ondelete='cascade'
)
employee_id = fields.Many2one(
'hr.employee',
string='Mitarbeiter'
)
Verwandte Felder, um einen Wert aus einem verknüpften Datensatz anzuzeigen:
class SaleOrder(models.Model):
_inherit = 'sale.order'
partner_country_id = fields.Many2one(
related='partner_id.country_id',
string='Kundenland',
store=True
)
Über die XML-RPC-API (Remote-Konfiguration)
Felder können auch programmgesteuert über Odoos XML-RPC-API und das ir.model.fields-Modell hinzugefügt werden. Dies ist der Ansatz, der in Dasolos Remote-Config-Notebooks verwendet wird. Es entspricht dem, was Studio tut, und ermöglicht die Erstellung von Feldern ohne direkten Serverzugriff.
Um ein verwandtes Feld über die API hinzuzufügen, erstellen Sie einen ir.model.fields-Datensatz mit ttype='many2one' (oder dem entsprechenden Typ) und setzen den related-Parameter, um den relationalen Pfad zu definieren. Dieser Ansatz eignet sich gut für die Bereitstellung benutzerdefinierter Felder im Rahmen eines automatisierten Einrichtungsprozesses.
Best Practices
Wählen Sie den richtigen Vererbungstyp für die Aufgabe
Verwenden Sie die klassische Vererbung, wenn Sie einfach Felder oder Methoden zu einem bestehenden Modell hinzufügen möchten. Es ist der einfachste Ansatz und wird von der überwiegenden Mehrheit der Odoo-Module verwendet. Reservieren Sie die Delegationsvererbung für Fälle, in denen Sie tatsächlich zwei separate Datensatzmengen benötigen, die miteinander verknüpft sind, wie wenn ein Geschäftskonzept einen Kontakt erweitert, ohne selbst ein Kontakt zu sein.
Bevorzugen Sie verwandte Felder für den Lesezugriff
Wenn Sie nur einen Wert aus einem verknüpften Datensatz in einem Formular oder einer Listenansicht anzeigen müssen, ist ein verwandtes Feld sauberer als die Delegationsvererbung. Es vermeidet die Erstellung einer neuen strukturellen Abhängigkeit und ist leicht zu verstehen und zu warten.
Seien Sie vorsichtig mit store=True bei verwandten Feldern
Das Speichern eines verwandten Feldes in der Datenbank beschleunigt Suchen und Filter, bedeutet jedoch, dass der Wert eine Kopie ist. Odoo löst eine Neuberechnung aus, wenn sich die Quelle ändert, aber in Grenzfällen kann dies aus dem Gleichgewicht geraten. Speichern Sie verwandte Felder nur, wenn Sie sie wirklich im großen Maßstab filtern oder sortieren müssen.
Benennen Sie benutzerdefinierte Felder immer mit x_ voran
Jedes Feld, das Sie über Vererbung zu einem Standard-Odoo-Modell hinzufügen, sollte mit x_ beginnen (oder einen Modul-Namespace in einem ordnungsgemäßen Modul verwenden). Dies verhindert Konflikte mit Feldern, die von Odoo in zukünftigen Versionen hinzugefügt werden.
Dokumentieren Sie Ihre Vererbungskette
Wenn Sie an komplexen Anpassungen arbeiten, schreiben Sie einen kurzen Kommentar oder Entwurfsnotiz, die erklärt, woher die Felder stammen und warum. Ein Feld namens x_country_code auf einem Verkaufsauftrag könnte ohne Dokumentation nicht offensichtlich auf partner_id.country_id.code verweisen.
Behandeln Sie Kaskadenlöschungen korrekt
Bei der Delegationsvererbung wird der Elterndatensatz automatisch erstellt, wenn das Kind erstellt wird. Wenn das Kind gelöscht wird, sollte normalerweise auch der Elternteil gelöscht werden. Setzen Sie ondelete='cascade' auf das Many2one in _inherits, um eine saubere Löschung ohne verwaiste Datensätze sicherzustellen.
Häufige Fallstricke
Verwirrung der drei Vererbungstypen
Der häufigste Fehler für Entwickler, die neu bei Odoo sind, ist die Verwendung von _inherit mit _name, wenn sie eine klassische Erweiterung beabsichtigten. Dies erstellt versehentlich ein brandneues Modell anstelle der Erweiterung des bestehenden. Überprüfen Sie Ihre Modelldefinition: Wenn Sie nicht beabsichtigen, ein neues Modell zu erstellen, lassen Sie _name weg.
Vergessen, den Eltern-Datensatz in _inherits zu erstellen
Bei der Delegationsvererbung erstellt der Eltern-Datensatz nicht automatisch in allen Szenarien. Wenn Sie einen Kinddatensatz programmgesteuert über die API oder in einem Skript erstellen, müssen Sie entweder Odoos ORM die Erstellung des Elternteils überlassen (was es tut, wenn Sie create normalerweise verwenden) oder den Eltern-Datensatz zuerst erstellen und seine ID übergeben. Das Überspringen dieses Schrittes führt zu einem Datenbankbeschränkungsfehler.
Versuchen, den Typ eines Feldes durch Vererbung zu ändern
Odoo erlaubt nicht, den Typ eines bestehenden Feldes über Vererbung zu überschreiben. Sie können Attribute wie das String-Label, die Domain oder den Hilfetext ändern, aber Sie können ein Char-Feld nicht in ein Integer-Feld ändern. Der Versuch, dies zu tun, führt zu einem Fehler bei der Modulinstallation.
Übermäßige Nutzung gespeicherter verwandter Felder
Es ist verlockend, store=True zu jedem verwandten Feld hinzuzufügen, aus Leistungsgründen, aber es erhöht die Datenbankgröße und führt zu Wartungsaufwand. Wenn sich das Quellfeld häufig ändert, lösen gespeicherte verwandte Felder eine Menge Neuberechnungen aus. Verwenden Sie gespeicherte verwandte Felder selektiv, nur wenn Sie einen konkreten Bedarf haben, um in großen Datensätzen nach ihnen zu filtern oder zu gruppieren.
Annahme, dass vererbte Felder die Zugriffsregeln des Kindmodells respektieren
Felder, die durch Delegation vererbt werden, leben im Elternmodell. Zugriffsrechte, die im Kindmodell definiert sind, gelten nicht automatisch für diese Felder auf Datenbankebene. Wenn Sie den Zugriff auf das Kindmodell einschränken, aber nicht auf das Elternmodell, können Benutzer möglicherweise dennoch die Werte der vererbten Felder direkt über das Elternmodell lesen. Überprüfen Sie immer die Sicherheitsregeln für beide Modelle, wenn Sie Delegationsvererbung verwenden.
Fazit
Vererbte Felder sind kein Nischenmerkmal der Odoo-Entwicklung. Sie sind in die Architektur des Systems integriert. Die Beziehung zwischen Benutzern und Partnern, zwischen Produktvarianten und Vorlagen, zwischen Verkaufsaufträgen und Kundenkontaktinformationen: All dies beruht auf der Feldvererbung, um Daten konsistent zu halten und Duplikate zu vermeiden.
Zu verstehen, welchen Vererbungstyp man verwenden sollte, wann man stattdessen ein verwandtes Feld verwenden sollte und wie sich diese Mechanismen in der Datenbank verhalten, wird Sie zu einem deutlich effektiveren Odoo-Anpasser machen. Sie werden saubereren Code schreiben, bessere Datenmodelle entwerfen und weniger Zeit mit dem Debuggen unerwarteten Feldverhaltens verbringen.
Die wichtigste Erkenntnis ist einfach: Odoos ORM ist so konzipiert, dass Felder an einem Ort leben und von vielen Orten aus zugegriffen wird. Dies ist das Prinzip hinter vererbten Feldern, und es sorgt dafür, dass Odoos Datenmodell kohärent bleibt, selbst wenn es über Dutzende von miteinander verbundenen Modulen wächst.
Brauchen Sie Hilfe bei Ihrer Odoo-Implementierung?
Bei Dasolo helfen wir Unternehmen, Odoo zu implementieren, anzupassen und zu optimieren. Egal, ob Sie ein benutzerdefiniertes Modul von Grund auf neu erstellen, Standardmodelle mit neuen Feldern erweitern oder versuchen zu verstehen, warum sich Ihr Datenmodell auf unerwartete Weise verhält, unser Team hat die praktische Odoo-Erfahrung, um Ihnen zu helfen, schneller voranzukommen und kostspielige Fehler zu vermeiden.
Wenn Sie Fragen zu Ihrem Odoo-Datenmodell, Ihrer Strategie für benutzerdefinierte Felder oder zur technischen Implementierung haben, sprechen wir gerne über Ihre Situation. Kontaktieren Sie uns und lassen Sie uns den richtigen Ansatz für Ihr Projekt finden.