[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 7cca8d56d2 from master.
This commit is contained in:
Anssi Kääriäinen 2013-07-26 13:02:32 +03:00
parent efdf7442bb
commit 7f892cedba
2 changed files with 17 additions and 1 deletions

View File

@ -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)

View File

@ -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)