2015-06-29 7 views

Antwort

4

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

+0

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 ... –

+0

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). –

+0

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

1

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

0
  • Unterschied zwischen einem, Multi und Modell

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.

  • Wenn die

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:

  1. 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" 
    
  2. 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.

0

@ 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

Verwandte Themen