Code

Ticket #16955: 16955.diff

File 16955.diff, 4.8 KB (added by dgouldin, 3 years ago)
Line 
1diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
2index 61fd2be..6e7abc1 100644
3--- a/django/db/models/sql/query.py
4+++ b/django/db/models/sql/query.py
5@@ -1092,6 +1092,12 @@ class Query(object):
6                     can_reuse)
7             return
8 
9+        from django.db.models.base import Model
10+        from django.db.models.fields.related import RelatedField
11+        if (isinstance(field, RelatedField) and isinstance(value, Model) and
12+                not isinstance(value, target.model)):
13+            raise TypeError, "'%s' instance expected" % target.model._meta.object_name
14+
15         table_promote = False
16         join_promote = False
17 
18diff --git a/tests/modeltests/many_to_many/tests.py b/tests/modeltests/many_to_many/tests.py
19index 39fe581..2479268 100644
20--- a/tests/modeltests/many_to_many/tests.py
21+++ b/tests/modeltests/many_to_many/tests.py
22@@ -195,6 +195,11 @@ class ManyToManyTests(TestCase):
23         self.assertQuerysetEqual(Article.objects.exclude(publications=self.p2),
24                                  ['<Article: Django lets you build Web apps easily>'])
25 
26+        # Filter values on related fields are checked to ensure the correct
27+        # model class is being used.
28+        self.assertRaises(TypeError, Article.objects.filter,
29+            publications=self.a1)
30+
31     def test_reverse_selects(self):
32         # Reverse m2m queries are supported (i.e., starting at the table that
33         # doesn't have a ManyToManyField).
34@@ -245,6 +250,11 @@ class ManyToManyTests(TestCase):
35                 '<Publication: The Python Journal>',
36             ])
37 
38+        # Filter values on related fields are checked to ensure the correct
39+        # model class is being used.
40+        self.assertRaises(TypeError, Publication.objects.filter,
41+             article=self.p1)
42+
43     def test_delete(self):
44         # If we delete a Publication, its Articles won't be able to access it.
45         self.p1.delete()
46diff --git a/tests/modeltests/many_to_one/tests.py b/tests/modeltests/many_to_one/tests.py
47index 9f60c21..053c5ee 100644
48--- a/tests/modeltests/many_to_one/tests.py
49+++ b/tests/modeltests/many_to_one/tests.py
50@@ -230,6 +230,10 @@ class ManyToOneTests(TestCase):
51                 "<Article: This is a test>",
52             ])
53 
54+        # Filter values on related fields are checked to ensure the correct
55+        # model class is being used.
56+        self.assertRaises(TypeError, Article.objects.filter, reporter=self.a)
57+
58     def test_reverse_selects(self):
59         a3 = Article.objects.create(id=None, headline="Third article",
60                                     pub_date=datetime(2005, 7, 27), reporter_id=self.r.id)
61@@ -301,6 +305,10 @@ class ManyToOneTests(TestCase):
62             list(Article.objects.filter(reporter=self.r).distinct().order_by()
63                  .values('reporter__first_name', 'reporter__last_name')))
64 
65+        # Filter values on related fields are checked to ensure the correct
66+        # model class is being used.
67+        self.assertRaises(TypeError, Reporter.objects.filter, article=self.r)
68+
69     def test_select_related(self):
70         # Check that Article.objects.select_related().dates() works properly when
71         # there are multiple Articles with the same date but different foreign-key
72diff --git a/tests/modeltests/one_to_one/tests.py b/tests/modeltests/one_to_one/tests.py
73index c3e1704..0e5724a 100644
74--- a/tests/modeltests/one_to_one/tests.py
75+++ b/tests/modeltests/one_to_one/tests.py
76@@ -61,6 +61,10 @@ class OneToOneTests(TestCase):
77         assert_get_restaurant(place__pk=self.p1.pk)
78         assert_get_restaurant(place__name__startswith="Demon")
79 
80+        # Filter values on related fields are checked to ensure the correct
81+        # model class is being used.
82+        self.assertRaises(TypeError, Restaurant.objects.get, place=self.r)
83+
84         def assert_get_place(**params):
85             self.assertEqual(repr(Place.objects.get(**params)),
86                              '<Place: Demon Dogs the place>')
87@@ -75,6 +79,10 @@ class OneToOneTests(TestCase):
88         assert_get_place(id__exact=self.p1.pk)
89         assert_get_place(pk=self.p1.pk)
90 
91+        # Filter values on related fields are checked to ensure the correct
92+        # model class is being used.
93+        self.assertRaises(TypeError, Place.objects.get, restaurant=self.p1)
94+
95     def test_foreign_key(self):
96         # Add a Waiter to the Restaurant.
97         w = self.r.waiter_set.create(name='Joe')
98@@ -89,7 +97,6 @@ class OneToOneTests(TestCase):
99         assert_filter_waiters(restaurant__place__exact=self.p1)
100         assert_filter_waiters(restaurant__place__pk=self.p1.pk)
101         assert_filter_waiters(restaurant__exact=self.p1.pk)
102-        assert_filter_waiters(restaurant__exact=self.p1)
103         assert_filter_waiters(restaurant__pk=self.p1.pk)
104         assert_filter_waiters(restaurant=self.p1.pk)
105         assert_filter_waiters(restaurant=self.r)