romgar/django-dirtyfields

KeyError in get_dirty_fields

Closed this issue · 9 comments

I am investigating a weird problem I can only replicate in certain environments (Sempahore... and production.. annoyingly) where I get a keyerror from dirtyfields.

  File "env/src/django-dirtyfields/src/dirtyfields/dirtyfields.py", line 37, in get_dirty_fields
KeyError 'updated_at'
36:        for key, value in new_state.iteritems():
37:            original_value = self._original_state[key]

Any ideas what might be the cause of this @smn? Could the state being incorrectly frozen when the object is initialized? The updated_at field is a regular datetime for all intents and purposes and is simply updated by a signal like so:

@receiver(pre_save)
def timestampable(sender, instance, *args, **kwargs):
    if hasattr(instance, 'created_at'):
        if instance._state.adding and not instance.created_at:
            instance.created_at = timezone.now().replace(microsecond=0)

    if hasattr(instance, 'updated_at'):
        if instance._state.adding or not hasattr(instance, 'is_dirty') or instance.is_dirty():
            instance.updated_at = timezone.now().replace(microsecond=0)

I am not sure what I am doing to confuse it.

I rolled back to 2106caf and the problem seems to have gone away – so I'm thinking it's an edge regression since then.

Sidenote: please please please semver

But difference between 0.1 and last one (0.3) is really minor...

Your model has a defined updated_at field ? Can you show your model ? You have the same versions of django/dirtyfield in local and production ?

smn commented

A failing test somewhere (Travis) would be great to help debug.

smn commented

Also thanks on the semver nudge. Time to get this code base into better shape.

This one is happening to me as well. I also offered a pull request that fixes this issue locally for me. Feel free to have a look and work over it accordingly.

@angelo-romano, I think that your issue is not related to the same problem (and will be resolved in next minor release by #24).

@stevelacey, can you give some additional informations (code example, precise context, test, ...) so that we can try to resolve it ?

Happy to test a build you think fixes the problem, but I've already spent trying to debug the cause and gotten deep enough to lose interest – IIRC any of the recent commits broke my CI – so give me a nudge with a commit you think has fixed and want me to try out.

I'm having the same issue. This is happening with DateTimeFields that have auto_now_add=True, as model_to_dict will exclude them for being editable=False.

The check_relationship release introduced this bug.
Steps to reproduce:

  1. Create a model with a non-editable field. Eg: a DateTimeField with auto_now_add=True.
  2. Call model_instance.get_dirty_fields()
  3. See that a KeyError exception is thrown.

Because dirty_fields is initialized using _full_dict() method (that uses model_to_dict) to set the original state of the model, this original state doesn't have the non-editable fields in it.
When calling get_dirty_fields(check_relationship=False) the the _as_dict() is iterated, which has non-editable fields in it, and thus a KeyError is thrown.