diff --git a/modelcluster/fields.py b/modelcluster/fields.py index e236280..cc78136 100644 --- a/modelcluster/fields.py +++ b/modelcluster/fields.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +from django import VERSION as DJANGO_VERSION from django.core import checks from django.db import IntegrityError, connections, router from django.db.models import CASCADE @@ -84,7 +85,10 @@ def _apply_rel_filters(self, queryset): # to work correctly with prefetch return queryset._next_is_sticky().all() - def get_prefetch_queryset(self, instances, queryset=None): + def get_prefetch_querysets(self, instances, querysets=None): + if querysets and len(querysets) != 1: + raise ValueError("get_prefetch_querysets() must be passed exactly one queryset") + queryset = querysets[0] if querysets else None if queryset is None: db = self._db or router.db_for_read(self.model, instance=instances[0]) queryset = super().get_queryset().using(db) @@ -103,6 +107,13 @@ def get_prefetch_queryset(self, instances, queryset=None): cache_name = rel_field.related_query_name() return qs, rel_obj_attr, instance_attr, False, cache_name, False + # Remove once we only support Django 5.0+ + if not DJANGO_VERSION >= (5, 0): + def get_prefetch_queryset(self, instances, queryset=None): + if queryset is None: + return self.get_prefetch_querysets(instances) + return self.get_prefetch_querysets(instances, querysets=[queryset]) + def get_object_list(self): """ return the mutable list that forms the current in-memory state of @@ -338,8 +349,11 @@ def get_queryset(self): return FakeQuerySet(rel_model, results) - def get_prefetch_queryset(self, instances, queryset=None): + def get_prefetch_querysets(self, instances, querysets=None): # Derived from Django's ManyRelatedManager.get_prefetch_queryset. + if querysets and len(querysets) != 1: + raise ValueError("get_prefetch_querysets() must be passed exactly one queryset") + queryset = querysets[0] if querysets else None if queryset is None: queryset = super().get_queryset() @@ -374,6 +388,13 @@ def get_prefetch_queryset(self, instances, queryset=None): False, ) + # Remove once we only support Django 5.0+ + if not DJANGO_VERSION >= (5, 0): + def get_prefetch_queryset(self, instances, queryset=None): + if queryset is None: + return self.get_prefetch_querysets(instances) + return self.get_prefetch_querysets(instances, querysets=[queryset]) + def _apply_rel_filters(self, queryset): # Required for get_prefetch_queryset. return queryset._next_is_sticky()