Skip to Content

Inherited Fields στο Odoo: Πώς το ORM Μοιράζει Δεδομένα Μεταξύ Models

Οδηγός για να κατανοήσετε πώς «κληρονομούνται» πεδία στο Odoo και πώς να το εφαρμόσετε στις δικές σας προσαρμογές
6 Μαρτίου 2026 από
Inherited Fields στο Odoo: Πώς το ORM Μοιράζει Δεδομένα Μεταξύ Models
Dasolo
| No comments yet

Εισαγωγή


Όταν αρχίζετε να δουλεύετε με ανάπτυξη για Odoo, το θέμα της κληρονομικότητας εμφανίζεται διαρκώς: το ORM του Odoo έχει σχεδιαστεί ώστε μοντέλα να μπορούν να επεκτείνουν και να ξαναχρησιμοποιούν πεδία άλλων μοντέλων χωρίς να πολλαπλασιάζουν τα δεδομένα ή τον κώδικα.


Τα κληρονομημένα πεδία είναι η καρδιά αυτού του μηχανισμού. Επιτρέπουν σε ένα μοντέλο να εμφανίζει και να χειρίζεται πεδία που φυσικά ανήκουν σε άλλο μοντέλο, σαν να ήταν δικά του. Μόλις κατανοήσετε αυτή τη λογική, η δομή δεδομένων του Odoo γίνεται πολύ πιο ξεκάθαρη.


Αυτό το άρθρο περιγράφει τι είναι τα κληρονομημένα πεδία, τους τρεις τρόπους κληρονομικότητας στο Odoo, πώς αποθηκεύονται στη βάση και πώς τα χρησιμοποιείτε σε πραγματικά έργα προσαρμογής.

Τι είναι ένα κληρονομημένο πεδίο στο Odoo;


Στο πλαίσιο του ORM του Odoo, ένα πεδίο θεωρείται κληρονομημένο όταν ένα μοντέλο αποκτά πρόσβαση σε πεδία που ορίζονται σε άλλο μοντέλο μέσω μίας από τις τρεις υποστηριζόμενες μορφές κληρονομικότητας. Αντί να ξαναδημιουργεί το ίδιο πεδίο, το παιδικό μοντέλο το ανακυκλώνει.


Αυτός ο μηχανισμός κρατά το μοντέλο δεδομένων συμπαγές και σταθερό. Το ίδιο όνομα πεδίου, για παράδειγμα το όνομα ενός επαφής, μπορεί να εμφανίζεται σε προσφορές, παραγγελίες και τιμολόγια επειδή όλοι διαβάζουν την ίδια πηγή.


Οι τρεις μορφές κληρονομικότητας στο Odoo

Το Odoo προσφέρει τρεις ξεχωριστές μεθόδους κληρονομικότητας και η κάθε μία διαχειρίζεται τα πεδία με διαφορετικό τρόπο.

1. Κλασική κληρονομικότητα

Σε αυτό το μοτίβο επεκτείνετε ένα υπάρχον μοντέλο με _inherit χωρίς νέο _name. Προσθέτετε πεδία ή μεθόδους απευθείας στο υπάρχον μοντέλο και δεν δημιουργείται νέα πίνακας στη βάση. Τα νέα πεδία αποθηκεύονται στον ίδιο πίνακα με τα βασικά πεδία.


Αυτή είναι η πιο διαδεδομένη περίπτωση προσαρμογής: ένα module προσθέτει πεδία στο res.partner ή στο sale.order απευθείας, και αυτά αποθηκεύονται μαζί με τα υπάρχοντα πεδία.


2. Πρότυπη (Prototype) κληρονομικότητα

Εδώ συνδυάζετε _inherit και _name, δημιουργώντας ένα νέο μοντέλο που ξεκινά ως αντίγραφο της δομής του γονικού αλλά έχει ξεχωριστό πίνακα βάσης. Τα πεδία του γονικού αντιγράφονται στο παιδί και αλλαγές στο παιδί δεν επηρεάζουν το γονικό.


Χρησιμοποιείται όταν χρειάζεστε ένα νέο ανεξάρτητο μοντέλο που μοιράζεται δομή με ένα υπάρχον, αλλά δεν είναι τόσο συνηθισμένο στις καθημερινές προσαρμογές.


3. Διάθεση/Εκχώρηση (Delegation) κληρονομικότητα

Αυτή ορίζεται με _inherits. Το παιδικό μοντέλο έχει ένα Many2one προς το γονικό και εκθέτει τα πεδία του γονικού ως δικά του. Τα δεδομένα παραμένουν στον πίνακα του γονικού και προσπελάζονται μέσω της σχέσης.

Στην πιο στενή έννοια, αυτό είναι το «κληρονομημένο πεδίο»: το πεδίο δεν πολλαπλασιάζεται, αλλά διαβάζεται και γράφεται στο γονικό αρχείο μέσω του συνδέσμου.


Ένα κλασικό παράδειγμα στο core είναι η σχέση μεταξύ res.users και res.partner: κάθε χρήστης είναι ταυτόχρονα επαφή και τα στοιχεία όπως όνομα ή email αποθηκεύονται στον πίνακα επαφών.

Πώς λειτουργεί το πεδίο


Τι συμβαίνει τεχνικά με τη διάθεση/εκχώρηση

Όταν ορίζετε _inherits, το ORM δημιουργεί μια «γέφυρα» μεταξύ των δύο πινάκων. Αν διαβάσετε ένα κληρονομημένο πεδίο από το παιδί, το ORM ακολουθεί την Many2one σχέση και επιστρέφει την τιμή από το γονικό.


Αν γράψετε σε αυτό το πεδίο από το παιδί, η εγγραφή γίνεται στον γονικό πίνακα. Στο επίπεδο προγραμματιστή το πεδίο συμπεριφέρεται σαν να είναι ενσωματωμένο, αλλά στη βάση δεδομένων τα δεδομένα βρίσκονται στο γονικό αρχείο.


Σημαντικό αποτέλεσμα αυτού είναι ότι δεν υπάρχει διπλή αποθήκευση. Μια αλλαγή στο όνομα της επαφής εμφανίζεται αμέσως σε όλα τα σημεία που αναφέρονται σε αυτήν.


Κλασική κληρονομικότητα και η βάση δεδομένων

Στην κλασική κληρονομικότητα, τα νέα πεδία προστίθενται απευθείας στον πίνακα του υπάρχοντος μοντέλου — δεν εμπλέκεται δεύτερος πίνακας. Αυτό είναι συνήθως ο πιο απλός και καθαρός τρόπος για προσθήκη πεδίων σε έργα προσαρμογής.


Σχετικά πεδία ως ελαφριά μορφή κληρονομικότητας

Ένα related πεδίο είναι ένας ειδικός υπολογιζόμενος τύπος που διαβάζει τιμή μέσα από μια αλυσίδα σχέσεων. Δεν είναι το ίδιο με την κληρονομικότητα μοντέλου, αλλά χρησιμοποιείται συχνά για να εμφανίσει δεδομένα άλλου μοντέλου χωρίς να αλλάξει η δομή.


Παράδειγμα: ένα partner_country_id στο sale.order μπορεί να δείχνει σε partner_id.country_id. Φαίνεται σαν εγγενές πεδίο στον παραγγελία αλλά η τιμή προέρχεται από την επαφή.

Τα related πεδία μπορούν να αποθηκευτούν στη βάση με store=True, που βελτιώνει αναζητήσεις και φίλτρα αλλά αυξάνει τον αποθηκευτικό χώρο και απαιτεί επανυπολογισμό όταν αλλάζει η πηγή.


Πώς επιλύονται τα πεδία κατά το runtime

Κατά τη φόρτωση ενός μοντέλου, το Odoo επιλύει τον πλήρη χάρτη πεδίων, συμπεριλαμβανομένων των κληρονομημένων. Πριν το μοντέλο χρησιμοποιηθεί, κάθε πεδίο έχει ήδη συνδεθεί με την πηγή του — είτε είναι ο ίδιος πίνακας, είτε ένας γονικός μέσω delegation, είτε μια αλυσίδα related. Αυτή η επιθυμητή αντιστοίχιση γίνεται μια φορά κατά το startup και cache-άρεται για απόδοση.

Πρακτικά επιχειρησιακά σενάρια


Τα κληρονομημένα πεδία δεν είναι απλώς τεχνική λεπτομέρεια· λύνουν πραγματικά επιχειρησιακά προβλήματα διατηρώντας τη συνοχή των δεδομένων χωρίς αντιγραφές.


1. CRM και Πωλήσεις: Στοιχεία Επαφής

Όταν ένας υπάλληλος πωλήσεων δημιουργεί ένα lead, το όνομα, το τηλέφωνο και το email προέρχονται από το αρχείο επαφής μέσω ενός Many2one. Αν η επαφή αλλάξει, κάθε lead, προσφορά ή παραγγελία που αναφέρεται σε αυτήν ενημερώνεται αυτόματα.


Αυτό το αποτέλεσμα προκύπτει από τη συνδυασμένη χρήση κλασικής κληρονομικότητας και related fields: τα CRM πεδία επεκτείνουν το res.partner, ενώ οι παραγγελίες αντλούν στοιχεία της επαφής μέσω related πεδίων.


2. Προϊόντα και Παραλλαγές

Τα προϊόντα του Odoo χρησιμοποιούν delegation για τις παραλλαγές: το product.product συνδέεται με product.template μέσω _inherits. Κοινά πεδία (όνομα, κατηγορία, περιγραφή, τιμή) μένουν στο template, ενώ χαρακτηριστικά ειδικά για κάθε παραλλαγή αποθηκεύονται στο variant.


Με αυτό τον τρόπο μπορείτε να έχετε δεκάδες χρωματικές παραλλαγές ενός προϊόντος χωρίς να πολλαπλασιάζετε όνομα και περιγραφή στη βάση.


3. Χρήστες και Επαφές

Το res.users κληρονομεί πεδία από res.partner μέσω delegation, οπότε στοιχεία όπως email, τηλέφωνο και διεύθυνση εμφανίζονται και στις δύο οντότητες ταυτόχρονα όταν ενημερώνονται.


4. Αποθήκη: Κινήσεις και Πληροφορίες Προϊόντων

Οι κινήσεις αποθέματος δείχνουν περιγραφές προϊόντων που προέρχονται από το template μέσω σχετικών πεδίων. Ο διαχειριστής αποθήκης βλέπει πάντα ενημερωμένα στοιχεία χωρίς διπλή αποθήκευση.


5. Λογιστική: Γραμμές Τιμολογίου

Οι γραμμές σε τιμολόγια αναφέρονται σε προϊόντα και επαφές, και τα ονόματα/λογαριασμοί/φορολογικές ρυθμίσεις προέρχονται από τα αντίστοιχα μοντέλα μέσω σχέσεων. Αυτό εξασφαλίζει συνέπεια ανάμεσα σε λογιστική και πωλήσεις.

Δημιουργία ή προσαρμογή κληρονομημένων πεδίων


Χρήση του Odoo Studio

Το Odoo Studio είναι το no-code εργαλείο για προσαρμογές μοντέλων και views. Όταν προσθέτετε πεδίο από το Studio, ουσιαστικά εφαρμόζετε κλασική κληρονομικότητα: το μοντέλο επεκτείνεται και το πεδίο προστίθεται στον πίνακα.


Το Studio επιτρέπει επίσης τη δημιουργία related fields. Επιλέγοντας "Related Field" δείχνετε έναν relational δρόμο από το τρέχον μοντέλο σε κάποιο πεδίο—π.χ. να εμφανίσετε τη χώρα ή τον ΑΦΜ του πελάτη στη φόρμα παραγγελίας.


Για functional users και συμβούλους, το Studio είναι συνήθως η σωστή επιλογή: αναλαμβάνει ονοματοδοσία πεδίων, μεταναστεύσεις βάσης και τοποθέτηση στα views.


Τεχνικές προσαρμογές με Python

Οι προγραμματιστές ορίζουν κληρονομημένα πεδία σε Python χρησιμοποιώντας την κλάση models.Model του Odoo ORM.


Παράδειγμα: κλασική κληρονομικότητα για να προσθέσετε πεδίο σε υπάρχον μοντέλο:

class CrmLead(models.Model):
    _inherit = 'crm.lead'

    x_contract_value = fields.Float(
        string='Προβλέψιμη Αξία Συμβολαίου'
    )

Παράδειγμα: delegation κληρονομικότητα για νέο μοντέλο που μοιράζεται πεδία:

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='Υπάλληλος'
    )

Παράδειγμα: related πεδίο για να εμφανίσετε τιμή από συνδεδεμένο αρχείο:

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    partner_country_id = fields.Many2one(
        related='partner_id.country_id',
        string='Χώρα Πελάτη',
        store=True
    )

Μέσω XML-RPC API (απομακρυσμένη διαμόρφωση)

Μπορείτε επίσης να δημιουργήσετε πεδία προγραμματιστικά μέσω του XML-RPC και του μοντέλου ir.model.fields. Αυτή η μέθοδος είναι αντίστοιχη με το τι κάνει το Studio και είναι χρήσιμη για αυτοματοποιημένες εγκαταστάσεις χωρίς άμεση πρόσβαση στο σύστημα.


Για να προσθέσετε related πεδίο μέσω API, δημιουργείτε μια εγγραφή στο ir.model.fields με το κατάλληλο ttype και ορίζετε το related μονοπάτι. Αυτό ταιριάζει όταν διανέμετε προσαρμογμένα πεδία ως μέρος εγκατάστασης.

Καλές πρακτικές


Επιλέξτε τον σωστό τύπο κληρονομικότητας

Χρησιμοποιήστε κλασική κληρονομικότητα για απλές επεκτάσεις ενός μοντέλου — είναι η πιο απλή και η πιο κατανοητή μέθοδος. Αποθηκεύστε delegation κληρονομικότητα για περιπτώσεις όπου πραγματικά χρειάζεστε δύο ξεχωριστές οντότητες που συνδέονται, π.χ. όταν ένα επιχειρηματικό concept επεκτείνει μια επαφή αλλά δεν είναι επαφή καθαυτή.


Προτιμήστε related fields για απλή ανάγνωση

Αν μόνο θέλετε να εμφανίσετε μια τιμή από συνδεδεμένο αρχείο σε ένα view, ένα related πεδίο είναι συχνά πιο απλό και πιο καθαρό από το delegation — αποφεύγει περιττές δομικές εξαρτήσεις.


Προσοχή με το store=True στα related πεδία

Η αποθήκευση βελτιώνει την απόδοση σε φίλτρα και ομαδοποιήσεις, αλλά σημαίνει ότι η τιμή είναι αντίγραφο. Ο επανυπολογισμός μπορεί σε σπάνιες περιπτώσεις να μη συγχρονιστεί σωστά — αποθηκεύστε μόνο όταν έχετε πραγματική ανάγκη.


Πάντα προθέστε x_ στα προσαρμοσμένα πεδία

Όποιο πεδίο προσθέτετε στο core μέσω προσαρμογής να ξεκινάει με x_ (ή να έχει ονοματεπώνυμο module) για να αποφύγετε συγκρούσεις με μελλοντικές εκδόσεις του Odoo.


Τεκμηριώστε την αλυσίδα κληρονομικότητας

Σε περίπλοκες προσαρμογές αφήστε σχόλια ή σύντομο σχεδιαστικό σημείωμα που εξηγεί από πού προέρχονται τα πεδία. Ένα πεδίο x_country_code σε μια παραγγελία δεν θα είναι προφανές χωρίς σύνδεση με partner_id.country_id.code.


Χειριστείτε σωστά τις διαγραφές με cascade

Στην delegation κληρονομικότητα, το γονικό αρχείο συνήθως πρέπει να διαγράφεται όταν διαγράφεται το παιδί. Ορίστε ondelete='cascade' στη Many2one του _inherits για να αποφύγετε ορφανά αρχεία.


Συνήθη σφάλματα


Μπερδέματα ανάμεσα στις τρεις μορφές κληρονομικότητας

Συχνό λάθος είναι να βάλετε _inherit μαζί με _name όταν θέλετε απλή επέκταση — αυτό δημιουργεί κατά λάθος νέο μοντέλο αντί να επεκτείνει το υπάρχον. Αν δεν θέλετε νέο μοντέλο, μην ορίζετε _name.


Ξεχασμός δημιουργίας του γονικού αρχείου στο _inherits

Στην delegation, το γονικό αρχείο δεν δημιουργείται πάντα αυτόματα σε όλα τα σενάρια. Αν δημιουργείτε εγγραφές προγραμματικά με API ή scripts, πρέπει είτε να αφήσετε το ORM να δημιουργήσει το γονικό (όταν καλείτε normal create) είτε να δημιουργήσετε πρώτα το γονικό και να περάσετε το ID—αλλιώς θα πάρετε σφάλμα περιορισμού στη βάση.


Προσπάθεια αλλαγής τύπου πεδίου μέσω κληρονομικότητας

Δεν επιτρέπεται να αλλάξετε τον τύπο ενός υπάρχοντος πεδίου μέσω κληρονομικότητας. Μπορείτε να τροποποιήσετε ετικέτες, domain ή help text, όχι όμως να μετατρέψετε Char σε Integer — αυτό θα προκαλέσει σφάλμα κατά την εγκατάσταση module.


Υπερβολική χρήση αποθηκευμένων related πεδίων

Το store=True για κάθε related πεδίο αυξάνει μέγεθος βάσης και φόρτο συντήρησης. Αν η πηγή αλλάζει συχνά, αυτά προκαλούν πολλά επανυπολογιστικά. Χρησιμοποιήστε τα συνετά, μόνο όταν χρειάζεται φιλτράρισμα ή ομαδοποίηση σε μεγάλα σετ.


Υπόθεση ότι τα κληρονομημένα πεδία ακολουθούν δικαιώματα του παιδιού

Τα πεδία μέσω delegation ζουν στον γονικό πίνακα. Τα δικαιώματα πρόσβασης του παιδιού δεν εφαρμόζονται αυτόματα στο επίπεδο της βάσης για το γονικό. Αν περιορίσετε πρόσβαση μόνο στο παιδί, χρήστες μπορεί παρόλα αυτά να διαβάσουν τις τιμές μέσω του γονικού. Ελέγξτε τους κανόνες ασφαλείας και στα δύο μοντέλα.

Συμπέρασμα


Τα κληρονομημένα πεδία δεν είναι περιφερειακή δυνατότητα — είναι ενσωματωμένα στην αρχιτεκτονική του Odoo και εξασφαλίζουν ότι οι σχέσεις μεταξύ χρηστών/επαφών, templates/variants και παραγγελιών/πελατών παραμένουν συνεπείς.


Κατανοώντας ποια μορφή κληρονομικότητας να χρησιμοποιήσετε, πότε ένα related πεδίο είναι προτιμότερο και πώς συμπεριφέρονται αυτά στη βάση θα κάνετε πιο γρήγορα και καθαρότερα προσαρμογές στο Odoo. Θα μειώσετε τον χρόνο debugging και θα σχεδιάσετε καλύτερα μοντέλα δεδομένων.


Το βασικό μάθημα είναι απλό: το ORM του Odoo θέλει τα πεδία να «ζουν» σε ένα σημείο και να προσπελάζονται από πολλά μέρη. Αυτός ο κανόνας πίσω από τα κληρονομημένα πεδία κρατά το μοντέλο συνεκτικό όσο το σύστημα αναπτύσσεται.

Χρειάζεστε βοήθεια με την υλοποίηση του Odoo;


Στη Dasolo βοηθάμε επιχειρήσεις να υλοποιήσουν, να προσαρμόσουν και να βελτιστοποιήσουν το Odoo. Είτε χτίζετε ένα custom module από την αρχή, είτε επεκτείνετε core μοντέλα με νέα πεδία, είτε προσπαθείτε να καταλάβετε περίεργη συμπεριφορά του data model, η ομάδα μας έχει πρακτική εμπειρία για να σας προχωρήσει γρηγορότερα και με λιγότερα λάθη.


Αν έχετε ερωτήσεις για το data model σας, τη στρατηγική custom fields ή την τεχνική υλοποίηση, θα χαρούμε να συζητήσουμε την περίπτωσή σας. Επικοινωνήστε μαζί μας και ας βρούμε την κατάλληλη προσέγγιση για το έργο σας.

Inherited Fields στο Odoo: Πώς το ORM Μοιράζει Δεδομένα Μεταξύ Models
Dasolo 6 Μαρτίου 2026
Share this post
Σύνδεση to leave a comment