Created
September 23, 2011 04:48
-
-
Save readevalprint/1236761 to your computer and use it in GitHub Desktop.
Django instance Diff - Now it's the bestestest.
This file contains 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
#!/usr/bin/env python | |
# By Tim Watts | |
# From http://readevalprint.com/blog/more-better-django-changed-instance-diff.html | |
# Updated on 9/22/2011 - Added Many2Many to supported fields | |
# Updated on 9/23/2011 - Fixed Many2Many fields | |
class Missing: | |
pass | |
def diff(instance1, instance2=None, missing_field=None): | |
''' | |
Compares two instances and returns a dictionary of | |
the different fields and a tuple of the corrisponding values. | |
If a instance2 is not provided, the first instance is compared | |
against the current values in the database. | |
Set "missing_field" to differentiate between a field that doesn't | |
exist and a field that contains a None. | |
''' | |
if not instance2: | |
if not instance1.pk: | |
return {} # nothing to compare, dur. | |
instance2 = instance1.__class__._default_manager.filter(pk=instance1.pk).get() | |
d = {} | |
for name, field in set(instance1._meta._name_map.items() + instance2._meta._name_map.items()): | |
value1 = missing_field | |
value2 = missing_field | |
if field[0].__class__.__name__ == 'ManyToManyField': | |
try: | |
objects = getattr(instance1, name, missing_field) | |
if objects != missing_field: | |
value1 = list(objects.values()) | |
except Exception as e: | |
value1 = e | |
try: | |
objects = getattr(instance2, name, missing_field) | |
if objects != missing_field: | |
value2 = list(objects.values()) | |
except Exception as e: | |
value2 = e | |
elif field[0].__class__.__name__ not in ['OneToOneField', 'AutoField', 'RelatedField']: | |
try: | |
value1 = getattr(instance1, name, missing_field) | |
except Exception as e: | |
value1 = e | |
try: | |
value2 = getattr(instance2, name, missing_field) | |
except Exception as e: | |
value2 = e | |
if value1 != value2: | |
# do they break in the same way? | |
if isinstance(value1, Exception) and isinstance(value2, Exception): | |
if type(value1) != type(value2): | |
# different type of exceptions | |
d[name] = (value1, value2) | |
else: | |
# actually different values | |
d[name] = (value1, value2) | |
return d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment