2010-11-05 12 views
15

Wie kann ich ein Diktat übergeben, die Felder enthalten, um ein Django-Modell zu aktualisieren? Dies ist kein Objekt zu erstellen, sondern es zu aktualisieren.Update-Modell django durch Kwargs

Beispiel:

obj = Object.objects.create(index=id, **fields) 

Antwort

25

Solange der PK gleich ist, wird die bestehende Reihe überschrieben.

obj = Object(index=id, **fields) 
obj.save() 
+0

Sie meinen, dass es erstellen wird, wenn in der Datenbank kein Feld mit Index ist und aktualisieren, wenn es ein Feld mit diesem Index gibt? Also können wir es update_or_create nennen? – Pol

+0

Das ist richtig. –

+0

Oh Mann !!! Ich habe bereits meine Methode von create_or_update beendet ... Cose ich fand artikel, dass es keine Methode erstellen oder aktualisieren in Django .. Es gibt artikel: http://blog.roseman.org.uk/2010/03/9/easy- create-or-update/so sein falscher Artikel? – Pol

11
def update_object(obj, **kwargs): 
    for k, v in kwargs.items(): 
     setattr(obj, k, v) 
    obj.save() 
+1

sein Dies kann nicht das, was OP alle wollte, da die Felder in die DB geschrieben werden; nicht nur diejenigen in 'Kwargs', also möglicherweise übertriebene Dinge. 1.5 führt ein "update_fields" -Argument zu "model.save" ein, obwohl Sie dann die Feldnamen wiederholen müssten. – ded7

8

Sie können eine queryset eines Objekts, und dann dieses Update: obwohl

model = Model.objects.filter(pk=pk) 
model.update(**kwargs) 

Dies wird die .save() -Methode für das Objekt nicht nennen. Ich denke, es wird jedoch nur eine Datenbankabfrage machen.

Beachten Sie, dass, wenn Sie nicht auf ein Objekt gefiltert haben (dh die Abfrage hat mehrere Objekte erhalten: wie wenn Sie PK nicht abgefragt hätten), würde es alle aktualisieren. Wenn es auf keine gefiltert wird, wird nichts in die Datenbank geschrieben.

Nachdem ich das gesagt hatte, war mir Ignacios Lösung nicht bekannt. Das mag ich sehr.

+0

Wenn Sie es schaffen, mehrere Datensätze zu erhalten, während Sie auf dem PK filtern, dann haben Sie ... größere Probleme. Das Filtern auf None ist jedoch kein Problem, da eine 'UPDATE'-Abfrage ausgegeben werden kann, die keinem Datensatz entspricht. –

+0

Ja, ich meinte, wenn Sie PK nicht abgefragt haben, aber auf etwas anderem, das _supposed_ war, um einzigartig zu sein. –

3

Wenn Sie wissen, dass Sie es schaffen:

Book.objects.create(**fields) 

Sie eine vorhandene Instanz überprüfen müssen Angenommen, können Sie es mit get oder erstellen finden:

instance, created = Book.objects.get_or_create(slug=slug, defaults=fields) 
if not created: 
    for attr, value in fields.iteritems(): 
     setattr(instance, attr, value) 
    instance.save() 

Wie in anderen erwähnten Antwort, Sie können auch die Funktion update auf den Queryset-Manager verwenden, aber ich glaube, dass keine Signale gesendet werden (was für Sie keine Rolle spielt, wenn Sie sie nicht verwenden). Allerdings sollten Sie wahrscheinlich verwenden Sie es nicht ein einzelnes Objekt zu ändern:

Book.objects.filter(id=id).update(**fields) 
+0

+1, da 'defaults' und 'setattr 'verwendet werden, um sicherzustellen, dass der Inhalt von Feldern auf das Objekt angewendet wird, ohne dass zusätzliche Attribute verloren gehen, die möglicherweise bereits für eine vorhandene Instanz festgelegt wurden – rhunwicks

3

Diese Frage ist ein wenig alt, aber nur es bisher mit den jüngsten Entwicklungen Django zu bringen - seit 1.7 gab es eine update_or_create Methode auf Querysets, die ähnlich wie get_or_create funktioniert.

In diesem Fall könnte es wie verwendet werden:

obj, created = Object.objects.update_or_create(index=id, defaults=fields)