Verfolgen der Änderungen seit dem letzten Speichern in Django-Modellen

9

Ein paar Mal bin ich auf eine Situation gestoßen, als ich zum Zeitpunkt der Speicherung wissen muss, welche Modellfelder aktualisiert werden und entsprechend handeln.

Die naheliegendste Lösung besteht darin, das Primärschlüsselfeld zu übernehmen und eine Kopie des Modells aus der Datenbank abzurufen:

%Vor%

Das funktioniert ganz gut, aber es trifft die Datenbank für jede Instanz des Modells, das Sie speichern (ist möglicherweise ziemlich unpraktisch, wenn Sie viele solcher Speicherungen durchführen).

Es ist offensichtlich, dass, wenn man sich die alten Feldwerte zu Beginn der Lebenszeit der Modellinstanz ( __init__ ) "merken" kann, es nicht notwendig sein sollte, eine Kopie des Modells aus der Datenbank zu erhalten. Also habe ich diesen kleinen Hack gefunden:

%Vor%

Dies scheint zu funktionieren, jedoch nutzt es die nicht öffentliche Schnittstelle von django.db.models.Model .

Vielleicht kennt jemand einen saubereren Weg, es zu tun?

    
shylent 08.01.2010, 18:37
quelle

2 Antworten

2

Ich denke, Ihre Lösung sieht vernünftig aus.

Alternativ können Sie auch eine Manager-Methode namens get_and_copy() (oder etwas) verwenden, die eine Kopie des ursprünglichen Objekts an die zurückgegebene Komponente anhängt. Sie könnten dann eine andere Manager-Methode verwenden, save_and_check() , die das kopierte Original nutzt.

FWIW: Wenn Sie mit Contrib / Admin Templates spielen, gibt es eine Kontextvariable namens original , die eine Kopie des ursprünglichen Objekts ist.

Update: Ich habe mir genauer angesehen, was der Admin macht. In class ModelAdmin (befindet sich in django / contrib / admin / options.py) gibt es eine Methode namens construct_change_message() . Es wird von formset.changed_data und formset.changed_objects gesteuert, also ist django / forms / models.py class BaseModelFormSet die Stelle, an der sich die Aktion befindet. Siehe die Methode save_existing_objects() . Schauen Sie sich auch die Methode _existing_object() an. Es ist ein wenig komplizierter als das, was ich zuvor erwähnt habe, da es sich um die Möglichkeit mehrerer Objekte handelt, aber im Grunde werden die Ergebnisse der beim ersten Zugriff eingestellten Abfrage zwischengespeichert.

    
Peter Rowell 08.01.2010 19:07
quelle
0

Dies wird nicht für Fixtures funktionieren. Der Befehl loaddata verwendet models.Model.base_save . Wahrscheinlich wäre die sauberste Methode, Deskriptoren für Felder zu verwenden, aber man muss herausfinden, wie man sie richtig einsetzt.

    
trybik 21.03.2011 15:42
quelle

Tags und Links