From f010c6ddf71e7d68e9895196fae7ab92ee80b3d0 Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Wed, 12 Apr 2017 23:52:06 +0100 Subject: [PATCH 1/2] Get tests running on django 1.11 I'm a little concerned that this loses some of the efficiencies (in particular, chunking) from previous versions. That's something that can probably be improved. --- polymorphic/query.py | 98 +++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/polymorphic/query.py b/polymorphic/query.py index c842414..fb1dfa8 100644 --- a/polymorphic/query.py +++ b/polymorphic/query.py @@ -25,6 +25,25 @@ except ImportError: Polymorphic_QuerySet_objects_per_request = CHUNK_SIZE +if django.VERSION >= (1, 9): + # We ignore this on django < 1.9, as ModelIterable didn't yet exist. + from django.db.models.query import ModelIterable + + + class PolymorphicModelIterable(ModelIterable): + def __iter__(self): + base_iter = super(PolymorphicModelIterable, self).__iter__() + + if self.queryset.polymorphic_disabled: + for o in base_iter: + yield o + return + + real_instances = self.queryset._get_real_instances(base_iter) + for obj in real_instances: + yield obj + + def transmogrify(cls, obj): """ Upcast a class to a different type without asking questions. @@ -72,6 +91,9 @@ class PolymorphicQuerySet(QuerySet): # to that queryset as well). self.polymorphic_deferred_loading = (set([]), True) super(PolymorphicQuerySet, self).__init__(*args, **kwargs) + if django.VERSION >= (1, 9): + # On django < 1.9 we override the iterator() method instead + self._iterable_class = PolymorphicModelIterable def _clone(self, *args, **kwargs): # Django's _clone only copies its own variables, so we need to copy ours here @@ -407,49 +429,51 @@ class PolymorphicQuerySet(QuerySet): return resultlist - def iterator(self): - """ - This function is used by Django for all object retrieval. - By overriding it, we modify the objects that this queryset returns - when it is evaluated (or its get method or other object-returning methods are called). + if django.VERSION < (1, 9): + # On django 1.9+, we can define self._iterator_class instead of iterator() + def iterator(self): + """ + This function is used by Django for all object retrieval. + By overriding it, we modify the objects that this queryset returns + when it is evaluated (or its get method or other object-returning methods are called). - Here we do the same as:: + Here we do the same as:: - base_result_objects = list(super(PolymorphicQuerySet, self).iterator()) - real_results = self._get_real_instances(base_result_objects) - for o in real_results: yield o + base_result_objects = list(super(PolymorphicQuerySet, self).iterator()) + real_results = self._get_real_instances(base_result_objects) + for o in real_results: yield o - but it requests the objects in chunks from the database, - with Polymorphic_QuerySet_objects_per_request per chunk - """ - base_iter = super(PolymorphicQuerySet, self).iterator() + but it requests the objects in chunks from the database, + with Polymorphic_QuerySet_objects_per_request per chunk + """ + base_iter = super(PolymorphicQuerySet, self).iterator() - # disabled => work just like a normal queryset - if self.polymorphic_disabled: - for o in base_iter: - yield o - return - - while True: - base_result_objects = [] - reached_end = False - - for i in range(Polymorphic_QuerySet_objects_per_request): - try: - o = next(base_iter) - base_result_objects.append(o) - except StopIteration: - reached_end = True - break - - real_results = self._get_real_instances(base_result_objects) - - for o in real_results: - yield o - - if reached_end: + # disabled => work just like a normal queryset + if self.polymorphic_disabled: + for o in base_iter: + yield o return + while True: + base_result_objects = [] + reached_end = False + + for i in range(Polymorphic_QuerySet_objects_per_request): + try: + o = next(base_iter) + base_result_objects.append(o) + except StopIteration: + reached_end = True + break + + real_results = self._get_real_instances(base_result_objects) + + for o in real_results: + yield o + + if reached_end: + return + def __repr__(self, *args, **kwargs): if self.model.polymorphic_query_multiline_output: result = [repr(o) for o in self.all()] From 64325d0f9945c16507d42a233f66cf67cd3a6796 Mon Sep 17 00:00:00 2001 From: Charlie Denton Date: Thu, 13 Apr 2017 00:18:31 +0100 Subject: [PATCH 2/2] Do not allow failures on django 1.11 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index be2fa59..175a66b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -90,7 +90,6 @@ matrix: - python: "2.6" env: DJANGO="https://github.com/django/django/tarball/master" allow_failures: - - env: DJANGO="Django>=1.11,<1.12" - env: DJANGO="https://github.com/django/django/tarball/master" before_install: