[Django] #22571: DateTimeField(auto_now_add=True) Breaks

22 views
Skip to first unread message

Django

unread,
May 3, 2014, 9:36:07 PM5/3/14
to django-...@googlegroups.com
#22571: DateTimeField(auto_now_add=True) Breaks
-------------------------+-------------------------------------------------
Reporter: | Owner: nobody
nu.everest@… | Status: new
Type: | Version: 1.4
Uncategorized | Keywords: integrityerror auto_now_add
Component: | get_or_create duplicatekey
Uncategorized | Has patch: 0
Severity: Normal | UI/UX: 0
Triage Stage: |
Unreviewed |
Easy pickings: 0 |
-------------------------+-------------------------------------------------
Example:
# Given this simple model
class Foo(models.Model):
name = models.CharField(max_length=100)
date_added = models.DateTimeField(auto_now_add=True)

# This will always be true, even if an instance
# with this name and today's date already exists

bar, created = Foo.objects.get_or_create(
name = 'Alex',
date_added = some_datetime_obj
)

print created
# >> True


# The problem is, auto_now_add does some stuff that
# makes it uneditable, and messes up my expectations
# when using it with get_or_create

# Here's the solution
class Foo(models.Model):
name = models.CharField(max_length=100)
date_added = models.DateTimeField(default=datetime.today())

bar, created = Foo.objects.get_or_create(
name = 'Alex',
date_added = some_datetime_obj
)

print created
# >> False

Error:
django.db.utils.IntegrityError: duplicate key value violates unique
constraint


These two links document the issue:
http://alexkehayias.tumblr.com/post/33889961953/django-gotcha-duplicate-
models-when-using

http://stackoverflow.com/questions/9297422/get-or-create-failure-with-
django-and-postgres-duplicate-key-value-violates-uni

--
Ticket URL: <https://code.djangoproject.com/ticket/22571>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 5, 2014, 7:01:28 AM5/5/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: 1.4
Component: Documentation | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: integrityerror | Needs documentation: 0
auto_now_add get_or_create | Patch needs improvement: 0
duplicatekey | UI/UX: 0
Has patch: 0 |
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Changes (by timo):

* needs_better_patch: => 0
* component: Uncategorized => Documentation
* needs_tests: => 0
* needs_docs: => 0
* type: Uncategorized => Cleanup/optimization
* stage: Unreviewed => Accepted


Comment:

I suppose the documentation could have a note about this.

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:1>

Django

unread,
May 16, 2014, 9:17:54 AM5/16/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: 1.4
Component: Documentation | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: integrityerror | Needs documentation: 0
auto_now_add get_or_create | Patch needs improvement: 0
duplicatekey | UI/UX: 0
Has patch: 0 |
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by MarkusH):

Your solution is not a solution at all, because your default on the
DateTimeField is evaluated only once at model loading. You can use
Django's `django.utils.timezone.now` (w/o the trailing `()`).

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:2>

Django

unread,
May 16, 2014, 11:13:09 AM5/16/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: 1.4
Component: Documentation | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: integrityerror | Needs documentation: 0
auto_now_add get_or_create | Patch needs improvement: 0
duplicatekey | UI/UX: 0
Has patch: 0 |
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Description changed by russellm:

Old description:

New description:

print created
# >> True

print created
# >> False

http://stackoverflow.com/questions/9297422/get-or-create-failure-with-
django-and-postgres-duplicate-key-value-violates-uni

--

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:3>

Django

unread,
May 18, 2014, 4:02:57 PM5/18/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: 1.4
Component: Documentation | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: integrityerror | Needs documentation: 0
auto_now_add get_or_create | Patch needs improvement: 0
duplicatekey | UI/UX: 0
Has patch: 0 |
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by mardini):

Note that your date_added is a DateTimeField, not a DateField, so it takes
time into account. That's why using "today's date" won't match the
existing value of date_added (since it's today's date + a particular
time). If however some_datetime_obj in your first is exactly the same date
and time, no new object will be created. If you don't want to consider the
time in your get_or_create(), you can either use a DateField for
date_added, or filter against year/month/day of your DateTimeField. So I
think this ticket is invalid.

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:4>

Django

unread,
May 30, 2014, 2:31:30 PM5/30/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization | Version: 1.4
Component: Documentation | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: integrityerror | Needs documentation: 0
auto_now_add get_or_create | Patch needs improvement: 0
duplicatekey | UI/UX: 0
Has patch: 0 |
Needs tests: 0 |
Easy pickings: 0 |
-------------------------------------+-------------------------------------

Comment (by charettes):

Replying to [comment:4 mardini]:


> Note that your date_added is a DateTimeField, not a DateField, so it
takes time into account. That's why using "today's date" won't match the
existing value of date_added (since it's today's date + a particular
time). If however some_datetime_obj in your first is exactly the same date
and time, no new object will be created. If you don't want to consider the
time in your get_or_create(), you can either use a DateField for
date_added, or filter against year/month/day of your DateTimeField. So I
think this ticket is invalid.

I agree that the second example is a bit wrong but there's a legitimate
issue to be documented here.

{{{#!python
from django.db import models
from django.utils import timezone

class Auto(models.Model):
added = models.DateTimeField(auto_now_add=True)

class Default(models.Model):
added = models.DateTimeField(default=timezone.now)
}}}

{{{#!python
In [1]: from app.models import Auto, Default, timezone

In [2]: added = timezone.now()

In [3]: Auto.objects.get_or_create(added=added)
Out[3]: (<Auto: Auto object>, True)

In [4]: Auto.objects.get_or_create(added=added)
Out[4]: (<Auto: Auto object>, True)

In [5]: Default.objects.get_or_create(added=added)
Out[5]: (<Default: Default object>, True)

In [6]: Default.objects.get_or_create(added=added)
Out[6]: (<Default: Default object>, False)
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:5>

Django

unread,
Dec 31, 2014, 11:44:55 PM12/31/14
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: nobody
Type: | Status: new
Cleanup/optimization |
Component: Documentation | Version: 1.4
Severity: Normal | Resolution:
Keywords: integrityerror | Triage Stage: Accepted
auto_now_add get_or_create |
duplicatekey |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by iambibhas):

* cc: me@… (added)


Comment:

Replying to [comment:5 charettes]:


> {{{#!python
> In [1]: from app.models import Auto, Default, timezone
>
> In [2]: added = timezone.now()
>
> In [3]: Auto.objects.get_or_create(added=added)
> Out[3]: (<Auto: Auto object>, True)
>
> In [4]: Auto.objects.get_or_create(added=added)
> Out[4]: (<Auto: Auto object>, True)
>
> In [5]: Default.objects.get_or_create(added=added)
> Out[5]: (<Default: Default object>, True)
>
> In [6]: Default.objects.get_or_create(added=added)
> Out[6]: (<Default: Default object>, False)
> }}}

Isn't this expected? The doc says -

> DateField.auto_now_add
>
> 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.

And the code also shows that the value with always set to `timezone.now()`
if `auto_now_add` is set, even if you provide a value when creating it.

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:6>

Django

unread,
Jun 5, 2015, 5:30:09 AM6/5/15
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: yamila-
Type: | moreno
Cleanup/optimization | Status: assigned

Component: Documentation | Version: 1.4
Severity: Normal | Resolution:
Keywords: integrityerror | Triage Stage: Accepted
auto_now_add get_or_create |
duplicatekey |
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by yamila-moreno):

* owner: nobody => yamila-moreno
* status: new => assigned


--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:7>

Django

unread,
Jun 5, 2015, 5:37:37 AM6/5/15
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: yamila-
Type: | moreno
Cleanup/optimization | Status: assigned
Component: Documentation | Version: 1.4
Severity: Normal | Resolution:
Keywords: integrityerror | Triage Stage: Accepted
auto_now_add get_or_create |
duplicatekey |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by yamila-moreno):

* has_patch: 0 => 1


Comment:

PR: https://github.com/django/django/pull/4792

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:8>

Django

unread,
Jun 5, 2015, 9:57:06 AM6/5/15
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: yamila-
Type: | moreno
Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.4
Severity: Normal | Resolution: fixed

Keywords: integrityerror | Triage Stage: Accepted
auto_now_add get_or_create |
duplicatekey |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"cbe4efcbc13ad402bf1f1a94b02a8ec93f20327d" cbe4efc]:
{{{
#!CommitTicketReference repository=""
revision="cbe4efcbc13ad402bf1f1a94b02a8ec93f20327d"
Fixed #22571 -- Added clarification about auto_now_add=True
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:9>

Django

unread,
Jun 5, 2015, 10:04:41 AM6/5/15
to django-...@googlegroups.com
#22571: Document implications of using auto_now_add=True and get_or_create
-------------------------------------+-------------------------------------
Reporter: nu.everest@… | Owner: yamila-
Type: | moreno
Cleanup/optimization | Status: closed
Component: Documentation | Version: 1.4
Severity: Normal | Resolution: fixed
Keywords: integrityerror | Triage Stage: Accepted
auto_now_add get_or_create |
duplicatekey |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham <timograham@…>):

In [changeset:"7dcfbb2ef38bb806531d6e73dd179d5266f48d7a" 7dcfbb2e]:
{{{
#!CommitTicketReference repository=""
revision="7dcfbb2ef38bb806531d6e73dd179d5266f48d7a"
[1.8.x] Fixed #22571 -- Added clarification about auto_now_add=True

Backport of cbe4efcbc13ad402bf1f1a94b02a8ec93f20327d from master
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/22571#comment:10>

Reply all
Reply to author
Forward
0 new messages