<s> from __future__ import unicode_literals <EOL> from django . core . exceptions import ObjectDoesNotExist <EOL> from django . db . models import Model , NOT_PROVIDED <EOL> from django . utils . encoding import smart_text <EOL> def track_field ( field ) : <EOL> """<STR_LIT>""" <EOL> from auditlog . models import LogEntry <EOL> if field . many_to_many : <EOL> return False <EOL> if getattr ( field , '<STR_LIT>' , None ) is not None and field . rel . to == LogEntry : <EOL> return False <EOL> return True <EOL> def get_fields_in_model ( instance ) : <EOL> """<STR_LIT>""" <EOL> assert isinstance ( instance , Model ) <EOL> use_api = hasattr ( instance . _meta , '<STR_LIT>' ) and callable ( instance . _meta . get_fields ) <EOL> if use_api : <EOL> return [ f for f in instance . _meta . get_fields ( ) if track_field ( f ) ] <EOL> return instance . _meta . fields <EOL> def model_instance_diff ( old , new ) : <EOL> """<STR_LIT>""" <EOL> from auditlog . registry import auditlog <EOL> if not ( old is None or isinstance ( old , Model ) ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> if not ( new is None or isinstance ( new , Model ) ) : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> diff = { } <EOL> if old is not None and new is not None : <EOL> fields = set ( old . _meta . fields + new . _meta . fields ) <EOL> model_fields = auditlog . get_model_fields ( new . _meta . model ) <EOL> elif old is not None : <EOL> fields = set ( get_fields_in_model ( old ) ) <EOL> model_fields = auditlog . get_model_fields ( old . _meta . model ) <EOL> elif new is not None : <EOL> fields = set ( get_fields_in_model ( new ) ) <EOL> model_fields = auditlog . get_model_fields ( new . _meta . model ) <EOL> else : <EOL> fields = set ( ) <EOL> model_fields = None <EOL> if model_fields and ( model_fields [ '<STR_LIT>' ] or model_fields [ '<STR_LIT>' ] ) and fields : <EOL> filtered_fields = [ ] <EOL> if model_fields [ '<STR_LIT>' ] : <EOL> filtered_fields = [ field for field in fields <EOL> if field . name in model_fields [ '<STR_LIT>' ] ] <EOL> else : <EOL> filtered_fields = fields <EOL> if model_fields [ '<STR_LIT>' ] : <EOL> filtered_fields = [ field for field in filtered_fields <EOL> if field . name not in model_fields [ '<STR_LIT>' ] ] <EOL> fields = filtered_fields <EOL> for field in fields : <EOL> try : <EOL> old_value = smart_text ( getattr ( old , field . name , None ) ) <EOL> except ObjectDoesNotExist : <EOL> old_value = field . default if field . default is not NOT_PROVIDED else None <EOL> try : <EOL> new_value = smart_text ( getattr ( new , field . name , None ) ) <EOL> except ObjectDoesNotExist : <EOL> new_value = None <EOL> if old_value != new_value : <EOL> diff [ field . name ] = ( smart_text ( old_value ) , smart_text ( new_value ) ) <EOL> if len ( diff ) == <NUM_LIT:0> : <EOL> diff = None <EOL> return diff </s>
