Ticket #13240: add_remove_querysets.diff
File add_remove_querysets.diff, 5.8 KB (added by , 15 years ago) |
---|
-
django/db/models/fields/related.py
411 411 412 412 def add(self, *objs): 413 413 for obj in objs: 414 if not isinstance(obj, self.model): 414 if isinstance(obj, QuerySet) and obj.model == self.model: 415 for queried_obj in obj.all(): 416 setattr(queried_obj, rel_field.name, instance) 417 queried_obj.save() 418 elif not isinstance(obj, self.model): 415 419 raise TypeError("'%s' instance expected" % self.model._meta.object_name) 416 setattr(obj, rel_field.name, instance) 417 obj.save() 420 else: 421 setattr(obj, rel_field.name, instance) 422 obj.save() 418 423 add.alters_data = True 419 424 420 425 def create(self, **kwargs): … … 435 440 def remove(self, *objs): 436 441 val = getattr(instance, rel_field.rel.get_related_field().attname) 437 442 for obj in objs: 443 if isinstance(obj, QuerySet) and obj.model == self.model: 444 for queried_obj in obj.all(): 445 # We'll pass over non-related objects in the QuerySet silently 446 if getattr(queried_obj, rel_field.attname) == val: 447 setattr(queried_obj, rel_field.name, None) 448 queried_obj.save() 438 449 # Is obj actually part of this descriptor set? 439 if getattr(obj, rel_field.attname) == val:450 elif getattr(obj, rel_field.attname) == val: 440 451 setattr(obj, rel_field.name, None) 441 452 obj.save() 442 453 else: … … 548 559 raise ValueError('Cannot add "%r": instance is on database "%s", value is on database "%s"' % 549 560 (obj, self.instance._state.db, obj._state.db)) 550 561 new_ids.add(obj.pk) 562 elif isinstance(obj, QuerySet) and obj.model == self.model: 563 new_ids.update(set(obj.values_list("id", flat=True))) 551 564 elif isinstance(obj, Model): 552 565 raise TypeError("'%s' instance expected" % self.model._meta.object_name) 553 566 else: … … 584 597 for obj in objs: 585 598 if isinstance(obj, self.model): 586 599 old_ids.add(obj.pk) 600 elif isinstance(obj, QuerySet) and obj.model == self.model: 601 old_ids.update(set(obj.values_list("id", flat=True))) 587 602 else: 588 603 old_ids.add(obj) 589 604 # Remove the specified objects from the join table -
docs/ref/models/relations.txt
33 33 .. method:: QuerySet.add(obj1, [obj2, ...]) 34 34 35 35 Adds the specified model objects to the related object set. 36 37 .. versionchanged:: 1.2 38 39 The ``add()`` method can now accept ``QuerySet`` objects as well. 36 40 37 41 Example:: 38 42 … … 84 88 without being added to another. In the above example, removing ``e`` from 85 89 ``b.entry_set()`` is equivalent to doing ``e.blog = None``, and because the 86 90 ``blog`` ``ForeignKey`` doesn't have ``null=True``, this is invalid. 91 92 .. versionchanged:: 1.2 93 94 The ``remove()`` method can now accept ``QuerySet`` objects as well. 87 95 88 96 .. method:: QuerySet.clear() 89 97 -
tests/modeltests/many_to_many/models.py
61 61 # Adding a second time is OK 62 62 >>> a2.publications.add(p3) 63 63 64 # Adding and removing using QuerySets works too 65 >>> p4 = Publication(id=None, title='Science Times') 66 >>> p4.save() 67 >>> a2.publications.add(Publication.objects.filter(title__contains="Science")) 68 >>> a2.publications.all() 69 [<Publication: Science News>, <Publication: Science Times>, <Publication: Science Weekly>, <Publication: The Python Journal>] 70 >>> a2.publications.remove(Publication.objects.filter(title__contains="Times")) 71 >>> p4.delete() 72 64 73 # Adding an object of the wrong type raises TypeError 65 74 >>> a2.publications.add(a1) 66 75 Traceback (most recent call last): -
tests/modeltests/many_to_one/models.py
79 79 ... 80 80 TypeError: 'Article' instance expected 81 81 82 >>> r3 = Reporter(first_name='Eric', last_name='James', email='eric@example.com') 83 >>> r3.save() 84 >>> a3 = Article.objects.create(headline="Human interest story", reporter=r, pub_date=datetime(2010, 3, 04)) 85 >>> a4 = Article.objects.create(headline="Eric's story", reporter=r, pub_date=datetime(2010, 3, 14)) 86 >>> new_articles = Article.objects.filter(pub_date__year=2010, pub_date__month=3) 87 >>> r3.article_set.add(new_articles) 88 >>> r3.article_set.all() 89 [<Article: Eric's story>, <Article: Human interest story>] 90 >>> new_articles.delete() 91 >>> r3.delete() 92 82 93 >>> r.article_set.all() 83 94 [<Article: John's second story>, <Article: This is a test>] 84 95 >>> r2.article_set.all()