2009-07-17 11 views
11

Mi piace molto la funzionalità di SQLAlchemy che consente di vedere se un oggetto è sporco: se è stato modificato da quando è stato recuperato dal database o dall'ultima volta che è stato salvato.Puoi scoprire se un'istanza di Django Model è "sporca"?

È possibile trovare queste informazioni dall'ORM Django?

Nota che questo non è lo stesso di Dirty fields in django, poiché non mi interessa quali erano i dati precedenti, sebbene la risposta di S.Lott possa fornire un modo per farlo, ma mi piacerebbe un modo che non colpisca il database.

Ho anche guardato il django.db.transaction.is_dirty(), ma questa non sembra essere la soluzione.

+0

la questione non è così diverso e le stesse risposte a http://stackoverflow.com/questions/110803/dirty-fields-in-django può funzionare per il vostro problema – dnozay

+0

questo è lo stesso tipo di risposta come http://stackoverflow.com/a/332225/1733117 – dnozay

risposta

4

Una soluzione che fa fare una query di database:

class DirtyMixin(object): 
    @property 
    def is_dirty(self): 
     db_obj = self.__class__.objects.get(self.pk) 
     for f in self._meta.local_fields: 
      if self.__getattribute__(f.name) != db_obj.__getattribute__(f.name): 
       return True 
     return False 

Si può quindi aggiungere questo come una classe antenato di un modello. Oppure, modifica i moduli in forma di scimmia. Classe di classe, se preferisci.

from django.db import models 
models.Model.__bases__ = (DirtyMixin,) + models.Model.__bases__ 
+0

Non genererà un'eccezione se il modello non è stato ancora salvato? Sembra che dovrebbe essere catturato e restituito 'True'. –

+0

Sì, probabilmente è una svista. –

+0

AttributeError: l'oggetto 'MyObject' non ha attributo 'get'. Non intendi qualcosa come auto .__ class __. Objects.get (pk = self.pk)? – Julian

2

altro modo, coinvolgendo override __setattr__, è a lungo discusso in this Django ticket.

+0

Questa è una buona risposta, ma sarebbe meglio se includesse il codice non solo un link. – poolie