Browse Source

Speeding up Range.product_queryset() (#4100)

* Update abstract_models.py

Speeding up Range.product_queryset()

* one query less

* exclude parent_excludes query

* revert to previous Version

* save join over parent_excludes

* comment

* Improved readability.

---------

Co-authored-by: Lars van de Kerkhof <lars@permanentmarkers.nl>
master
Gunther Waidacher 1 year ago
parent
commit
8aa90a8cea
No account linked to committer's email address
1 changed files with 30 additions and 18 deletions
  1. 30
    18
      src/oscar/apps/offer/abstract_models.py

+ 30
- 18
src/oscar/apps/offer/abstract_models.py View File

971
                 id__in=self.excluded_products.values("id")
971
                 id__in=self.excluded_products.values("id")
972
             )
972
             )
973
 
973
 
974
+        # start with filter clause that always applies
975
+        _filter = Q(includes=self)
976
+
977
+        # extend filter if included_products have children
978
+        if Product.objects.filter(parent__includes=self).exists():
979
+            _filter |= Q(parent__includes=self)
980
+
981
+        # extend filter if included classes exist:
982
+        if self.classes.exists():
983
+            _filter |= Q(product_class__classes=self)
984
+            # this is always very fast so no check is needed
985
+            _filter |= Q(parent__product_class__classes=self)
986
+
987
+        # extend filter if included_categories exist
974
         if self.included_categories.exists():
988
         if self.included_categories.exists():
975
             expanded_range_categories = ExpandDownwardsCategoryQueryset(
989
             expanded_range_categories = ExpandDownwardsCategoryQueryset(
976
                 self.included_categories.values("id")
990
                 self.included_categories.values("id")
977
             )
991
             )
978
-            selected_products = Product.objects.filter(
979
-                Q(categories__in=expanded_range_categories)
980
-                | Q(product_class__classes=self)
981
-                | Q(includes=self)
982
-                | Q(parent__categories__in=expanded_range_categories)
983
-                | Q(parent__product_class__classes=self)
984
-                | Q(parent__includes=self),
985
-                ~Q(excludes=self),
992
+            _filter |= Q(categories__in=expanded_range_categories)
993
+            # extend filter for parent categories
994
+            if Product.objects.filter(
995
+                    parent__categories__in=expanded_range_categories).exists():
996
+                _filter |= Q(parent__categories__in=expanded_range_categories)
997
+
998
+        qs = Product.objects.filter(
999
+            _filter,
1000
+            ~Q(excludes=self)
1001
+        )
1002
+
1003
+        if Product.objects.filter(parent__excludes=self).exists():
1004
+            qs = qs.filter(
986
                 ~Q(parent__excludes=self)
1005
                 ~Q(parent__excludes=self)
987
             )
1006
             )
988
-        else:
989
-            selected_products = Product.objects.filter(
990
-                Q(product_class__classes=self)
991
-                | Q(includes=self)
992
-                | Q(parent__product_class__classes=self)
993
-                | Q(parent__includes=self),
994
-                ~Q(excludes=self),
995
-                ~Q(parent__excludes=self)
996
-            )
997
-        return selected_products.distinct()
1007
+
1008
+        # make sure to filter out duplicates originating from a join
1009
+        return qs.distinct()
998
 
1010
 
999
     @property
1011
     @property
1000
     def is_editable(self):
1012
     def is_editable(self):

Loading…
Cancel
Save