def save()

in src/olympia/amo/models.py [0:0]


    def save(self, *args, **kwargs):
        """
        Save changes to the model instance.

        If _signal=False is in `kw` the on_change() callbacks won't be called.
        """
        # When saving an existing instance, if the caller didn't specify
        # an explicit update_fields and _dynamic_update_fields is absent or
        # True, we attempt to find out which fields were changed and only
        # save those. This allows for slightly better performance as we don't
        # keep re-saving the same data over and over again, but also avoids
        # overwriting data that has changed in the meantime.
        # Fields with auto_now=True will be included all the time.
        #
        # Note that deferred fields will be included in the list of changed
        # fields if they are loaded afterwards, even if their value does not
        # change.
        if (
            self.pk
            # Just having self.pk is not enough, we only really want to catch
            # UPDATE calls and the caller could be doing Model(pk=1).save().
            # Django save() implementation uses the special _state attribute
            # for this.
            and self._state.adding is False
            and kwargs.get('update_fields') is None
            and kwargs.pop('_dynamic_update_fields', True)
        ):
            fields = [f.attname for f in self._meta.concrete_fields]
            concrete_initial_attrs = [
                (k, v) for k, v in self._initial_attrs.items() if k in fields
            ]
            current_attrs = [(k, self.__dict__[k]) for k, v in concrete_initial_attrs]
            changed_attrs = (
                set(current_attrs)
                - set(concrete_initial_attrs)
                # Never include primary key field - it might be set to None
                # initially in _initial_attrs right after a call to create()
                # even though self.pk is set.
                - {(self._meta.pk.name, self.pk)}
            )
            auto_now_fields = [
                f.name for f in self._meta.fields if getattr(f, 'auto_now', False)
            ]
            kwargs['update_fields'] = [k for k, v in changed_attrs] + auto_now_fields
        signal = kwargs.pop('_signal', True)
        result = super().save(*args, **kwargs)
        if signal and self.__class__ in _on_change_callbacks:
            self._send_changes(self._initial_attrs.copy(), dict(self.__dict__))
        # Reset initial_attr to be ready for the next save.
        updated_fields = kwargs.get('update_fields')
        self._reset_initial_attrs(
            attrs={k: self.__dict__[k] for k in updated_fields}
            if updated_fields
            else None
        )
        return result