Chapter 12: Inheritance¶
Az Odoo egyik erőteljes aspektusa a modularitása. Egy modul egy üzleti igényre van szánva, de a modulok egymással is kölcsönhatásba léphetnek. Ez hasznos egy meglévő modul funkcionalitásának bővítésére. Például az ingatlanforgatókönyvünkben azt szeretnénk, hogy az értékesítő ingatlanjainak listája közvetlenül megjelenjen a szokásos felhasználói nézetben.
De mielőtt rátérnénk az Odoo modul öröklődésének részleteire, nézzük meg, hogyan módosíthatjuk a szabványos CRUD (Create, Retrieve, Update vagy Delete) metódusok viselkedését.
Python öröklődés¶
Megjegyzés
Cél: ennek a szakasznak a végén:
It should not be possible to delete a property which is not new or cancelled.
Amikor egy ajánlat létrejön, az ingatlan állapotának «Ajánlat érkezett» állapotra kell változnia.
Nem szabad lehetővé tenni egy olyan ajánlat létrehozását, amely alacsonyabb áron van, mint egy meglévő ajánlat.
Az ingatlan modulunkban soha nem kellett semmi specifikusat fejlesztenünk ahhoz, hogy végrehajthassuk a szokásos CRUD műveleteket. Az Odoo keretrendszer biztosítja a szükséges eszközöket ezek végrehajtásához. Valójában az ilyen műveletek már szerepelnek a modellünkben a klasszikus Python öröklésnek köszönhetően:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
...
A class TestModel osztályunk örökli a Model osztályt, amely biztosítja a create(), read(), write() és unlink() metódusokat.
Ezek a metódusok (és bármely más, a Model osztályon definiált metódus) kiterjeszthetők specifikus üzleti logika hozzáadására:
from odoo import fields, models
class TestModel(models.Model):
_name = "test_model"
_description = "Test Model"
...
@api.model
def create(self, vals):
# Do some business logic, modify vals...
...
# Then call super to execute the parent method
return super().create(vals)
A model() dekorátor szükséges a create() metódushoz, mert a rekordhalmaz self tartalma nem releváns a létrehozás kontextusában, de nem szükséges a többi CRUD metódushoz.
Fontos megjegyezni, hogy bár közvetlenül felülírhatjuk a unlink() metódust, szinte mindig érdemesebb egy új metódust írni a ondelete() dekorátorral. Az ezzel a dekorátorral jelölt metódusok a unlink() során kerülnek meghívásra, és elkerülik azokat a problémákat, amelyek a modell moduljának eltávolítása során jelentkezhetnek, amikor a unlink() közvetlenül felül van írva.
Python 3-ban a super() egyenértékű a super(TestModel, self) kifejezéssel. Az utóbbi szükséges lehet, amikor a szülő metódust egy módosított rekordhalmazzal kell meghívni.
Veszély
Nagyon fontos, hogy mindig hívjuk meg a
super()-t, hogy elkerüljük a folyamat megszakítását. Csak néhány nagyon specifikus eset van, amikor nem akarjuk meghívni.Győződjön meg róla, hogy mindig a szülő metódussal konzisztens adatokat ad vissza. Például, ha a szülő metódus egy
dict()-et ad vissza, akkor a felülírásnak is egydict()-et kell visszaadnia.
Exercise
Adjon hozzá üzleti logikát a CRUD metódusokhoz.
Prevent deletion of a property if its state is not «New» or «Cancelled»
Tipp: hozzon létre egy új metódust a ondelete() dekorátorral, és ne feledje, hogy a self több rekordot tartalmazó rekordhalmaz is lehet.
Ajánlat létrehozásakor állítsa az ingatlan állapotát «Ajánlat érkezett» értékre. Hibát kell jelezni, ha a felhasználó alacsonyabb összegű ajánlatot próbál létrehozni, mint egy meglévő ajánlat.
Tipp: a property_id mező elérhető a vals-ban, de ez egy int. Egy estate.property objektum példányosításához használja a self.env[model_name].browse(value) (példa)
Modell öröklés¶
Referencia: a témával kapcsolatos dokumentáció megtalálható a Öröklés és kiterjesztés.
Az ingatlan modulunkban szeretnénk megjeleníteni az értékesítőhöz kapcsolódó ingatlanok listáját közvetlenül a Beállítások / Felhasználók és Cégek / Felhasználók űrlap nézetben. Ehhez hozzá kell adnunk egy mezőt a res.users modellhez, és módosítanunk kell a nézetét, hogy megjelenítse azt.
Az Odoo két öröklési mechanizmust biztosít, hogy moduláris módon bővítsen egy meglévő modellt.
Az első öröklési mechanizmus lehetővé teszi a modulok számára, hogy módosítsák egy másik modulban definiált modell viselkedését az alábbi módokon:
mezők hozzáadása a modellhez,
mezők definíciójának felülírása a modellben,
korlátozások hozzáadása a modellhez,
módszerek hozzáadása a modellhez,
létező módszerek felülírása a modellben.
A második öröklési mechanizmus (delegálás) lehetővé teszi, hogy egy modell minden rekordja kapcsolódjon egy szülő modell rekordjához, és átlátható hozzáférést biztosítson a szülő rekord mezőihez.
Az Odoo-ban az első mechanizmus messze a leggyakrabban használt. Esetünkben egy mezőt szeretnénk hozzáadni egy meglévő modellhez, ami azt jelenti, hogy az első mechanizmust fogjuk használni. Például:
from odoo import fields, models
class InheritedModel(models.Model):
_inherit = "inherited.model"
new_field = fields.Char(string="New Field")
Egy gyakorlati példa, ahol két mezőt adnak hozzá egy modellhez, itt található.
Konvenció szerint minden örökölt modellt a saját Python fájljában definiálnak. Példánkban ez a models/inherited_model.py lenne.
Exercise
Adjon hozzá egy mezőt a Felhasználókhoz.
Adja hozzá a következő mezőt a
res.users-hez:
Mező |
Típus |
|---|---|
property_ids |
One2many mező inverze, amely az értékesítőt hivatkozza az |
Adjon hozzá egy domaint a mezőhöz, hogy csak az elérhető ingatlanokat listázza.
A következő részben adjuk hozzá a mezőt a nézethez, és ellenőrizzük, hogy minden jól működik-e!
Nézet öröklés¶
Referencia: a témával kapcsolatos dokumentáció megtalálható a Öröklés hivatkozás alatt.
Megjegyzés
Cél: ennek a résznek a végére az értékesítőhöz kapcsolódó elérhető ingatlanok listájának meg kell jelennie a felhasználói űrlap nézetükben
A meglévő nézetek helyben történő módosítása helyett (felülírással), az Odoo nézet öröklést biztosít, ahol a gyermek «kiterjesztés» nézetek a gyökér nézetek tetejére kerülnek alkalmazásra. Ezek a kiterjesztések tartalmat adhatnak hozzá vagy távolíthatnak el a szülő nézetükből.
Egy kiterjesztés nézet a szülőjére az inherit_id mező használatával hivatkozik. Egyetlen nézet helyett az arch mezője számos xpath elemet tartalmaz, amelyek kiválasztják és módosítják a szülő nézetük tartalmát:
<record id="inherited_model_view_form" model="ir.ui.view">
<field name="name">inherited.model.form.inherit.test</field>
<field name="model">inherited.model</field>
<field name="inherit_id" ref="inherited.inherited_model_view_form"/>
<field name="arch" type="xml">
<!-- find field description and add the field
new_field after it -->
<xpath expr="//field[@name='description']" position="after">
<field name="new_field"/>
</xpath>
</field>
</record>
exprEgy XPath kifejezés, amely egyetlen elemet választ ki a szülő nézetben. Hibát jelez, ha nem talál elemet vagy egynél több elemet talál
positionMűvelet, amelyet az egyező elemre kell alkalmazni:
insidehozzáfűzi az
xpathtörzsét a megfelelő elem végéhezreplaceaz egyező elemet az
xpathtörzsével helyettesíti, az új törzs bármely$0csomópont előfordulását az eredeti elemmel helyettesítvebeforeaz
xpathtörzsét testvérként beszúrja az egyező elem eléafteraz
xpathstörzsét testvérként beszúrja az egyező elem utánattributesmódosítja a megfelelő elem attribútumait az
xpathtörzsében található speciálisattributeelemek segítségével
Egyetlen elem egyezésekor a position attribútum közvetlenül a megtalálandó elemre állítható. Az alábbi két öröklés ugyanazt az eredményt adja.
<xpath expr="//field[@name='description']" position="after">
<field name="idea_ids" />
</xpath>
<field name="description" position="after">
<field name="idea_ids" />
</field>
A nézet öröklésének kiterjesztésére egy példa található itt.
Exercise
Adjon hozzá mezőket a Felhasználók nézethez.
Adja hozzá a property_ids mezőt a base.view_users_form-hoz egy új jegyzetfüzet oldalon.
Tipp: a felhasználók nézetének öröklésére egy példa található itt.
Az öröklés széles körben használt az Odoo-ban a moduláris koncepció miatt. Ne habozzon elolvasni a megfelelő dokumentációt további információkért!
In the next chapter, we will learn how to interact with other modules.