Opened 4 years ago

Closed 4 years ago

#16583 closed Bug (wontfix)

Explicitly passing a date to a DateTimeField in a model's create method should override auto_now_add

Reported by: ian Owned by: nobody
Component: Database layer (models, ORM) Version: 1.3
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm writing some unit tests where I'm testing specific logic based on DateTimeFields in a model. When I use the .create() method on the model, I pass in a specific datetime to the DateTimeField but it gets ignored and overwritten by the auto_now_add functionality.

The only way I can do what I want is by first creating, then altering the value on the DateTimeField, then saving a second time to override.

Change History (5)

comment:1 Changed 4 years ago by aaugustin

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

Per the docs:

Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it's not just a default value that you can override.

You can think of auto_now_add (and auto_now) as database triggers.

In your situation, you shouldn't use auto_now_add. Instead you should override save() like this:

class MyModel(models.Model):
    def save(self, *args, **kwargs):
        if date_field is None:
            date_field = datetime.datetime.now()
        super(MyModel, self).save(*args, **kwargs)

comment:2 Changed 4 years ago by ian

  • Resolution invalid deleted
  • Status changed from closed to reopened

I realize it works this way, but I don't agree that it is the correct behaviour. Based on PEP8, I would claim that this is being implicit, rather than explicit, and not pythonic. Any other field that has a default can be overridden.

No explanation as to why the behaviour is as it is, only that it is, and pointing me to the documentation does NOT make it correct.

comment:3 Changed 4 years ago by anonymous

Or PEP20, whatever. Zen of Python; You know what I mean.

comment:4 Changed 4 years ago by anonymous

Sorry for so many comment, but this is a normal situation where I've used auto_now_add and I want to run unit tests against the model. To say that I need to override save() seems utterly ridiculous simply to satisfy my testing situation.

The behaviour is unexpected, and is therefore called into question. Please do not simply dismiss it based on what the docs say.

comment:5 Changed 4 years ago by jezdez

  • Resolution set to wontfix
  • Status changed from reopened to closed

As aaugustin pointed out, this is a known behavior of auto_now_add and can be prevented by providing a custom save method and using the default argument. That way you're actually receiving the behavior you expected.

Note: See TracTickets for help on using tickets.
Back to Top