Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prefetch_definitions aren't preserved across an FK reverse relationship #8

Open
gavinwahl opened this issue Oct 18, 2013 · 2 comments

Comments

@gavinwahl
Copy link

Given these models:

class User(Model):
    pass

class UserThing(Model):
    user = ForiegnKey(User, related_name='things')

    objects = PrefetchManager(
        # prefetches here...
    )

I'd like to be able to be able to do user.things.prefetch('stuff'). PrefetchManagerMixin does set use_for_related_fields, so user.things is a PrefetchManager, but it doesn't have any prefetch_definitions. This is because Django only uses the class of the manager to create its RelatedManager. See ForeignRelatedObjectsDescriptor.related_manager_cls.

One way to solve this issue would be to have a class factory that returned PrefetchManager classes with prefetch_definitions already set. If this isn't feasible, a way to reduce the impact would be to allow PrefetchQuerySet.prefetch to take a Prefetcher. This way you could use the actual Prefetcher instance instead of a name when the table of names isn't available.

If either of these solutions sound interesting, let me know and I can write a patch.

@ionelmc
Copy link
Owner

ionelmc commented Oct 18, 2013

Note that I haven't tried but this should do the trick (if django works as you describe)

class User(Model):
    pass
class UserThingPrefetchManager(PrefetchManager):
    prefetch_definitions = dict(
        # prefetches here...
    )
class UserThing(Model):
    user = ForiegnKey(User, related_name='things')

    objects = UserThingPrefetchManager()

@ionelmc
Copy link
Owner

ionelmc commented Oct 18, 2013

On second thought you have to subclass the mixin as the initializer in PrefetchManager will just empty the prefetch_definitions. Eg:

class UserThingPrefetchManager(PrefetchManagerMixin):
    prefetch_definitions = dict(
        # prefetches here...
    )

But a class factory would be more useful (it's not obvious that you need a class definition like that). However, that presents its own challenge as the class would be non-pickleable if it's not defined at module level (you can always patch the module with the anonymous class that the factory would return by looking at stackframes but that's ugly).

What do you think ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants