Pārlūkot izejas kodu

Improved basket usage.

* Less DB queries
* Added basic tests
master
David Winterbottom 13 gadus atpakaļ
vecāks
revīzija
369fa8e828

+ 7
- 3
oscar/apps/basket/abstract_models.py Parādīt failu

@@ -63,6 +63,8 @@ class AbstractBasket(models.Model):
63 63
         This is important for offers as they alter the line models and you don't
64 64
         want to reload them from the DB.
65 65
         """
66
+        if self.id is None:
67
+            return []
66 68
         if self._lines is None:
67 69
             self._lines = self.lines.all()
68 70
         return self._lines
@@ -237,8 +239,10 @@ class AbstractBasket(models.Model):
237 239
 
238 240
     @property
239 241
     def is_empty(self):
240
-        """Return bool based on basket having 0 lines"""
241
-        return self.num_lines == 0
242
+        """
243
+        Test if this basket is empty
244
+        """
245
+        return self.id is None or self.num_lines == 0
242 246
 
243 247
     @property
244 248
     def total_excl_tax(self):
@@ -319,7 +323,7 @@ class AbstractBasket(models.Model):
319 323
     @property
320 324
     def num_lines(self):
321 325
         """Return number of lines"""
322
-        return self.all_lines().count()
326
+        return len(self.all_lines())
323 327
 
324 328
     @property
325 329
     def num_items(self):

+ 8
- 8
oscar/apps/basket/middleware.py Parādīt failu

@@ -13,7 +13,7 @@ Basket = get_model('basket', 'basket')
13 13
 class BasketMiddleware(object):
14 14
 
15 15
     def process_request(self, request):
16
-        self.cookies_to_delete = []
16
+        request.cookies_to_delete = []
17 17
         basket = self.get_basket(request)
18 18
         self.apply_offers_to_basket(request, basket)
19 19
         request.basket = basket
@@ -23,7 +23,7 @@ class BasketMiddleware(object):
23 23
         cookie_basket = self.get_cookie_basket(settings.OSCAR_BASKET_COOKIE_OPEN,
24 24
                                                request, manager)
25 25
 
26
-        if request.user.is_authenticated():
26
+        if hasattr(request, 'user') and request.user.is_authenticated():
27 27
             # Signed-in user: if they have a cookie basket too, it means
28 28
             # that they have just signed in and we need to merge their cookie
29 29
             # basket into their user basket, then delete the cookie
@@ -31,7 +31,7 @@ class BasketMiddleware(object):
31 31
                 basket, _ = manager.get_or_create(owner=request.user)
32 32
             except Basket.MultipleObjectsReturned:
33 33
                 # Not sure quite how we end up here with multiple baskets
34
-                # We merge any  them and create a fresh one
34
+                # We merge them and create a fresh one
35 35
                 old_baskets = list(manager.filter(owner=request.user))
36 36
                 basket = old_baskets[0]
37 37
                 for other_basket in old_baskets[1:]:
@@ -39,7 +39,7 @@ class BasketMiddleware(object):
39 39
 
40 40
             if cookie_basket:
41 41
                 self.merge_baskets(basket, cookie_basket)
42
-                self.cookies_to_delete.append(settings.OSCAR_BASKET_COOKIE_OPEN)
42
+                request.cookies_to_delete.append(settings.OSCAR_BASKET_COOKIE_OPEN)
43 43
         elif cookie_basket:
44 44
             # Anonymous user with a basket tied to the cookie
45 45
             basket = cookie_basket
@@ -59,8 +59,8 @@ class BasketMiddleware(object):
59 59
 
60 60
     def process_response(self, request, response):
61 61
         # Delete any surplus cookies
62
-        if hasattr(self, 'cookies_to_delete'):
63
-            for cookie_key in self.cookies_to_delete:
62
+        if hasattr(request, 'cookies_to_delete'):
63
+            for cookie_key in request.cookies_to_delete:
64 64
                 response.delete_cookie(cookie_key)
65 65
 
66 66
         # If a basket has had products added to it, but the user is anonymous
@@ -100,9 +100,9 @@ class BasketMiddleware(object):
100 100
                     basket = Basket.objects.get(pk=basket_id, owner=None,
101 101
                                                 status=OPEN)
102 102
                 except Basket.DoesNotExist:
103
-                    self.cookies_to_delete.append(cookie_key)
103
+                    request.cookies_to_delete.append(cookie_key)
104 104
             else:
105
-                self.cookies_to_delete.append(cookie_key)
105
+                request.cookies_to_delete.append(cookie_key)
106 106
         return basket
107 107
 
108 108
     def apply_offers_to_basket(self, request, basket):

+ 1
- 1
oscar/templates/oscar/partials/nav_alternate.html Parādīt failu

@@ -11,7 +11,7 @@
11 11
             </a>
12 12
             <a class="btn btn-navbar app-ico ico_shop_bag btn-cart hidden" href="{% url checkout:index %}">
13 13
 				<strong>{% trans "Basket" %}
14
-                {% if request.basket.lines.count %}
14
+                {% if not request.basket.is_empty %}
15 15
 				{% trans "Total:" %} {{ basket.total_incl_tax|currency }}
16 16
                 {% endif %}
17 17
                 </strong>

+ 25
- 15
tests/unit/basket_tests.py Parādīt failu

@@ -1,39 +1,49 @@
1 1
 import datetime
2 2
 
3 3
 from django.test import TestCase
4
+from django.test.client import RequestFactory
4 5
 
5
-from oscar.apps.basket.models import Basket, Line
6
+from oscar.apps.basket.models import Basket
7
+from oscar.apps.basket.middleware import BasketMiddleware
6 8
 from oscar.test.helpers import create_product
7 9
 from oscar.apps.basket.reports import (
8 10
     OpenBasketReportGenerator, SubmittedBasketReportGenerator)
9 11
 
10 12
 
11
-class BasketModelTest(TestCase):
13
+class TestBasketModel(TestCase):
12 14
 
13 15
     def setUp(self):
14 16
         self.basket = Basket.objects.create()
15
-        self.dummy_product = create_product()
17
+        self.product = create_product()
16 18
 
17
-    def test_empty_baskets_have_zero_lines(self):
18
-        self.assertTrue(Basket().num_lines == 0)
19
+    def test_an_empty_basket_has_zero_lines(self):
20
+        self.assertEqual(0, self.basket.num_lines)
19 21
 
20 22
     def test_new_baskets_are_empty(self):
21
-        self.assertTrue(Basket().is_empty)
23
+        self.assertTrue(self.basket.is_empty)
22 24
 
23
-    def test_basket_have_with_one_line(self):
24
-        Line.objects.create(basket=self.basket, product=self.dummy_product)
25
-        self.assertTrue(self.basket.num_lines == 1)
26
-
27
-    def test_add_product_creates_line(self):
28
-        self.basket.add_product(self.dummy_product)
29
-        self.assertTrue(self.basket.num_lines == 1)
25
+    def test_adding_product_creates_line(self):
26
+        self.basket.add_product(self.product)
27
+        self.assertEqual(1, self.basket.num_lines)
30 28
 
31 29
     def test_adding_multiproduct_line_returns_correct_number_of_items(self):
32
-        self.basket.add_product(self.dummy_product, 10)
30
+        self.basket.add_product(self.product, 10)
33 31
         self.assertEqual(self.basket.num_items, 10)
32
+        self.assertEqual(self.basket.num_lines, 1)
33
+
34
+
35
+class TestBasketMiddleware(TestCase):
36
+
37
+    def setUp(self):
38
+        self.middleware = BasketMiddleware()
39
+
40
+    def test_basket_is_attached_to_request(self):
41
+        req = RequestFactory().get('/')
42
+        self.middleware.process_request(req)
43
+        self.assertTrue(hasattr(req, 'basket'))
34 44
 
35 45
 
36
-class BasketReportTests(TestCase):
46
+class TestBasketReports(TestCase):
37 47
 
38 48
     def test_open_report_doesnt_error(self):
39 49
         data = {

Notiek ielāde…
Atcelt
Saglabāt