Temporarily disable auto_now / auto_now_add

Solution 1:

I've recently faced this situation while testing my application. I needed to "force" an expired timestamp. In my case I did the trick by using a queryset update. Like this:

# my model
class FooBar(models.Model):
    title = models.CharField(max_length=255)
    updated_at = models.DateTimeField(auto_now=True, auto_now_add=True)



# my tests
foo = FooBar.objects.get(pk=1)

# force a timestamp
lastweek = datetime.datetime.now() - datetime.timedelta(days=7)
FooBar.objects.filter(pk=foo.pk).update(updated_at=lastweek)

# do the testing.

Solution 2:

You can't really disable auto_now/auto_now_add in another way than you already do. If you need the flexibility to change those values, auto_now/auto_now_add is not best choice. It is often more flexible to use default and/or override the save() method to do manipulation right before the object is saved.

Using default and an overridden save() method, one way to solve your problem would be to define your model like this:

class FooBar(models.Model):
    createtime = models.DateTimeField(default=datetime.datetime.now)
    lastupdatetime = models.DateTimeField()

    def save(self, *args, **kwargs):
        if not kwargs.pop('skip_lastupdatetime', False):
            self.lastupdatetime = datetime.datetime.now()

        super(FooBar, self).save(*args, **kwargs)

In your code, where you want to skip the automatic lastupdatetime change, just use

new_entry.save(skip_lastupdatetime=True)

If your object is saved in the admin interface or other places, save() will be called without the skip_lastupdatetime argument, and it will behave just as it did before with auto_now.