Skip to content

Commit 9cd5200

Browse files
committed
add select_related and partial prefetch_related support
implement support for a single query for select related base fetches across polymorphic models. adds a polymorphic QuerySet Mixin to enable non polymorphic models to fetch related models. Fixes: jazzband#198 jazzband#436 jazzband#359 jazzband#244 Possible Fixes: jazzband#498: support for prefetch_related cannot fetch attributes not on all child models or via class names Related: jazzband#531
1 parent 6990167 commit 9cd5200

File tree

7 files changed

+1401
-261
lines changed

7 files changed

+1401
-261
lines changed

polymorphic/base.py

-11
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ class PolymorphicModelBase(ModelBase):
5757
def __new__(self, model_name, bases, attrs, **kwargs):
5858
# print; print '###', model_name, '- bases:', bases
5959

60-
polymorphic__proxy = None
61-
if "Meta" in attrs:
62-
if hasattr(attrs["Meta"], "polymorphic__proxy"):
63-
polymorphic__proxy = attrs["Meta"].polymorphic__proxy
64-
del attrs["Meta"].polymorphic__proxy
65-
6660
# Workaround compatibility issue with six.with_metaclass() and custom Django model metaclasses:
6761
if not attrs and model_name == "NewBase":
6862
return super().__new__(self, model_name, bases, attrs, **kwargs)
@@ -89,11 +83,6 @@ def __new__(self, model_name, bases, attrs, **kwargs):
8983
# for __init__ function of this class (monkeypatching inheritance accessors)
9084
new_class.polymorphic_super_sub_accessors_replaced = False
9185

92-
if polymorphic__proxy is not None:
93-
new_class._meta.polymorphic__proxy = polymorphic__proxy
94-
else:
95-
new_class._meta.polymorphic__proxy = not new_class._meta.proxy
96-
9786
# determine the name of the primary key field and store it into the class variable
9887
# polymorphic_primary_key_name (it is needed by query.py)
9988
for f in new_class._meta.fields:

polymorphic/managers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def from_queryset(cls, queryset_class, class_name=None):
2828

2929
def get_queryset(self):
3030
qs = self.queryset_class(self.model, using=self._db, hints=self._hints)
31-
if not self.model._meta.polymorphic__proxy:
31+
if self.model._meta.proxy:
3232
qs = qs.instance_of(self.model)
3333
return qs
3434

polymorphic/models.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,18 @@ def __init__(self, *args, **kwargs):
198198
self.__class__.polymorphic_super_sub_accessors_replaced = True
199199

200200
def create_accessor_function_for_model(model, accessor_name):
201+
NOT_PROVIDED = object()
202+
201203
def accessor_function(self):
202-
objects = getattr(model, "_base_objects", model.objects)
203-
attr = objects.get(pk=self.pk)
204+
attr = NOT_PROVIDED
205+
try:
206+
attr = self._state.fields_cache[accessor_name]
207+
pass
208+
except KeyError:
209+
pass
210+
if attr is NOT_PROVIDED:
211+
objects = getattr(model, "_base_objects", model.objects)
212+
attr = objects.get(pk=self.pk)
204213
return attr
205214

206215
return accessor_function

0 commit comments

Comments
 (0)