2009-07-17 9 views
11

J'aime vraiment la fonctionnalité de SQLAlchemy qui vous permet de voir si un objet est sale: s'il a été modifié depuis qu'il a été récupéré de la base de données, ou la dernière fois qu'il a été sauvegardé.Pouvez-vous savoir si une instance de modèle Django est "sale"?

Est-il possible de trouver cette information à partir de l'ORM de Django? Notez que ce n'est pas la même chose que Dirty fields in django, comme je me fous de ce que les données précédentes étaient, bien que la réponse de S.Lott puisse fournir un moyen de le faire, mais je voudrais un moyen qui ne frappe pas la base de données. J'ai également regardé le django.db.transaction.is_dirty(), mais cela ne semble pas être la solution.

+0

la question est pas si différent et les mêmes réponses à http://stackoverflow.com/questions/110803/dirty-fields-in-django peut travailler pour votre problème – dnozay

+0

c'est le même genre de réponse que http://stackoverflow.com/a/332225/1733117 – dnozay

Répondre

4

Une solution qui fait faire une requête de base de données:

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 

Vous pouvez ensuite ajouter cela comme une classe ancêtre à un modèle. Ou, monkey-patch les formes. Classe de modèle, si vous aimez.

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

Cela ne déclenchera-t-il pas une exception si le modèle n'a pas encore été sauvegardé? On dirait que cela devrait être attrapé et 'True' retourné. –

+0

Oui, c'est probablement un oubli. –

+0

AttributeError: l'objet 'MyObject' n'a pas d'attribut 'get'. Ne veux-tu pas dire quelque chose comme self .__ class __. Objects.get (pk = self.pk)? – Julian

2

Une autre façon, impliquant __setattr__ remplaçant, est discuté assez longuement dans this Django ticket.

+0

Ceci est une bonne réponse mais serait mieux si elle comprenait du code pas seulement un lien. – poolie