Wie aktualisiere ich andere Felder oder andere Modelle aus der Compute-Funktion?

8

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.

Das Feld

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.

    
William 14.09.2015, 04:54
quelle

1 Antwort

5

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:

  • Sie werden berechnet, wenn das Feld, von dem sie abhängen, geändert wird (das sind die guten Nachrichten)
  • Die Notwendigkeit, sie neu zu berechnen, wird jedes Mal ausgewertet, wenn Sie versuchen, auf ihren Wert zuzugreifen. Es ist also etwas Vorsicht geboten, um eine endlose Rekursion zu vermeiden.

Ü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 :

%Vor%

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.

    
Andrei Boyanov 17.09.2015, 10:47
quelle

Tags und Links