Created
May 11, 2017 17:58
-
-
Save gepatino/c444a309014943d3b0292eeb30e87354 to your computer and use it in GitHub Desktop.
Field change aware Django Model
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
class StoredOriginalValuesModel(models.Model): | |
""" | |
Model that stores original data in a dictionary and provides the | |
field_has_changed(field_name) method to check if a field has been modified | |
after loading the data from the db. | |
Original values are stored in the _original dictionary only when creating | |
the object or calling refresh_from_db(), so the field_has_changed() method | |
works even after save(). | |
""" | |
class Meta: | |
abstract = True | |
def __init__(self, *args, **kwargs): | |
super(StoredOriginalValuesModel, self).__init__(*args, **kwargs) | |
self.store_original_values() | |
def refresh_from_db(self, *args, **kwargs): | |
super(StoredOriginalValuesModel, self).refresh_from_db(*args, **kwargs) | |
self.store_original_values() | |
def store_original_values(self): | |
""" | |
Store the current model data as original values. | |
""" | |
all_fields = self._meta.get_fields(include_parents=True) | |
# TODO: check how to store ForeingKeys and ManyToManys | |
fields = [x for x in all_fields if not x.is_relation] | |
self._original = {} | |
for field in fields: | |
self._original[field.name] = field.value_from_object(self) | |
def field_has_changed(self, field): | |
""" | |
Verifies if a field was changed since last refresh from db. | |
""" | |
if field not in self._original: | |
raise Exception('Field not found in stored original values: %s' % field) | |
return self._original[field] != getattr(self, field) | |
def changed_fields(self): | |
""" | |
Returns a list of all changed fields. | |
""" | |
changed_fields = [] | |
for field in self._original.keys(): | |
if self.field_has_changed(field): | |
changed_fields.append(field) | |
return changed_fields |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment