Browse Source

Allow chaining of Product's custom querysets

This aligns the implementation of Oscar specific QuerySet Methods with
the implementation in current django core[1].
While this is not DRY, it does deliver on chainability and can be seen
as preparation to take advantage of the improvements coming to this part
of django in 1.7 [2]

The original motivation for this was that using a custom QuerySet while
trying not to copy code from oscar felt too hard.

[1] https://github.com/django/django/blob/1.6.2/django/db/models/manager.py#L123
[2] https://docs.djangoproject.com/en/dev/releases/1.7/#calling-custom-queryset-methods-from-the-manager

Fixes #1278.

Deprecation comments added by @maikhoepfel
master
Jonathan Fiebelkorn 12 years ago
parent
commit
10bfa701f3
1 changed files with 33 additions and 7 deletions
  1. 33
    7
      oscar/apps/catalogue/managers.py

+ 33
- 7
oscar/apps/catalogue/managers.py View File

@@ -1,26 +1,52 @@
1 1
 from django.db import models
2 2
 
3 3
 
4
-class ProductManager(models.Manager):
4
+class ProductQuerySet(models.query.QuerySet):
5 5
 
6 6
     def base_queryset(self):
7 7
         """
8
-        Return ``QuerySet`` with related content pre-loaded.
8
+        Applies select_related and prefetch_related for commonly related
9
+        models to save on queries
9 10
         """
10
-        return self.get_query_set().select_related('product_class')\
11
+        return self.select_related('product_class')\
11 12
             .prefetch_related('variants',
12 13
                               'product_options',
13 14
                               'product_class__options',
14 15
                               'stockrecords',
15 16
                               'images',
16
-                              ).all()
17
+                              )
18
+
19
+    def browsable(self):
20
+        """
21
+        Excludes non-canonical products.
22
+        """
23
+        return self.filter(parent=None)
24
+
25
+
26
+class ProductManager(models.Manager):
27
+    """
28
+    Uses ProductQuerySet and proxies its methods to allow chaining
29
+
30
+    Once Django 1.7 lands, this class can probably be removed:
31
+    https://docs.djangoproject.com/en/dev/releases/1.7/#calling-custom-queryset-methods-from-the-manager  #n oqa
32
+    """
33
+
34
+    def get_queryset(self):
35
+        return ProductQuerySet(self.model, using=self._db)
36
+
37
+    def browsable(self):
38
+        return self.get_queryset().browsable()
39
+
40
+    def base_queryset(self):
41
+        return self.get_queryset().base_queryset()
17 42
 
18 43
 
19 44
 class BrowsableProductManager(ProductManager):
20 45
     """
21 46
     Excludes non-canonical products
47
+
48
+    Could be deprecated after Oscar 0.7 is released
22 49
     """
23 50
 
24
-    def get_query_set(self):
25
-        return super(BrowsableProductManager, self).get_query_set().filter(
26
-            parent=None)
51
+    def get_queryset(self):
52
+        return super(BrowsableProductManager, self).get_queryset().browsable()

Loading…
Cancel
Save