Skip to content

Conversation

@OskarPersson
Copy link

This is an attempt at adding support for select_related and thus closing #198. So far it has no unit tests or documentation and has mostly been tested with Graphene-Django which is where I found my need for this.

(Getting graphene-django-optimizer to work with this is the next step!)

With my limited testing it seems to work at the first level (e.g. Parent.objects.select_related('childa__related')) but not any deeper than that (e.g. Parent.objects.select_related('childa__related__childb'))

This PR is not in a mergeable state and instead is currently mostly created for bringing the discussion further for implementing select_related with a more complete solution.

@ADR-007
Copy link

ADR-007 commented Mar 21, 2020

You can try something like that:

from typing import List

from polymorphic.models import PolymorphicModel
from polymorphic.query import PolymorphicQuerySet


class SelectRelatedPolymorphicQuerySet(PolymorphicQuerySet):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.used_select_related_cache = False

    def use_select_related(self):
        qs = self._clone()
        qs.used_select_related_cache = True

        return qs

    def _clone(self, *args, **kwargs):
        qs = super()._clone(*args, **kwargs)
        qs.used_select_related_cache = self.used_select_related_cache

        return qs

    def _get_real_instances(self, base_result_objects: List[PolymorphicModel]):
        if self.used_select_related_cache:
            return [item.get_real_instance() for item in base_result_objects]

        return super()._get_real_instances(base_result_objects)
from polymorphic.managers import PolymorphicManager
from polymorphic.models import PolymorphicModel

from vas.utils.models.polymorhic.querysets import SelectRelatedPolymorphicQuerySet


class SelectRelatedPolymorphicModel(PolymorphicModel):
    class Meta:
        abstract = True

    objects = PolymorphicManager.from_queryset(SelectRelatedPolymorphicQuerySet)()

    def get_real_instance(self):
        real_model = self.get_real_instance_class()

        if real_model == self.__class__:
            return self

        # allow to use cache:
        # return getattr(self, real_model.__name__.lower())
        return self._state.fields_cache[real_model.__name__.lower()]  # todo

@bckohan bckohan marked this pull request as draft December 2, 2025 22:33
@codecov
Copy link

codecov bot commented Dec 2, 2025

Codecov Report

❌ Patch coverage is 10.00000% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.21%. Comparing base (9399f7d) to head (f02f609).

Files with missing lines Patch % Lines
src/polymorphic/query.py 10.00% 8 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #395      +/-   ##
==========================================
- Coverage   74.71%   74.21%   -0.50%     
==========================================
  Files          21       21              
  Lines        1337     1346       +9     
  Branches      211      214       +3     
==========================================
  Hits          999      999              
- Misses        261      269       +8     
- Partials       77       78       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bckohan
Copy link
Contributor

bckohan commented Dec 2, 2025

Thanks for this start @OskarPersson!

I am the new leader of this project. It will take me a bit to work through the backlog of issues but this feature is also a desire of mine so I plan to revisit this as time allows. If you want to take another look that would be great too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants