Custom model Manager get_query_set extra not working #34

Closed
karoljoc opened this Issue Mar 21, 2013 · 7 comments

Projects

None yet

4 participants

@karoljoc

Good day,

I can't seem to get the extra select results when using an Inheritance manager and I can't seem to find any documentation on how to sub class InheritanceManager and override the get_query_set method.

Example:

class GeneralManager(InheritanceManager):
    def get_query_set(self):
        return super(GeneralManager, self).get_query_set().extra(select={'counter': 'some sql'})

class General(models.Model):
    name = models.CharField(max_length = 30)
    objects = GeneralManager()

class Car(General):
    pass

class Truck(General):
   pass

When using this kind of model structure when I do a General.objects.select_subclasses() each object in the queryset no longer has the 'counter' sub select. If I remove the select_subclasses they all have the 'counter' sub select.

Any help would be highly appreciated.

@carljm
Owner
carljm commented Mar 26, 2013

Looking at the code I don't immediately see why this would be the case. If you could provide your sample code as a new (failing) test in the model-utils test suite, that would help in tracking it down.

@blagofofo

Hello, this same issue is still there, extra fields are not retrieved on child models. Any thoughts on how to fix that?

@carljm
Owner
carljm commented Sep 19, 2013

I think this is a consequence of how select_subclasses is implemented. It is just a wrapper around calling select_related with the subclass name and then following the attribute to the subclass instance, which you can do in plain Django. (I.e. instead of select_subclasses('foo') you do select_related('foo') and then parent_obj.foo to get the child Foo class instance.) When you do the latter, you don't expect to find the extra fields on there, as the instance you are getting back wasn't "part" of the original queryset. But when you use select_subclasses your expectations are different, even though what's happening internally is the same, because the child class instance you get back as part of your original queryset with the .extra() call.

So this could be seen as a bug, but in terms of implementation it's really more of a new feature. InheritanceManager would need to introspect the queryset for any .extra() calls, figure out the attribute names that are being added, and then manually copy those attributes over to the child class instance before returning it.

I'd accept a pull request for this, but I'm not likely to work on the implementation myself anytime soon.

@funkybob
Contributor
funkybob commented Jan 8, 2014

Just ran into this... will whip up a PR later today.

@funkybob
Contributor
funkybob commented Jan 8, 2014

Untested : #101

@karoljoc
karoljoc commented Jan 8, 2014

Glad to see some work is being done on this :) Will definitely help with many situations.

ps: funkybob I think there is a typo in your tests "self.assertTrue(all(result.foo == str(result.foo) for result inresults))" where the ending should be "in results" and not "inresults"

@carljm
Owner
carljm commented Jan 26, 2014

Fixed with merge of #101 - thanks @funkybob !

@carljm carljm closed this Jan 26, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment