diff --git a/django/contrib/contenttypes/generic.py b/django/contrib/contenttypes/generic.py index 8dd735d15e1..be675578051 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 df0f6ef5383..1d083cd9879 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 cc34c868b93..21b4e82aa02 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 1972ac72ee9..8093e730137 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()