GeeWee / django-auto-prefetching

Automatic prefetching for Django
MIT License
231 stars 18 forks source link

Add overridable method get_prefetchable_queryset to allow complex querysets #51

Closed FelipeSanchezCalzada closed 1 year ago

FelipeSanchezCalzada commented 1 year ago

This allows you to override get_prefetchable_queryset to create complex querysets.

Sometimes queryset = Model.objects.all() not enough and this is a very simple way to support complex querysets.

If there is any trick to do this in a simple way I can remove this PR and use the suggested approach, but this seems like a clean way to me.

You can change the name of the overridable method if you don't like the one I suggested.

Thanks, I'm waiting for news

GeeWee commented 1 year ago

I'm curious, what sort of usecases does this solve that you can't do by overriding get_queryset and calling prefetch?

    def get_queryset(self):
        # Simply do the extra select_related / prefetch_related here
        # and leave the mixin to do the rest of the work
        queryset = YourModel.objects.all()
        queryset = queryset.select_related('my_extra_field')
        return django_auto_prefetching.prefetch(queryset, self.serializer_class)
FelipeSanchezCalzada commented 1 year ago

In that case you will have to manually add to support all other overridable methods:

        kwargs = {
            "excluded_fields": self.get_auto_prefetch_excluded_fields(),
            "extra_select_fields": self.get_auto_prefetch_extra_select_fields(),
            "extra_prefetch_fields": self.get_auto_prefetch_extra_prefetch_fields(),
        }

In full example:

    def get_queryset(self):
        # Simply do the extra select_related / prefetch_related here
        # and leave the mixin to do the rest of the work
        queryset = YourModel.objects.all()
        queryset = queryset.select_related('my_extra_field')
        kwargs = {
            "excluded_fields": self.get_auto_prefetch_excluded_fields(),
            "extra_select_fields": self.get_auto_prefetch_extra_select_fields(),
            "extra_prefetch_fields": self.get_auto_prefetch_extra_prefetch_fields(),
        }
        return django_auto_prefetching.prefetch(queryset, self.serializer_class, **kwargs)

I don't like the idea of ​​having to add all that code because of overriding get_queryset(). My idea would be similar to how the DRF creators added perform_create() in addition to create() to give even more flexibility and avoid redundant code.

Thank you very much for your quick review.

GeeWee commented 1 year ago

Yeah that's fair enough. I don't do much maintenance of this package anymore, but if you write a test exercising how it would work overriding the new method and update the documentation I'd be happy to accept it :)

FelipeSanchezCalzada commented 1 year ago

Done, thanks for the review!

GeeWee commented 1 year ago

Released in 0.2.12