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
 from django.db import models
1
 from django.db import models
2
 
2
 
3
 
3
 
4
-class ProductManager(models.Manager):
4
+class ProductQuerySet(models.query.QuerySet):
5
 
5
 
6
     def base_queryset(self):
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
             .prefetch_related('variants',
12
             .prefetch_related('variants',
12
                               'product_options',
13
                               'product_options',
13
                               'product_class__options',
14
                               'product_class__options',
14
                               'stockrecords',
15
                               'stockrecords',
15
                               'images',
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
 class BrowsableProductManager(ProductManager):
44
 class BrowsableProductManager(ProductManager):
20
     """
45
     """
21
     Excludes non-canonical products
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