Made clear() on a reverse foreign key significantly more efficient. Thanks to Andrew Godwin for the review.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16335 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2011-06-07 20:51:59 +00:00
parent 684b0396cf
commit fcf8312ade
3 changed files with 16 additions and 6 deletions

View File

@ -459,9 +459,7 @@ class ForeignRelatedObjectsDescriptor(object):
remove.alters_data = True remove.alters_data = True
def clear(self): def clear(self):
for obj in self.all(): self.update(**{rel_field.name: None})
setattr(obj, rel_field.name, None)
obj.save()
clear.alters_data = True clear.alters_data = True
manager = RelatedManager() manager = RelatedManager()

View File

@ -1,10 +1,13 @@
from copy import deepcopy
from datetime import datetime from datetime import datetime
from django.test import TestCase from django.test import TestCase
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from models import Article, Reporter from models import Article, Reporter
class ManyToOneTests(TestCase):
class ManyToOneTests(TestCase):
def setUp(self): def setUp(self):
# Create a few Reporters. # Create a few Reporters.
self.r = Reporter(first_name='John', last_name='Smith', email='john@example.com') self.r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
@ -368,5 +371,4 @@ class ManyToOneTests(TestCase):
# Regression for #12876 -- Model methods that include queries that # Regression for #12876 -- Model methods that include queries that
# recursive don't cause recursion depth problems under deepcopy. # recursive don't cause recursion depth problems under deepcopy.
self.r.cached_query = Article.objects.filter(reporter=self.r) self.r.cached_query = Article.objects.filter(reporter=self.r)
from copy import deepcopy
self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>") self.assertEqual(repr(deepcopy(self.r)), "<Reporter: John Smith>")

View File

@ -1,8 +1,10 @@
from __future__ import with_statement
from django.test import TestCase from django.test import TestCase
from models import Reporter, Article from models import Reporter, Article
class ManyToOneNullTests(TestCase):
class ManyToOneNullTests(TestCase):
def setUp(self): def setUp(self):
# Create a Reporter. # Create a Reporter.
self.r = Reporter(name='John Smith') self.r = Reporter(name='John Smith')
@ -82,3 +84,11 @@ class ManyToOneNullTests(TestCase):
self.assertQuerysetEqual(self.r.article_set.all(), []) self.assertQuerysetEqual(self.r.article_set.all(), [])
self.assertQuerysetEqual(Article.objects.filter(reporter__isnull=True), self.assertQuerysetEqual(Article.objects.filter(reporter__isnull=True),
['<Article: First>', '<Article: Fourth>']) ['<Article: First>', '<Article: Fourth>'])
def test_remove_efficiency(self):
r = Reporter.objects.create()
for _ in xrange(3):
r.article_set.create()
with self.assertNumQueries(1):
r.article_set.clear()
self.assertEqual(r.article_set.count(), 0)