Ticket #18556: 18556.diff

File 18556.diff, 3.3 KB (added by Tim Graham, 12 years ago)
  • django/db/models/fields/related.py

    diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
    index bd2e288..fc2f6d2 100644
    a b class ForeignRelatedObjectsDescriptor(object):  
    542542            if rel_field.null:
    543543                def remove(self, *objs):
    544544                    val = getattr(self.instance, attname)
     545                    ids = []
    545546                    for obj in objs:
    546547                        # Is obj actually part of this descriptor set?
    547548                        if getattr(obj, rel_field.attname) == val:
    548                             setattr(obj, rel_field.name, None)
    549                             obj.save()
     549                            ids.append(obj.pk)
    550550                        else:
    551551                            raise rel_field.rel.to.DoesNotExist("%r is not related to %r." % (obj, self.instance))
     552                    self.filter(pk__in=ids).update(**{rel_field.name: None})
    552553                remove.alters_data = True
    553554
    554555                def clear(self):
  • docs/ref/models/relations.txt

    diff --git a/docs/ref/models/relations.txt b/docs/ref/models/relations.txt
    index 37986ec..fa1ed38 100644
    a b Related objects reference  
    9191        :class:`~django.db.models.ForeignKey` doesn't have ``null=True``, this
    9292        is invalid.
    9393
     94        .. versionchanged:: 1.6
     95
     96        The ``remove()`` method executes one query regardless of the number of
     97        objects being removed. In prior versions, it executed one query per
     98        object by calling the ``save()`` method of each object being removed.
     99
    94100    .. method:: clear()
    95101
    96102        Removes all objects from the related object set::
  • docs/releases/1.6.txt

    diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
    index 5d61517..cb8979b 100644
    a b Backwards incompatible changes in 1.6  
    108108    deprecation timeline for a given feature, its removal may appear as a
    109109    backwards incompatible change.
    110110
     111*  The :meth:`~django.db.models.fields.related.RelatedManager.remove` method on
     112   a reverse foreign key now does one query regardless of the number of objects
     113   removed rather than one query per object. The ``save()`` method of the
     114   objects being removed is no longer called and thus
     115   :data:`~django.db.models.signals.pre_save` and
     116   :data:`~django.db.models.signals.post_save` signals are no longer sent. This
     117   is consistent with how
     118   :meth:`~django.db.models.fields.related.RelatedManager.clear` works.
     119
    111120Features deprecated in 1.6
    112121==========================
    113122
  • tests/modeltests/many_to_one_null/tests.py

    diff --git a/tests/modeltests/many_to_one_null/tests.py b/tests/modeltests/many_to_one_null/tests.py
    index 4de44b5..935733c 100644
    a b class ManyToOneNullTests(TestCase):  
    9393        with self.assertNumQueries(1):
    9494            r.article_set.clear()
    9595        self.assertEqual(r.article_set.count(), 0)
     96
     97    def test_remove_efficiency(self):
     98        r = Reporter.objects.create()
     99        articles = []
     100        for _ in xrange(3):
     101            articles.append(r.article_set.create())
     102        with self.assertNumQueries(1):
     103            r.article_set.remove(*articles)
     104        self.assertEqual(r.article_set.count(), 0)
Back to Top