From 6ce25d3be9804ca199b65110d10240559293a917 Mon Sep 17 00:00:00 2001 From: Jacob Kaplan-Moss Date: Mon, 30 Mar 2009 22:41:49 +0000 Subject: [PATCH] Fixed #10413: RelatedManager.add no longer fails silenty when trying to add an object of the wrong type. Thanks, dgouldin. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10226 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/contenttypes/generic.py | 2 ++ django/db/models/fields/related.py | 5 +++++ tests/modeltests/many_to_many/models.py | 6 ++++++ tests/modeltests/many_to_one/models.py | 7 +++++++ 4 files changed, 20 insertions(+) diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index 8dd735d15e..be67557805 100644 --- a/django/contrib/contenttypes/generic.py +++ b/django/contrib/contenttypes/generic.py @@ -253,6 +253,8 @@ def create_generic_related_manager(superclass): def add(self, *objs): for obj in objs: + if not isinstance(obj, self.model): + raise TypeError, "'%s' instance expected" % self.model._meta.object_name setattr(obj, self.content_type_field_name, self.content_type) setattr(obj, self.object_id_field_name, self.pk_val) obj.save() diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index df0f6ef538..1d083cd987 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -332,6 +332,8 @@ class ForeignRelatedObjectsDescriptor(object): def add(self, *objs): for obj in objs: + if not isinstance(obj, self.model): + raise TypeError, "'%s' instance expected" % self.model._meta.object_name setattr(obj, rel_field.name, instance) obj.save() add.alters_data = True @@ -452,11 +454,14 @@ def create_many_related_manager(superclass, through=False): # If there aren't any objects, there is nothing to do. if objs: + from django.db.models.base import Model # Check that all the objects are of the right type new_ids = set() for obj in objs: if isinstance(obj, self.model): new_ids.add(obj._get_pk_val()) + elif isinstance(obj, Model): + raise TypeError, "'%s' instance expected" % self.model._meta.object_name else: new_ids.add(obj) # Add the newly created or already existing objects to the join table. diff --git a/tests/modeltests/many_to_many/models.py b/tests/modeltests/many_to_many/models.py index cc34c868b9..21b4e82aa0 100644 --- a/tests/modeltests/many_to_many/models.py +++ b/tests/modeltests/many_to_many/models.py @@ -61,6 +61,12 @@ ValueError: 'Article' instance needs to have a primary key value before a many-t # Adding a second time is OK >>> a2.publications.add(p3) +# Adding an object of the wrong type raises TypeError +>>> a2.publications.add(a1) +Traceback (most recent call last): +... +TypeError: 'Publication' instance expected + # Add a Publication directly via publications.add by using keyword arguments. >>> new_publication = a2.publications.create(title='Highlights for Children') diff --git a/tests/modeltests/many_to_one/models.py b/tests/modeltests/many_to_one/models.py index 1972ac72ee..8093e73013 100644 --- a/tests/modeltests/many_to_one/models.py +++ b/tests/modeltests/many_to_one/models.py @@ -72,6 +72,13 @@ __test__ = {'API_TESTS':""" >>> r2.article_set.add(new_article2) >>> new_article2.reporter.id 2 + +# Adding an object of the wrong type raises TypeError +>>> r.article_set.add(r2) +Traceback (most recent call last): +... +TypeError: 'Article' instance expected + >>> r.article_set.all() [, ] >>> r2.article_set.all()