You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

middleware.py 3.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import zlib
  2. from django.conf import settings
  3. from django.core.exceptions import SuspiciousOperation
  4. from django.db.models import get_model
  5. from oscar.core.loading import import_module
  6. import_module('offer.utils', ['Applicator'], locals())
  7. basket_model = get_model('basket', 'basket')
  8. class BasketMiddleware(object):
  9. cookies_to_delete = []
  10. def process_request(self, request):
  11. manager = basket_model.open
  12. cookie_basket = self.get_cookie_basket(settings.OSCAR_BASKET_COOKIE_OPEN,
  13. request, manager)
  14. if request.user.is_authenticated():
  15. # Signed-in user: if they have a cookie basket too, it means
  16. # that they have just signed in and we need to merge their cookie
  17. # basket into their user basket, then delete the cookie
  18. basket, _ = manager.get_or_create(owner=request.user)
  19. if cookie_basket:
  20. basket.merge(cookie_basket)
  21. self.cookies_to_delete.append(settings.OSCAR_BASKET_COOKIE_OPEN)
  22. elif cookie_basket:
  23. # Anonymous user with a basket tied to the cookie
  24. basket = cookie_basket
  25. else:
  26. # Anonymous user with no basket - we don't save the basket until
  27. # we need to.
  28. basket = basket_model()
  29. # Assign basket object to request
  30. self.apply_offers_to_basket(request, basket)
  31. request.basket = basket
  32. def process_response(self, request, response):
  33. # Delete any surplus cookies
  34. for cookie_key in self.cookies_to_delete:
  35. response.delete_cookie(cookie_key)
  36. # If a basket has had products added to it, but the user is anonymous
  37. # then we need to assign it to a cookie
  38. if hasattr(request, 'basket') and request.basket.id > 0 and not request.user.is_authenticated():
  39. cookie = "%s_%s" % (request.basket.id, self.get_basket_hash(request.basket.id))
  40. response.set_cookie(settings.OSCAR_BASKET_COOKIE_OPEN,
  41. cookie,
  42. max_age=settings.OSCAR_BASKET_COOKIE_LIFETIME,
  43. httponly=True)
  44. return response
  45. def process_template_response(self, request, response):
  46. if response.context_data is None:
  47. response.context_data = {}
  48. response.context_data['basket'] = request.basket
  49. return response
  50. def get_cookie_basket(self, cookie_key, request, manager):
  51. """
  52. Looks for a basket which is referenced by a cookie.
  53. If a cookie key is found with no matching basket, then we add
  54. it to the list to be deleted.
  55. """
  56. basket = None
  57. if cookie_key in request.COOKIES:
  58. basket_id, basket_hash = request.COOKIES[cookie_key].split("_")
  59. if basket_hash == self.get_basket_hash(basket_id):
  60. try:
  61. basket = basket_model.objects.get(pk=basket_id, owner=None)
  62. except basket_model.DoesNotExist:
  63. self.cookies_to_delete.append(cookie_key)
  64. else:
  65. self.cookies_to_delete.append(cookie_key)
  66. return basket
  67. def apply_offers_to_basket(self, request, basket):
  68. if not basket.is_empty:
  69. Applicator().apply(request, basket)
  70. def get_basket_hash(self, basket_id):
  71. return str(zlib.crc32(str(id)+settings.SECRET_KEY))