Returns dict of fields that changed since save (with old values)
543207
def changed(self):
        """"""
        return dict(
            (field, self.previous(field))
            for field in self.fields
            if self.has_changed(field)
        )
359358
def clear(self):
        
        self.__modified_data__ = {}
        self.__deleted_fields__ = [field for field in self.__original_data__.keys()]
71043
def changes_str(self):
        ''''''
        changes = ''
        for item in self._get_recursive_difference(type='intersect'):
            if item.diffs:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   # Next line should be tabulated even deeper,
                                   #  every change should be tabulated 1 deeper
                                   '\tidentified by {0} {1}:\n\t{2}\n'.format(
                                       self._key,
                                       item.past_dict[self._key],
                                       item.changes_str.replace('\n', '\n\t'))])
        for item in self._get_recursive_difference(type='removed'):
            if item.past_dict:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   '\tidentified by {0} {1}:'
                                   '\n\twill be removed\n'.format(self._key,
                                                                  item.past_dict[self._key])])
        for item in self._get_recursive_difference(type='added'):
            if item.current_dict:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   '\tidentified by {0} {1}:'
                                   '\n\twill be added\n'.format(self._key,
                                                                item.current_dict[self._key])])
        return changes
344388
def changed(self):
        '''
        
        '''
        def _changed(diffs, prefix):
            keys = []
            for key in diffs.keys():
                if not isinstance(diffs[key], dict):
                    continue

                if isinstance(diffs[key], dict) and 'old' not in diffs[key]:
                    keys.extend(_changed(diffs[key],
                                       prefix='{0}{1}.'.format(prefix, key)))
                    continue
                if self.ignore_unset_values:
                    if 'old' in diffs[key] and 'new' in diffs[key] and \
                            diffs[key]['old'] != self.NONE_VALUE and \
                            diffs[key]['new'] != self.NONE_VALUE:
                        if isinstance(diffs[key]['new'], dict):
                            keys.extend(
                                _changed(diffs[key]['new'],
                                         prefix='{0}{1}.'.format(prefix, key)))
                        else:
                            keys.append('{0}{1}'.format(prefix, key))
                    elif isinstance(diffs[key], dict):
                        keys.extend(
                            _changed(diffs[key],
                                     prefix='{0}{1}.'.format(prefix, key)))
                else:
                    if 'old' in diffs[key] and 'new' in diffs[key]:
                        if isinstance(diffs[key]['new'], dict):
                            keys.extend(
                                _changed(diffs[key]['new'],
                                         prefix='{0}{1}.'.format(prefix, key)))
                        else:
                            keys.append('{0}{1}'.format(prefix, key))
                    elif isinstance(diffs[key], dict):
                        keys.extend(
                            _changed(diffs[key],
                                     prefix='{0}{1}.'.format(prefix, key)))

            return keys

        return sorted(_changed(self._diffs, prefix=''))
1230126
def has_changed(self, field_name: str = None) -> bool:
        
        changed = self._diff_with_initial.keys()

        if self._meta.get_field(field_name).get_internal_type() == 'ForeignKey':
            if not field_name.endswith('_id'):
                field_name = field_name+'_id'

        if field_name in changed:
            return True

        return False
717114
def clear_modified_data(self):
        
        self.__modified_data__ = {}
        self.__deleted_fields__ = []

        for value in self.__original_data__.values():
            try:
                value.clear_modified_data()
            except AttributeError:
                pass
912951
def get_current_fields(self):
        """"""
        if hasattr(self, 'current_fields') and self.current_fields:
            return self.current_fields

        field_attribute = 'list_{}_{}_fields'.format(self.kwargs.get('app'), self.kwargs.get('model'))
        current_fields = self.request.user.attributes.get_attribute(field_attribute, [])
        request_fields = self.request.POST.get('selected_fields', None)

        if request_fields and ','.join(current_fields) != request_fields:
            # TODO validate fields
            current_fields = request_fields.split(',')
            self.request.user.attributes.set_attribute(field_attribute, current_fields)
        elif request_fields:
            current_fields = request_fields.split(',')

        if not current_fields:
            config = self.get_model_config()
            current_fields = config.list_default_fields if config.list_default_fields else ['created_at', 'id']

        self.current_fields = current_fields
        return current_fields
349436
protected function changedRevisionableFields()
    {
        $changes = [];
        foreach ($this->dirtyData as $key => $value) {
            // check that the field is revisionable, and the data is dirty enough
            if ($this->isRevisionable($key) && !is_array($value)) {
                if (is_object($original = array_get($this->originalData, $key)) || is_string($original)) {
                    $original = trim($original);
                }

                if (is_object($updated = array_get($this->updatedData, $key)) || is_string($updated)) {
                    $updated = trim($updated);
                }

                if ($original != $updated) {
                    $changes[$key] = $value;
                }
            } else {
                // if it's not dirty enough, then remove the field from the array
                unset($this->updatedData[$key]);
                unset($this->originalData[$key]);
            }
        }

        return $changes;
    }
1368169
def get_dict_diff_str(d1, d2, title):
    
    added, removed, changed = get_dict_diff(d1, d2)
    lines = [title]

    if added:
        lines.append("Added attributes: %s"
                     % ['.'.join(x) for x in added])
    if removed:
        lines.append("Removed attributes: %s"
                     % ['.'.join(x) for x in removed])
    if changed:
        lines.append("Changed attributes: %s"
                     % ['.'.join(x) for x in changed])

    return '\n'.join(lines)
147803
def export_deleted_fields(self):
        
        result = []
        if self.__modified_data__ is not None:
            return result

        for index, item in enumerate(self):
            try:
                deleted_fields = item.export_deleted_fields()
                result.extend(['{}.{}'.format(index, key) for key in deleted_fields])
            except AttributeError:
                pass
        return result
374596
def changed(self, *fields):
        
        S = super(Value, self).changed
        for fld in fields or (None,): # no args tests for any change
            if S(fld):
                return True
        return False
343826
def values(self):
        
        report = {}
        for k, k_changes in self._changes.items():
            if len(k_changes) == 1:
                report[k] = k_changes[0].new_value
            elif k_changes[0].old_value != k_changes[-1].new_value:
                report[k] = k_changes[-1].new_value
        return report
1145702
def previous(self, field):
        """"""

        # handle deferred fields that have not yet been loaded from the database
        if self.instance.pk and field in self.deferred_fields and field not in self.saved_data:

            # if the field has not been assigned locally, simply fetch and un-defer the value
            if field not in self.instance.__dict__:
                self.get_field_value(field)

            # if the field has been assigned locally, store the local value, fetch the database value,
            # store database value to saved_data, and restore the local value
            else:
                current_value = self.get_field_value(field)
                self.instance.refresh_from_db(fields=[field])
                self.saved_data[field] = deepcopy(self.get_field_value(field))
                setattr(self.instance, self.field_map[field], current_value)

        return self.saved_data.get(field)
532533
def get_columns_diff(changes):
    
    for change in changes:
        change.diff = []
        elt_changes = change.get_changes()
        if elt_changes:
            change.diff = elt_changes.columns

    return changes
869558
def _check_diff(changes):
    '''
    
    '''
    for conf_dict in changes:
        if conf_dict == 'Networks':
            continue
        for item in changes[conf_dict]:
            if changes[conf_dict][item]['new'] is None:
                old = changes[conf_dict][item]['old']
                if old == '':
                    return True
                else:
                    try:
                        if all(x == '' for x in old):
                            return True
                    except TypeError:
                        # Old value is not an iterable type
                        pass
    return False
214488
def changes
      changes = {'new' => {}, 'obsolete' => {}, 'updated' => {}}

      if @environment.nil?
        new_environments.each do |env|
          changes['new'][env] = {}
        end

        old_environments.each do |env|
          changes['obsolete'][env] = {}
        end
      else
        env = @environment
        changes['new'][env] = {} if new_environments.include?(@environment)
        changes['obsolete'][env] = {} if old_environments.include?(@environment)
      end
      changes
    end
1249727
def new_values(self):
        ''''''
        def get_new_values_and_key(item):
            values = item.new_values
            if item.past_dict:
                values.update({self._key: item.past_dict[self._key]})
            else:
                # This is a new item as it has no past_dict
                values.update({self._key: item.current_dict[self._key]})
            return values

        return [get_new_values_and_key(el)
                for el in self._get_recursive_difference('all')
                if el.diffs and el.current_dict]