This code will cause Model#array_field's data to bleed between different
instances.
{{{
def add_to_array(self, item):
if item not in self.array_field:
self.array_field.append(item)
}}}
However, this code does the correct thing:
{{{
def add_to_array(self, item):
existing = self.array_field
if item not in self.array_field:
self.array_field = existing + [item]
}}}
I put together a django project/app with the code and tests that show the
problems with self.array_field.append(). It also has a Vagrant file setup
that should also exhibit the problems.
https://github.com/redbeard0x0a/django18bug
--
Ticket URL: <https://code.djangoproject.com/ticket/24690>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* stage: Unreviewed => Accepted
* severity: Normal => Release blocker
* needs_tests: => 0
* needs_docs: => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:1>
* status: new => closed
* resolution: => worksforme
Comment:
The issue in your example code is that you have used `default=[]`. This
default is shared between all instances and in this case it is mutable, so
you are modifying the default array.
The correct code is to use `default=list`.
I don't consider this a bug in Django - this is the same behaviour as you
would get if you have code like:
{{{
def myfunc(foo, bar=[]):
bar.append(foo)
return bar
}}}
The first call to `myfunc(1)` would return `[1]`, the second `[1, 1]`,
etc.
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:2>
* status: closed => new
* severity: Release blocker => Normal
* resolution: worksforme =>
* component: contrib.postgres => Documentation
* owner: => nobody
* type: Bug => Cleanup/optimization
Comment:
Could we add a warning about mutable defaults to the `ArrayField` docs? I
guess this also applies to `JSONField`.
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:3>
* owner: nobody => marissazhou
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:4>
* has_patch: 0 => 1
Comment:
Pull Request Submitted
https://github.com/django/django/pull/4806
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:5>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:6>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:7>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:8>
* needs_better_patch: 1 => 0
Comment:
[https://github.com/django/django/pull/5078 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:9>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"f93e7f5674436b230e6b4023570939a20c0c6055" f93e7f5]:
{{{
#!CommitTicketReference repository=""
revision="f93e7f5674436b230e6b4023570939a20c0c6055"
Fixed #24690 -- Added a warning about mutable defaults for
ArrayField/JSONField.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:10>
Comment (by Tim Graham <timograham@…>):
In [changeset:"ef5cf564bff695049b3b51024d05c570be29e4cf" ef5cf564]:
{{{
#!CommitTicketReference repository=""
revision="ef5cf564bff695049b3b51024d05c570be29e4cf"
[1.8.x] Fixed #24690 -- Added a warning about mutable defaults for
ArrayField.
Backport of f93e7f5674436b230e6b4023570939a20c0c6055 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/24690#comment:11>