carljm/django-model-utils — pull request #78 by screamndigit (2013-09-12 18:14:25+00:00)
Title: preserve reverse_related_field caches when casting to a subclass

I was going to write a test for this but the tests currently fail up to 4 assertions when I run them without making a change. Anyway, I'm new at this whole pull thing so be gentle.

The issue is if i define a class with a related class:

class Opportunity(models.Model):
objects=InheritanceManager()
pass

class Contest(Opportunity):
pass

class Terms(models.Model):
opportunity = models.OneToOneField(Opportunity, related_name='contest_terms')

Calling:

contests = Opportunity.objects.select_related('contest_terms').filter(id=1)
t = contests[0].contest_terms
assert(len(connection.queries)==1)

works because it makes one DB hit and can access the contest_terms as it's been cached by select_related()
changing the query in the first line to include select_subclasses:

contests = Opportunity.objects.select_related('contest_terms').select_subclasses('contest').filter(id=1)

fails because the related object cache is lost after subclassing so it makes the additional hit to the DB to get the terms.

The fix I proposed will copy the object caches from the base class when _get_sub_obj_recurse finds the appropriate subclass. This will keep the results of select_related() in the returned model instance.