Skip to content

AutoLastModifiedField default caching keeps the first time called value #520

Open
@nesaro

Description

@nesaro

Problem

AutoLastModifiedField caches the default value for new entries rather than calling now every time.

Environment

  • Django Model Utils version: >= 4.0.0
  • Django version: Tested on 2.2 and 3.0
  • Python version: 3.8

Code examples

class MyModel(models.Model):
    my_field = AutoLastModifiedField()

with freezegun.freezetime(time1):
    instance1 = MyModel()
with freezegun.freezetime(time2):
    instance2 = MyModel()

assert(instance1.my_field != instance2.my_field) # this will fail

Explanation

AutoLastModifiedField has a cache for the default value

    def get_default(self):
        """Return the default value for this field."""
        if not hasattr(self, "_default"):
            self._default = self._get_default()
        return self._default

This overrides the base django field get_default by always returning the value stored on the first call of save()

I noticed this while upgrading the version and running tests with various freezed time values. My temporary solution was to remove the cache.

del MyModel._meta.get_field('modified')._default

This bug was introduced in version 4.0.0 1878537

I do not understand the purpose of caching the value, but my suggestion is to remove the caching or to keep the django logic that caches the value if not callable.

    def get_default(self):
        """Return the default value for this field."""
        return self._get_default()

    @cached_property
    def _get_default(self):
         if callable(self.default):
             return self.default
          return lambda: self.default

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions