Ich bin verwirrt in Bezug auf @ api.one, @ api.multi und @ api.model.Was ist anders s/w @ api.one, @ api.multi und @ api.model?
In welchem Fall verwenden wir diese auf andere Weise?
Ich bin verwirrt in Bezug auf @ api.one, @ api.multi und @ api.model.Was ist anders s/w @ api.one, @ api.multi und @ api.model?
In welchem Fall verwenden wir diese auf andere Weise?
api.one
verwendet werden soll, wenn Methode nur auf einen Datensatz aufgerufen wird. Es stellt sicher, dass beim Aufruf der Methode mit api.one
Dekorator keine Mehrfachsätze vorhanden sind. Sagen wir, du hast einen Eintrag partner = res.partner(1,)
. Es ist nur ein Datensatz, und es gibt Verfahren zum Beispiel (in res.partner
):
@api.one
def get_name(self):
return self.name #self here means one record
es so Aufruf funktioniert:
partner.get_name()
Aber wenn es mehr Datensätze sein, wie partners = res.partner(1, 2,)
Aufruf, würde Warnung auslösen, Ihnen sagen, dass Sie es nur auf einem Datensatz aufrufen können. Für mehrere Datensätze wird api.multi
verwendet, wobei Recordset ist, und es kann durch alle Datensätze iteriert werden, um etwas zu tun. Zum Beispiel:
@api.multi
def get_partner_names(self):
names = []
for rec in self:
names.append(rec.name)
return ', '.join(names)
Und api.model
gilt als verwendet werden, wenn Sie etwas mit dem Modell tun, müssen selbst und brauchen nicht zu ändern/Sehen Sie sich einigen Rekord genauen Modells/Aufzeichnungen. Zum Beispiel könnte es eine Methode geben, die einige Metainformationen über die Struktur des Modells oder einige Hilfsmethoden usw. zurückgibt. Auch in der Dokumentation wird gesagt, dass diese API bei der Migration von alten APIs gut ist, weil sie "höflich" Code in neue API umwandelt . Auch in meiner eigenen Erfahrung, wenn Sie eine Methode brauchen, um etwas zurückzugeben, ist model
Dekorateur gut dafür. api.one
gibt leere Liste zurück, sodass es zu unerwartetem Verhalten führen kann, wenn api.one
für Methode verwendet wird, wenn es etwas zurückgeben soll.
Einige weitere Informationen: http://odoo-new-api-guide-line.readthedocs.org/en/latest/decorator.html
api.one
Dieser Dekorateur Loops automatisch auf Aufzeichnungen von RecordSet für Sie. Selbst als aktuelle Datensatz neu definiert:
@api.one ## here you will get singleton object in self
def name(self):
self.name = ’admin’
@ api.multi
Selbst wird die aktuelle RecordSet ohne Iteration sein. Es ist das Standardverhalten:
@api.multi ## here you will get multi objects in self
def name(self):
print len(self)
for obj in self:
obj.name = 'Admin'
@ api.model
Dieser Dekorateur wird alte API-Aufrufe dekoriert Funktion, um neue API Signatur konvertieren. Es ermöglicht, beim Migrieren von Code höflich zu sein.
@api.model
def name(self):
pass
Methode benötigt Dekorateure nach Ihren Methoden definiert werden müssen, wenn Sie Wörterbuch aus dem Verfahren dann Ihre Methode muss @api.multi
enthält zurückkehren möchten.
Siehe New API Guideline
Sie tatsächlich können Anruf ein @api.one
Methode mit einem RecordSet mehrere Datensätze enthält. Der einzige Unterschied besteht darin, dass bei @api.one
die Schleifenaufzeichnungen außerhalb der von Ihnen definierten Funktion ausgeführt werden und der Dekorator self
jeden Datensatz im Datensatzsatz nacheinander übergibt.
Als Beispiel wollen wir zwei Funktionen in unserem Modell example.model
definieren:
@api.one
print_self_one(self):
print self
@api.multi
print_self_multi(self):
print self
Und die ihnen die folgende Art und Weise sowohl von odoo shell nennen lassen:
model = env['example.model']
record_set = model.browse(1,2)
print "record set: " + record_set
print "using @api.one:"
record_set.print_self_one()
print "using @api.multi:"
record_set.print_self_multi()
zurückkehren würde:
record set: example.model(1,2)
using @api.one:
example.model(1)
example.model(2)
using @api.multi:
example.model(1,2)
Somit sind die folgenden zwei gleichwertig:
@api.one
_compute_name(self):
self.name = "Default Name"
@api.multi
print_self_multi(self):
for record in self:
record.name = "Default Name"
auch wenn sie mit mehr Datensatz im Recordset aufgerufen werden.
Auf der anderen Seite, verwenden Sie nicht alle Dekorateur, dann kann es nicht mit mehr (oder weniger) als ein Datensatz aufgerufen werden, oder es wird sich beschweren und wahrscheinlich mit einem Fehler zu stoppen.
@api.model
ist eine ganz andere Geschichte: Sie sollten diesen Dekorator nur verwenden, wenn Sie nur erwarten, dass er mit einem leeren Recordset aufgerufen wird.
verwenden Wenn Sie einen nicht leeren RecordSet als Eingabewert erwarten, dann in vielen Fällen, Sie beide @api.one
und @api.multi
verwenden können, ist es nur eine Frage der persönliche Präferenz. Ich persönlich bevorzuge es, @api.one
zu verwenden, wenn es möglich ist, weil ich finde, dass der Code auf diese Weise viel sauberer ist (auch für Compute- und Onchange-Methoden verwendet die Odoo-Quelle im Allgemeinen @api.one
).
Es gibt einige Fälle, in denen Sie nur @api.multi
obwohl verwenden können:
Wenn Sie nicht nur auf die Datensätze Schleife wollen, aber Sie wollen auch nur einmal etwas tun:
@api.multi
print_self_multi(self):
print "this will only be printed once"
for record in self:
print "this will be printed len(record_set) times"
Wenn der Rückgabewert wichtig ist. Eine mit @api.one
dekorierte Funktion wird immer eine Liste (eine Liste der Rückgabewerte in Ihrer Funktion als Iterationen) zurückgeben. In einigen Fällen, insbesondere bei der Interaktion mit der GUI, müssen Sie jedoch ein Wörterbuch zurückgeben (z. B. mit einer Warnung). In diesen Fällen müssen Sie mit @api.multi
gehen.
@ api.multi
Verzieren einen Rekord-style-Methode, wo self
ein Cord-Set ist. Die Methode definiert typischerweise eine Operation für Datensätze. Ein solches Verfahren ::
@api.multi
def method(self, args):
...
kann sowohl Aufzeichnung und traditionellen Stile genannt werden, wie ::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, ids, args, context=context)
@ api.model
eine Rekord-Stil Methode Verzieren wo self
ist ein Recordset, aber sein Inhalt ist nicht relevant, nur das Modell ist. Ein solches Verfahren ::
@api.model
def method(self, args):
...
können sowohl Aufzeichnung und traditionelle Stile genannt werden, wie ::
recs = model.browse(cr, uid, ids, context)
recs.method(args)
model.method(cr, uid, args, context=context)
Sie den Basiscode für diese Dekorateure in der Datei finden: odoo/api .py
Nein, das ist völlig falsch ... Sie können eine api.one-Methode auf einem Recordset aufrufen, das mehrere Datensätze enthält, es wird nur eine Schleife auf dem Recordset durchlaufen und das self für jeden Reacord neu definieren. Siehe die anderen Antworten ... –
Außerdem gibt es keine leere Liste zurück, es gibt eine Liste mit dem Rückgabewert jedes Vorgangs zurück (was bei gui-Anrufen möglicherweise nicht funktioniert, wenn ein Diktat erwartet wird). –
Sie haben Recht mit api.one . Ich habe mich geirrt. Zu dieser Zeit dachte ich, es würde so funktionieren, aber das war es nicht. Was ich über api.one beschrieben habe, gibt es tatsächlich eine Methode self.ensure_one, die nur einen einzigen Datensatz erlaubt. Es wird normalerweise am Anfang des Methodenkörpers aufgerufen. – Andrius