In the following test case the join type of the User model isn't promoted (to a LEFT OUTER JOIN) as it should be when using a ValuesQuerySet. This results in nothing being returned when the Item.person ForeignKey is null.
Three (or more) models deep linked by ForeignKey's.
The first model's (Item) ForeignKey should allow null values.
The query should reference the second model (Person), but not the third (User), before conversion to a ValuesQuerySet.
The values list (that is passed to ValueQuerySet) should reference a field in the third model (User).
The following snippet shows what happens currently. Note that the Q objects aren't required, they are just for satisfying point 3 above.
When the filter is constructed, a query.alias_map entry is created for the Person model. It is NULLABLE so the join type is set to LOUTER which is correct.
During the conversion to a ValuesQuerySet, promote_alias_chain is called on the fields from the User model (eg. person__user__first_name or person__user__last_name).
Because Person had been previously promoted promote_alias returns False which causes promote_alias_chain to not promote the User model.
promote_alias should return True if it promotes the join or if the join has previously been promoted, so that promote_alias_chain can promote the remainder of the chain correctly.
The included diff provides a simple fix to promote_alias and a test case that tests the fix.
promote_alias.diff​ (2.6 KB) - added by ryanbutterfield 8 years ago.
Tests need to be updated to be unittests. Preferably, they should also be integrated into an existing test app, rather than starting a whole new test app. The regressiontest/queries test app would seem appropriate.
This bug still exists. The patch works fine for me, any reason there's been no activity on this for 9 months?
If you want to see this move forward, please Russel's comment above.
It seems this was fixed in 1.5 as the tests from the patch fail in 1.4 but pass on 1.5 and later.