summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAymeric Augustin <aymeric.augustin@m4x.org>2013-09-06 17:13:51 -0500
committerAymeric Augustin <aymeric.augustin@m4x.org>2013-09-06 21:59:28 -0500
commitf855058c35db9d35ba7f310d8f9db6f4533b7424 (patch)
tree693a3b62d983c501050548d1fde1fa062b808a83
parent2a2ac5c1400c67f25388621a39749c918a4efe98 (diff)
[1.6.x] Fixed #11811 -- Data-loss bug in queryset.update.
It's now forbidden to call queryset.update(field=instance) when instance hasn't been saved to the database ie. instance.pk is None. Conflicts: tests/queries/tests.py Backport of b4cd8169 from master.
-rw-r--r--django/db/models/base.py2
-rw-r--r--tests/queries/models.py4
-rw-r--r--tests/queries/tests.py10
3 files changed, 15 insertions, 1 deletions
diff --git a/django/db/models/base.py b/django/db/models/base.py
index dfb4fae24c..33229f21f3 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -736,6 +736,8 @@ class Model(six.with_metaclass(ModelBase)):
return getattr(self, cachename)
def prepare_database_save(self, unused):
+ if self.pk is None:
+ raise ValueError("Unsaved model instance %r cannot be used in an ORM query." % self)
return self.pk
def clean(self):
diff --git a/tests/queries/models.py b/tests/queries/models.py
index 7248246261..99c04a1c9b 100644
--- a/tests/queries/models.py
+++ b/tests/queries/models.py
@@ -17,9 +17,13 @@ class ProxyCategory(DumbCategory):
class Meta:
proxy = True
+@python_2_unicode_compatible
class NamedCategory(DumbCategory):
name = models.CharField(max_length=10)
+ def __str__(self):
+ return self.name
+
@python_2_unicode_compatible
class Tag(models.Model):
name = models.CharField(max_length=10)
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index fbeadf726a..cffead7a52 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -13,6 +13,7 @@ from django.db.models.sql.where import WhereNode, EverythingNode, NothingNode
from django.db.models.sql.datastructures import EmptyResultSet
from django.test import TestCase, skipUnlessDBFeature
from django.test.utils import str_prefix
+from django.utils import six
from django.utils import unittest
from django.utils.datastructures import SortedDict
@@ -957,7 +958,7 @@ class Queries1Tests(BaseQuerysetTest):
q = NamedCategory.objects.filter(tag__parent__isnull=True)
self.assertTrue(str(q.query).count('INNER JOIN') == 1)
self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 1)
- self.assertQuerysetEqual( q, ['<NamedCategory: NamedCategory object>'])
+ self.assertQuerysetEqual(q, ['<NamedCategory: Generic>'])
def test_ticket_10790_4(self):
# Querying across m2m field should not strip the m2m table from join.
@@ -1267,6 +1268,13 @@ class Queries4Tests(BaseQuerysetTest):
Item.objects.create(name='i1', created=datetime.datetime.now(), note=n1, creator=self.a1)
Item.objects.create(name='i2', created=datetime.datetime.now(), note=n1, creator=self.a3)
+ def test_ticket11811(self):
+ unsaved_category = NamedCategory(name="Other")
+ with six.assertRaisesRegex(self, ValueError,
+ 'Unsaved model instance <NamedCategory: Other> '
+ 'cannot be used in an ORM query.'):
+ Tag.objects.filter(pk=self.t1.pk).update(category=unsaved_category)
+
def test_ticket14876(self):
# Note: when combining the query we need to have information available
# about the join type of the trimmed "creator__isnull" join. If we