What is the status of auto_now and auto_now_add?

499 views
Skip to first unread message

Ryan K

unread,
Sep 10, 2009, 9:35:19 AM9/10/09
to Django developers
I wrote an article here http://www.ryankaskel.com/2009/09/09/model-development-tips-for-django-projects/
describing a useful case (or rather a useful set up for many potential
cases) using abstract base models that implements this:

# Abstract models used by various application specific models

from django.db import models

class CommonAbstractModel(models.Model):
added = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)

class Meta:
abstract = True

The documentation still says these attributes are fine to use yet
respected Django develop James Bennett and Jacob (coBDFL) have both
stated comments to the effect that these attributes should never be
used (the former here: http://www.b-list.org/weblog/2006/nov/02/django-tips-auto-populated-fields/,
and the latter here: http://code.djangoproject.com/ticket/1056 -- a 4
year old ticket last updated two years ago). In the code it says that
using these attributes is a hack. Another blogger wrote here that
http://benspaulding.com/weblog/2008/aug/02/auto_now_add-evil/ that
auto_now_add is evil and it links to James's blog.

Now the newforms-admin was added within a year of that last referenced
blog post and in that case the auto_now_add failed during his admin
hacking experience. Does newforms-admin change the status of
auto_now_add and auto_now as being evil? The code itself doesn't look
evil?

I'm trying to give advice to people but I can't even figure it out
myself (even though it works for me just fine -- so far?).

Developer in distress,
Ryan Kaskel

drozzy

unread,
Sep 10, 2009, 12:03:25 PM9/10/09
to Django developers
Hi,
I've looked at the svn and I don't quite understand what's wrong with
auto_now or auto_now_add.
Can you see a problem with it?
http://code.djangoproject.com/browser/django/trunk/django/db/models/fields/__init__.py#L453




On Sep 10, 10:35 am, Ryan K <ryankas...@gmail.com> wrote:
> I wrote an article herehttp://www.ryankaskel.com/2009/09/09/model-development-tips-for-djang...
> describing a useful case (or rather a useful set up for many potential
> cases) using abstract base models that implements this:
>
> # Abstract models used by various application specific models
>
> from django.db import models
>
> class CommonAbstractModel(models.Model):
>     added = models.DateTimeField(auto_now_add=True)
>     modified = models.DateTimeField(auto_now=True)
>     active = models.BooleanField(default=True)
>
>     class Meta:
>         abstract = True
>
> The documentation still says these attributes are fine to use yet
> respected Django develop James Bennett and Jacob (coBDFL) have both
> stated comments to the effect that these attributes should never be
> used (the former here:http://www.b-list.org/weblog/2006/nov/02/django-tips-auto-populated-f...,
> and the latter here:http://code.djangoproject.com/ticket/1056-- a 4

Waylan Limberg

unread,
Sep 10, 2009, 12:15:04 PM9/10/09
to django-d...@googlegroups.com
Well, both auto_now and auto_now_add are fully documented [1] and part
of the official releases since 1.0. And I note that the docs
specifically mention how auto_now_add behaves in the admin (remember
the newforms-admin was merged before 1.0 was released). That being the
case the devs have committed to long term support. At least, as I
understand it, if they were to be removed it would happen only after
depreciation warnings etc through multiple releases before they would
be dropped completely.

Of course, I can't speak for what the core dev's official opinion is
of them, but they are all in the middle of DjangoCon this week and
generally not checking their email. Thus the quiet on the lists.
You'll have to wait a few days for more. Regardless, I think you may
be dwelling on some old, outdated info.

[1]: http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.DateField
--
----
\X/ /-\ `/ |_ /-\ |\|
Waylan Limberg

drozzy

unread,
Sep 10, 2009, 12:18:14 PM9/10/09
to Django developers
I see, but what strikes me as odd is the comment in the source:
"#HACKs : auto_now_add/auto_now should be done as a default or a
pre_save."

Andrew Gwozdziewycz

unread,
Sep 10, 2009, 12:19:56 PM9/10/09
to django-d...@googlegroups.com
On Thu, Sep 10, 2009 at 9:35 AM, Ryan K<ryank...@gmail.com> wrote:

> I'm trying to give advice to people but I can't even figure it out
> myself (even though it works for me just fine -- so far?).

Last week, I ran into a problem using them because I wanted to set manually
the date in certain situations. auto_now sets it to datetime.datetime.now()
*everytime* it's saved, which means you can't actually set it manually. Thus,
you have to be careful, and overriding save() may be a better option in some
cases.


--
http://www.apgwoz.com

drozzy

unread,
Sep 10, 2009, 12:21:38 PM9/10/09
to Django developers
Well, that is the purpose of that. I mean if you want a custom field
that saves only on Thursday, it makes sense to write a modified save
routine..


On Sep 10, 1:19 pm, Andrew Gwozdziewycz <apg...@gmail.com> wrote:

Andrew Gwozdziewycz

unread,
Sep 10, 2009, 12:37:34 PM9/10/09
to django-d...@googlegroups.com
On Thu, Sep 10, 2009 at 12:21 PM, drozzy<dro...@gmail.com> wrote:
>
> Well, that is the purpose of that. I mean if you want a custom field
> that saves only on Thursday, it makes sense to write a modified save
> routine..

Of course it is the purpose. I was replying to Ryan K, with sort of an answer
of "it depends." We're stuck with auto_now, and auto_now_add, and they
work perfectly fine in some situations. They just aren't the be-all, end-all
solution to automatically saving date columns, as you so bluntly pointed out.

> On Sep 10, 1:19 pm, Andrew Gwozdziewycz <apg...@gmail.com> wrote:
>> On Thu, Sep 10, 2009 at 9:35 AM, Ryan K<ryankas...@gmail.com> wrote:
>> > I'm trying to give advice to people but I can't even figure it out
>> > myself (even though it works for me just fine -- so far?).
>>
>> Last week, I ran into a problem using them because I wanted to set manually
>> the date in certain situations. auto_now sets it to datetime.datetime.now()
>> *everytime* it's saved, which means you can't actually set it manually. Thus,
>> you have to be careful, and overriding save() may be a better option in some
>> cases.
>>
>> --http://www.apgwoz.com
> >
>



--
http://www.apgwoz.com

Ryan K

unread,
Sep 10, 2009, 1:03:19 PM9/10/09
to Django developers
Thank you Waylan for your comments. I've found the developer
discussion about this (searching the group for "auto_now_add" does not
find the result! wow! Google missing an easy hit?).
http://groups.google.com/group/django-developers/browse_thread/thread/4cd631c225cb4e52
. This solves the problem sufficiently. Thanks.

Ryan K

unread,
Sep 10, 2009, 2:26:58 PM9/10/09
to Django developers
By the way drossy, I still don't know why it's evil, just that every
respected Django dev (and BDFLs) were +1 on removing it (very +1). But
the reasons don't seem consistent. In one case James B. describe's
some unexplained side effects of using it (which coincide with another
bloggers findings) which would make the two attributes unstable. I
don't know if that is just older behavior from previous releases.

Then the above discussion I found (through a link on a blog to a
ticket that Google (!) can't find) says that it violates the DRY
principle. Well, in my eyes, and some developers in that discussion
would agree, it's just a very convenient attribute, like the
render_to_response function. Anyway, I just used default for
auto_now_add and created a DateTimeField sublass AutoDateTimeField
which overrides pre_save and returns datetime.datetime no matter the
value of the in argument "add" (auto_now) -- an example of one of the
many alternative solutions suggested.

It should have just been removed before 1.0 (a perfect time to do
that) like it seemed they would do but it seems they opted for
backward compatibility instead.

At least this discussion is "findable" by Google Group's search.

Cheers,
Ryan

On Sep 10, 1:03 pm, Ryan K <ryankas...@gmail.com> wrote:
> Thank you Waylan for your comments. I've found the developer
> discussion about this (searching the group for "auto_now_add" does not
> find the result! wow! Google missing an easy hit?).http://groups.google.com/group/django-developers/browse_thread/thread...

drozzy

unread,
Sep 10, 2009, 3:56:03 PM9/10/09
to Django developers
I find it amusing how people like to use fancy words like DRY, without
explaining exactly how it applies.
I am not trying to argue for keeping auto_now, but I just don't see
what the fuss is about?

The lazy date thing seems more "un-DRY" to me that this. But then
again, why not have both? + the "default" value.

I can see perfectly coding up something like this:

class Document(models.Model):
created = Date.... (auto_now_add
modified = Date...(auto_now...

This way I can CLEARLY see which fields do waht. IMHO it is much
better than Inheriting from some super/meta/power-class or using some
smart-ass decorators. I mean how far can we go with those, and how
will it look?

@auto_now('modified')
@auto_add_now('created')
@permission..
@other_stuff
@christmas_tree
class Document(models.Model):
created = Date.... ()
modified = Date...()


OR:

class Document(ComplicatedParent, AnotherFunParent):
pass

ComplicatedParent(models.Model?):
created = Date.... ()
modified = Date...()

def save():
//with custom save logic...

This last one, is the Approach I actually took, and let me tell you -
it was not pleasant always going and trying to dig up the class
hierarchy to see which fields exactly this model has.

Nick Lo

unread,
Sep 10, 2009, 7:24:11 PM9/10/09
to django-d...@googlegroups.com
> By the way drossy, I still don't know why it's evil, just that every
> respected Django dev (and BDFLs) were +1 on removing it (very +1). But
> the reasons don't seem consistent. In one case James B. describe's
> some unexplained side effects of using it (which coincide with another
> bloggers findings) which would make the two attributes unstable. I
> don't know if that is just older behavior from previous releases.

Since auto_now uses datetime.datetime.now() I don't know if it's
tangential or relevant to point to another article that discusses some
unexpected behaviour of datetime. It says "datetime.now() is never to
be used. Always use datetime.utcnow()":

http://www.enricozini.org/2009/debian/using-python-datetime/

I've not investigated this to any degree so I'm just passing it on as
a potentially relevant sidenote.

Nick

drozzy

unread,
Sep 14, 2009, 7:44:37 AM9/14/09
to Django developers
I can't see the problem in that article.
Also, the datetime objects have changed since then, taking a timezone
as optional parameter:
http://docs.python.org/library/datetime.html#datetime-objects

I mean we are using date/time already with our pre-save way of doing
things, why should auto_add act any different?

Nick Lo

unread,
Sep 14, 2009, 8:34:41 PM9/14/09
to django-d...@googlegroups.com
> I can't see the problem in that article.
> Also, the datetime objects have changed since then, taking a timezone
> as optional parameter:
> http://docs.python.org/library/datetime.html#datetime-objects
>
> I mean we are using date/time already with our pre-save way of doing
> things, why should auto_add act any different?

I don't understand what you mean by "changed since then" as that
article was "Last edited Thu 25 Jun 2009". I was referring
specifically to /db/models/fields/__init__.py line 888:

value = datetime.datetime.now()

As you say, datetime.now() takes timezone as an optional parameter,
but it has done for years. From my reading of that article the
statement "datetime.now() is never to be used. Always use
datetime.utcnow()" means the above line would become:

value = datetime.datetime.utcnow()

I'm not and cannot argue for or against that idea due to my poor
knowledge of Python, it's date libraries and the whole timezone issue
in general so I'm really just wondering if that has any relevance?
Thanks to the original poster I'm now also interested in whether and
if so why, auto_now and auto_now_add are to be avoided.

Nick

Reply all
Reply to author
Forward
0 new messages