code: def calculate_hash(obj):
      
  
      hashable_fields = {
          'Chamber': ['name', 'country', 'abbreviation'],
          'Constituency': ['name'],
          'Group': ['name', 'abbreviation', 'kind', 'chamber'],
          'Mandate': ['group', 'constituency', 'role', 'begin_date', 'end_date',
              'representative']
      }
  
      fingerprint = hashlib.sha1()
      for field_name in hashable_fields[obj.__class__.__name__]:
          field = obj._meta.get_field(field_name)
          if field.is_relation:
              related = getattr(obj, field_name)
              if related is None:
                  fingerprint.update(smart_str(related))
              else:
                  fingerprint.update(related.fingerprint)
          else:
              fingerprint.update(smart_str(getattr(obj, field_name)))
      obj.fingerprint = fingerprint.hexdigest()
      return obj.fingerprint
docs: Computes fingerprint for an object, this code is duplicated from
      representatives.models.HashableModel because we don't have access to model
      methods in a migration scenario.