Django documentation states that:
If you don't provide a lookup type -- that is, if your keyword argument doesn't contain a double underscore -- the lookup type is assumed to be exact.
For example, the following two statements are equivalent:
Blog.objects.get(id=14)
Blog.objects.get(id__exact=14)
This is for convenience, because exact lookups are the common case.
While this is true for the provided example, it is not true for joined queries:
Blog.objects.get(author__id=14)
Blog.objects.get(author__id__exact=14)
The second query works - the first one fails because "id" is not a valid query term.
The fault appears to be in the code in parse_lookup that does pk 'faking' of queries - this code relies upon a query size of 1 to determin the assumed __exact, which fails if there are multiple query terms.