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.

history.py 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import json
  2. from django.dispatch import receiver
  3. from django.conf import settings
  4. from django.db.models import get_model
  5. from oscar.core.loading import get_class
  6. Product = get_model('catalogue', 'Product')
  7. product_viewed = get_class('catalogue.signals', 'product_viewed')
  8. COOKIE_NAME = 'oscar_history'
  9. MAX_PRODUCTS = settings.OSCAR_RECENTLY_VIEWED_PRODUCTS
  10. def get(request):
  11. """
  12. Return a list of recently viewed products
  13. """
  14. ids = extract(request)
  15. # Reordering as the ID order gets messed up in the query
  16. product_dict = Product.browsable.in_bulk(ids)
  17. ids.reverse()
  18. return [product_dict[id] for id in ids if id in product_dict]
  19. def extract(request, response=None):
  20. """
  21. Extract the IDs of products in the history cookie
  22. """
  23. ids = []
  24. if COOKIE_NAME in request.COOKIES:
  25. try:
  26. ids = json.loads(request.COOKIES[COOKIE_NAME])
  27. except ValueError:
  28. # This can occur if something messes up the cookie
  29. if response:
  30. response.delete_cookie(COOKIE_NAME)
  31. return ids
  32. def add(ids, new_id):
  33. """
  34. Add a new product ID to the list of product IDs
  35. """
  36. if new_id in ids:
  37. ids.remove(new_id)
  38. ids.append(new_id)
  39. if (len(ids) > MAX_PRODUCTS):
  40. ids = ids[len(ids) - MAX_PRODUCTS:]
  41. return ids
  42. def update(product, request, response):
  43. """
  44. Updates the cookies that store the recently viewed products
  45. removing possible duplicates.
  46. """
  47. ids = extract(request, response)
  48. updated_ids = add(ids, product.id)
  49. response.set_cookie(COOKIE_NAME, json.dumps(updated_ids), httponly=True)
  50. # Receivers
  51. @receiver(product_viewed)
  52. def receive_product_view(sender, product, user, request, response, **kwargs):
  53. """
  54. Receiver to handle viewing single product pages
  55. Requires the request and response objects due to dependence on cookies
  56. """
  57. return update(product, request, response)