Skip to content

Commit

Permalink
fix caching issues for criteria; fix tests - added trailing slash
Browse files Browse the repository at this point in the history
  • Loading branch information
pigletto committed Feb 17, 2017
1 parent df703e8 commit aaad9f3
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 78 deletions.
165 changes: 89 additions & 76 deletions lfs/caching/listeners.py
Expand Up @@ -9,7 +9,7 @@
from django.db.models.signals import pre_delete

# lfs imports
from lfs.caching.utils import clear_cache, invalidate_cache_group_id
from lfs.caching.utils import clear_cache, delete_cache, invalidate_cache_group_id
from lfs.cart.models import Cart
from lfs.catalog.models import Category
from lfs.catalog.models import Product
Expand All @@ -21,7 +21,8 @@
from lfs.core.signals import shop_changed
from lfs.core.signals import topseller_changed
from lfs.core.signals import manufacturer_changed
from lfs.criteria.models import CountryCriterion
from lfs.criteria.models import CountryCriterion, Criterion, WeightCriterion, WidthCriterion, ShippingMethodCriterion, \
PaymentMethodCriterion, LengthCriterion, HeightCriterion, CombinedLengthAndGirthCriterion, CartPriceCriterion
from lfs.customer_tax.models import CustomerTax
from lfs.marketing.models import Topseller
from lfs.order.models import OrderItem
Expand Down Expand Up @@ -73,26 +74,22 @@ def product_categories_changed_listener(sender, **kwargs):

if reverse:
product = instance
cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
cache.delete(cache_key)
cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
cache.delete(cache_key)
delete_cache("%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True))
delete_cache("%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False))
else:
if pk_set:
for product in Product.objects.filter(pk__in=pk_set):
cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True)
cache.delete(cache_key)
cache_key = "%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False)
cache.delete(cache_key)
delete_cache("%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, True))
delete_cache("%s-product-categories-%s-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, product.id, False))
m2m_changed.connect(product_categories_changed_listener, sender=Category.products.through)


# Manufacturer
def manufacturer_changed_listener(sender, **kwargs):
# filtered lists of products assigned to manufacturer used at manufacturer page
cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
delete_cache("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.slug))
# list of all manufacturer products
cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
delete_cache("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, sender.pk))
# if manufacturer assignment was changed then product navigation might be different too
invalidate_cache_group_id('product_navigation')
manufacturer_changed.connect(manufacturer_changed_listener)
Expand All @@ -104,10 +101,10 @@ def order_item_listener(sender, instance, **kwargs):
calculated automatically on base of OrderItems, hence we have to take of
that.
"""
cache.delete("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
try:
for category in instance.product.get_categories(with_parents=True):
cache.delete("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))
delete_cache("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))
except:
pass # fail silently
pre_delete.connect(order_item_listener, sender=OrderItem)
Expand All @@ -116,8 +113,8 @@ def order_item_listener(sender, instance, **kwargs):

# Page
def page_saved_listener(sender, instance, **kwargs):
cache.delete("%s-page-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
cache.delete("%s-pages" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-page-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-pages" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
post_save.connect(page_saved_listener, sender=Page)


Expand All @@ -142,40 +139,34 @@ def product_pre_saved_listener(sender, instance, **kwargs):
else:
parent = instance

cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id)
cache.delete(cache_key)
cache_key_hash = hashlib.md5(cache_key).hexdigest()
cache.delete(cache_key_hash)
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))

try:
old_product = Product.objects.get(pk=parent.pk)
except Product.DoesNotExist:
pass
else:
cache_key = "%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, old_product.slug)
cache.delete(cache_key)
cache_key_hash = hashlib.md5(cache_key).hexdigest()
cache.delete(cache_key_hash)
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, old_product.slug))

pre_save.connect(product_pre_saved_listener, sender=Product)


# Shipping Method
def shipping_method_saved_listener(sender, instance, **kwargs):
cache.delete("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
cache.delete("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
cache.delete("all_active_shipping_methods")
delete_cache("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("all_active_shipping_methods")
post_save.connect(shipping_method_saved_listener, sender=ShippingMethod)


def shipping_method_deleted_listener(sender, instance, **kwargs):
cache.delete("all_active_shipping_methods")
delete_cache("all_active_shipping_methods")
post_delete.connect(shipping_method_deleted_listener, sender=ShippingMethod)


# Shop
def shop_saved_listener(sender, instance, **kwargs):
cache.delete("%s-shop-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-shop-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
post_save.connect(shop_saved_listener, sender=Shop)


Expand Down Expand Up @@ -207,33 +198,31 @@ def review_added_listener(sender, **kwargs):
def criterion_countries_changed(sender, instance, action, reverse, model, pk_set, **kwargs):
if action in ('post_add', 'post_remove', 'post_clear'):
if not reverse:
cache_key = u'country_values_{}'.format(instance.pk)
cache.delete(cache_key)
delete_cache(u'country_values_{}'.format(instance.pk))
else:
for pk in pk_set:
cache_key = u'country_values_{}'.format(pk)
cache.delete(cache_key)
delete_cache(u'country_values_{}'.format(pk))
m2m_changed.connect(criterion_countries_changed, sender=CountryCriterion.value.through)


def customer_tax_created_listener(sender, instance, created, **kwargs):
if created:
cache.delete(u'all_customer_taxes')
delete_cache(u'all_customer_taxes')
post_save.connect(customer_tax_created_listener, sender=CustomerTax)


def customer_tax_deleted_listener(sender, instance, **kwargs):
cache.delete(u'all_customer_taxes')
delete_cache(u'all_customer_taxes')
post_delete.connect(customer_tax_deleted_listener, sender=CustomerTax)


def tax_rate_created_listener(sender, instance, created, **kwargs):
cache.delete(u'tax_rate_{}'.format(instance.pk))
delete_cache(u'tax_rate_{}'.format(instance.pk))
post_save.connect(tax_rate_created_listener, sender=Tax)


def tax_rate_deleted_listener(sender, instance, **kwargs):
cache.delete(u'tax_rate_{}'.format(instance.pk))
delete_cache(u'tax_rate_{}'.format(instance.pk))
post_delete.connect(tax_rate_deleted_listener, sender=Tax)


Expand All @@ -245,22 +234,22 @@ def update_category_cache(instance):
# (1000s) and the shop admin changes a category.
clear_cache()
return
cache.delete("%s-category-breadcrumbs-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
cache.delete("%s-category-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
cache.delete("%s-category-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
cache.delete("%s-category-categories-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-category-breadcrumbs-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-category-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-category-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-category-categories-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))

for category in Category.objects.all():
cache.delete("%s-categories-portlet-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.slug))
delete_cache("%s-categories-portlet-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.slug))

cache.delete("%s-category-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-category-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))
delete_cache("%s-category-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.slug))

cache.delete("%s-category-all-children-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-category-children-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-category-parents-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-category-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-category-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-all-children-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-children-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-parents-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-category-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))

# Note: As this is called "pre-saved" newly created categories don't have
# the many-to-many attribute "products", hence we have to take care of it
Expand All @@ -283,16 +272,16 @@ def update_product_cache(instance):
# if product was changed then we have to clear all product_navigation caches
invalidate_cache_group_id('product_navigation')
invalidate_cache_group_id('properties-%s' % parent.id)
cache.delete("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
cache.delete("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
cache.delete("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
cache.delete("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
cache.delete("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
cache.delete("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
cache.delete("%s-default-variant-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
delete_cache("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
delete_cache("%s-default-variant-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.id))
if parent.manufacturer:
cache.delete("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.pk))
cache.delete("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.slug))
delete_cache("%s-manufacturer-all-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.pk))
delete_cache("%s-manufacturer-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.manufacturer.slug))

try:
c = cache.get("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
Expand All @@ -302,42 +291,66 @@ def update_product_cache(instance):
pass

for variant in parent.get_variants():
cache.delete("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
cache.delete("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
cache.delete("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
cache.delete("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
cache.delete("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
cache.delete("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
cache.delete("%s-product-shipping-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.slug))
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
delete_cache("%s-product-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, parent.slug))
delete_cache("%s-product-images-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
delete_cache("%s-related-products-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
delete_cache("%s-product-categories-%s-False" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
delete_cache("%s-product-categories-%s-True" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.id))
delete_cache("%s-product-shipping-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, variant.slug))


def update_cart_cache(instance):
"""Deletes all cart relevant caches.
"""
if instance.user:
cache.delete("%s-cart-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.user.pk))
delete_cache("%s-cart-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.user.pk))

cache.delete("%s-cart-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.session))
cache.delete("%s-cart-items-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-cart-costs-True-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-cart-costs-False-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
cache.delete("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
cache.delete("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-cart-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.session))
delete_cache("%s-cart-items-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-cart-costs-True-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-cart-costs-False-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-shipping-delivery-time-cart" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-shipping-delivery-time" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)


def update_static_block_cache(instance):
"""Deletes all static block relevant caches.
"""
cache.delete("%s-static-block-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))
delete_cache("%s-static-block-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, instance.id))

for category in instance.categories.all():
cache.delete("%s-category-inline-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.slug))
delete_cache("%s-category-inline-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.slug))


def update_topseller_cache(topseller):
"""Deletes all topseller relevant caches.
"""
cache.delete("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
delete_cache("%s-topseller" % settings.CACHE_MIDDLEWARE_KEY_PREFIX)
product = topseller.product
for category in product.get_categories(with_parents=True):
cache.delete("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))
delete_cache("%s-topseller-%s" % (settings.CACHE_MIDDLEWARE_KEY_PREFIX, category.id))


def clear_criterion_cache(sender, instance, created, **kwargs):
cache_key = u'criteria_for_model_{}_{}'.format(instance.content_id, instance.content_type.pk)
cache.delete(cache_key)
post_save.connect(clear_criterion_cache, sender=WeightCriterion)
post_save.connect(clear_criterion_cache, sender=CartPriceCriterion)
post_save.connect(clear_criterion_cache, sender=CombinedLengthAndGirthCriterion)
post_save.connect(clear_criterion_cache, sender=CountryCriterion)
post_save.connect(clear_criterion_cache, sender=HeightCriterion)
post_save.connect(clear_criterion_cache, sender=LengthCriterion)
post_save.connect(clear_criterion_cache, sender=PaymentMethodCriterion)
post_save.connect(clear_criterion_cache, sender=ShippingMethodCriterion)
post_save.connect(clear_criterion_cache, sender=WidthCriterion)

pre_delete.connect(clear_criterion_cache, sender=WeightCriterion)
pre_delete.connect(clear_criterion_cache, sender=CartPriceCriterion)
pre_delete.connect(clear_criterion_cache, sender=CombinedLengthAndGirthCriterion)
pre_delete.connect(clear_criterion_cache, sender=CountryCriterion)
pre_delete.connect(clear_criterion_cache, sender=HeightCriterion)
pre_delete.connect(clear_criterion_cache, sender=LengthCriterion)
pre_delete.connect(clear_criterion_cache, sender=PaymentMethodCriterion)
pre_delete.connect(clear_criterion_cache, sender=ShippingMethodCriterion)
pre_delete.connect(clear_criterion_cache, sender=WidthCriterion)
5 changes: 5 additions & 0 deletions lfs/caching/utils.py
Expand Up @@ -119,6 +119,11 @@ def clear_cache():
pass


def delete_cache(cache_key):
cache.delete(cache_key)
cache.delete(hashlib.md5(cache_key).hexdigest())


def get_cache_group_id(group_code):
""" Get id for group_code that is stored in cache. This id is supposed to be included in cache key for all items
from specific group.
Expand Down
2 changes: 1 addition & 1 deletion lfs/catalog/tests.py
Expand Up @@ -914,7 +914,7 @@ def test_get_format_info(self):
def test_get_absolute_url(self):
"""
"""
self.assertEqual(self.c1.get_absolute_url(), "/category-%s" % self.c1.slug)
self.assertEqual(self.c1.get_absolute_url(), "/category-%s/" % self.c1.slug)

def test_unicode(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion lfs/checkout/tests/test_checkout.py
Expand Up @@ -213,7 +213,7 @@ def test_checkout_country_after_cart_country_change(self):

# change the country in the cart
de = Country.objects.get(code="de")
cart_response = self.client.post('/refresh-cart', {'country': de.code.lower(), "amount-cart-item_%s" % self.item1.id: 1, "amount-cart-item_%s" % self.item2.id: 1})
cart_response = self.client.post(reverse('lfs_refresh_cart'), {'country': de.code.lower(), "amount-cart-item_%s" % self.item1.id: 1, "amount-cart-item_%s" % self.item2.id: 1})

customer = Customer.objects.get(user=user)
self.assertEquals(customer.selected_shipping_address.country.code.lower(), "de")
Expand Down

0 comments on commit aaad9f3

Please sign in to comment.