summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-07-26 13:02:32 +0300
committerAnssi Kääriäinen <akaariai@gmail.com>2013-07-26 13:17:50 +0300
commit7f892cedbad13b444151a1c163a328d968ee6b44 (patch)
treeb369a42507578914b3274dd09d62a97f0d408a81
parentefdf7442bbd81eb4bc460e98e3b5c1825eaef546 (diff)
[1.6.x] Fixed related model lookup regression
It has been possible to use models of wrong type in related field lookups. For example pigs__in=[a_duck] has worked. Changes to ForeignObject broke that. It might be a good idea to restrict the model types usable in lookups. This should be done intentionally, not accidentally and without any consideration for deprecation path. Backpatch of 7cca8d56d28e321ffc395c92f82d97adaa0dcf94 from master.
-rw-r--r--django/db/models/fields/related.py2
-rw-r--r--tests/queries/tests.py16
2 files changed, 17 insertions, 1 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index b288a82298..5c13205fbb 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -1060,7 +1060,7 @@ class ForeignObject(RelatedField):
value_list = []
for source in sources:
# Account for one-to-one relations when sent a different model
- while not isinstance(value, source.model):
+ while not isinstance(value, source.model) and source.rel:
source = source.rel.to._meta.get_field(source.rel.field_name)
value_list.append(getattr(value, source.attname))
return tuple(value_list)
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 352e87a634..ff6c0bb7a1 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -2927,3 +2927,19 @@ class Ticket18785Tests(unittest.TestCase):
).order_by()
self.assertEqual(1, str(qs.query).count('INNER JOIN'))
self.assertEqual(0, str(qs.query).count('OUTER JOIN'))
+
+class RelatedLookupTypeTests(TestCase):
+ def test_wrong_type_lookup(self):
+ oa = ObjectA.objects.create(name="oa")
+ wrong_type = Order.objects.create(id=oa.pk)
+ ob = ObjectB.objects.create(name="ob", objecta=oa, num=1)
+ # Currently Django doesn't care if the object is of correct
+ # type, it will just use the objecta's related fields attribute
+ # (id) for model lookup. Making things more restrictive could
+ # be a good idea...
+ self.assertQuerysetEqual(
+ ObjectB.objects.filter(objecta=wrong_type),
+ [ob], lambda x: x)
+ self.assertQuerysetEqual(
+ ObjectB.objects.filter(objecta__in=[wrong_type]),
+ [ob], lambda x: x)