Es gibt 3 Klassen, sync.test.subject.a
, die viele2 viele Beziehungen mit sync.test.subject.b
haben, die von sync.test.subject.c
geerbt werden.
sync.test.subject.b
s separated_chars
wird durch eine Berechnungsfunktion namens _compute_separated_chars
gefüllt, die durch die Änderung des Feldes sync.test.subject.b
von chars
ausgelöst wird.
Die Rolle von sync.test.subject.c
besteht im Wesentlichen darin, chars
durch seine eigene name
zu setzen, so dass _compute_separated_chars
ausgelöst wird.
Das Problem ist, dass ich übrig gebliebene Datensätze, die zu einem Many2many-Feld gehören (nämlich sync.test.subject.a
übrig gebliebene Datensätze), nicht aus der Compute-Funktion löschen kann, da das Feld vor der Ausführung der Funktion bereits vom System geleert wird Erhalte die IDs nicht. Ich kann nicht einmal temporäres Feld verwenden, um sync.test.subject.a
ids zu speichern, da alle Änderungen, die nicht mit separated_chars
zusammenhängen, vom System nicht innerhalb der Compute-Funktion ausgeführt werden (Mit irgendwelchen Änderungen meine ich wirklich ALLE Änderungen an andere Felder aus demselben Modell oder andere Änderungen an anderen Modellen werden nicht übernommen). Wie löse ich das?
Modelle:
%Vor%Ansichten:
%Vor%Ich denke, dass dieses Verhalten durch eine faule Implementierung von Odoo verursacht wird, um kettenberechnete Feldtrigger zu behandeln, anstatt die Trigger korrekt zu behandeln (sequentiell basierend auf den Abhängigkeiten), sie aktualisieren JEDER berechneten Felder EVERYTIME, wenn Änderungen an JEDEM ANDEREN FELD vorgenommen werden. Aus diesem Grund beschränken sie jede Aktualisierung auf ein anderes Feld innerhalb der Compute-Funktion. Denn wenn sie es nicht tun, wird es mit rekursiven Compute-Funktion aufrufen.
Da die Frage interessant ist und sich mit dem Verhalten der neuen Odoo API beschäftigt, habe ich mir die Zeit genommen ein wenig mit den compute
Methoden zu spielen. Was Sie in Ihrer Frage sagen, ist nicht völlig falsch, obwohl es mehrere vorzeitige Aussagen gibt.
Um das Verhalten von Odoo zu demonstrieren, habe ich die einfache Bücher -Anwendung mit dem folgenden Design erstellt.
Es gibt zwei Modelle - "books.book" und "books.author". Jede von ihnen hat eine Many2many
Beziehung mit der anderen - das ist Mode als normal, da jedes Buch von einem oder mehreren Autoren geschrieben werden kann und jeder Autor ein oder mehrere Bücher geschrieben haben soll.
Hier ist der Platz zu sagen, dass ein bisschen verrückt ist, um mit Many2many
verwandten Objekten von einer solchen compute
-Methode umzugehen, wie Sie wollen. Das liegt daran, dass die Many2many
Datensätze existieren und ihr ein Leben unabhängig voneinander haben. Mit One2many
relation ist es viel anders.
Aber irgendwie, um das Verhalten wiederzugeben, das Sie uns in Ihrem Beispiel zeigen, habe ich das author.books
-Feld berechnet gemacht - sein Wert wird von der _get_books()
-Methode berechnet, oh die author
-Klasse.
Nur um zu zeigen, dass verschiedene berechnete Felder gut und unabhängig funktionieren, habe ich ein weiteres berechnetes Feld erstellt - name
, welches berechnet wird als Methode _get_full_name()
der Klasse author
.
Nun ein paar Worte zur Methode _get_books()
. Basierend auf dem Feld books_list
Text generiert diese Methode ein Buch pro Zeile des books_list
.
Wenn Sie das Buch erstellen, prüfen Sie zunächst, ob bereits ein Buch mit diesem Namen existiert. Wenn dies der Fall ist, ist dieses Buch mit dem Autor verknüpft. Andernfalls wird ein neues Buch erstellt und mit dem Autor verknüpft.
Und nun die Frage, die Sie am meisten interessiert - vor der Erstellung der neuen Bücher werden die vorhandenen Bücher, die sich auf diesen Autor beziehen, gelöscht . Dazu verwendet die Methode SQL-Abfragen niedriger Ebene . Auf diese Weise behandeln wir das Problem, dass wir keine Liste verwandter Objekte in der Methode compute
haben.
Was Sie beachten müssen, wenn Sie mit berechneten Feldern arbeiten, die von einem anderen Feld abhängen, ist Folgendes:
Über das Ändern der Werte anderer Felder innerhalb der Berechnungsmethode. Lesen Sie den folgenden Teil der Dokumentation :
Hinweis
onchange-Methoden funktionieren bei der Zuweisung virtueller Datensätze für diese Datensätze wird nicht in die Datenbank geschrieben, sondern nur verwendet, um zu wissen, welcher Wert gesendet werden soll zurück zum Client
Das ist auch für die Methoden compute
gültig. Was das bedeutet? Wenn Sie einem anderen Feld des Modells einen Wert zuweisen, wird dieser Wert nicht in die Datenbank geschrieben. Der Wert wird jedoch beim Speichern des Formulars an die Benutzeroberfläche zurückgegeben und in die Datenbank geschrieben.
Bevor Sie meinen Beispielcode einfügen, empfehle ich Ihnen erneut, das Design Ihrer Anwendung zu ändern und sich nicht mit den many2many-Beziehungen aus der Compute-Methode zu befassen. Das Erstellen neuer Objekte funktioniert gut, aber das Löschen und Ändern bestehender Objekte ist schwierig und überhaupt nicht angenehm.
Hier ist die Datei books.py
:
Und die Benutzeroberfläche:
%Vor%
BEARBEITEN
Wenn Sie beispielsweise die Klasse author ableiten möchten, entfernen Sie die Attribute relation
, column1
und column2
aus der Felddefinition Many2many. er wird die Standardnamen der Relationstabelle verlassen.
Nun können Sie in jeder Unterklasse eine Methode wie folgt definieren:
%Vor%und verwenden Sie diese Methode in der SQL-Abfragekonstruktion, wenn Sie Datensätze aus dieser Beziehungstabelle löschen möchten.