#Using Django Cache and Signals Setup

6 messages · Page 1 of 1 (latest)

crystal cave
#

Hello, I'm working on integrating Django's cache and signals into my project for the first time, and I want to ensure I'm on the right track. I've set up Redis Cache via Render, where my web service and database are also hosted. I also took note about the limitation of Django's Signal from one of the django users in this channel that shared this article; https://www.django-antipatterns.com/antipattern/signals.html . For my case, I think signals should be fine since I ma not working with ManytoMany relationships

Here's the summary:

What I'm Doing:

  1. Caching Database Queries:
    I cache shoe data with a key "cached_shoe_data", storing JSON representations of shoe objects. If the cache misses, I query the database and update the cache.
    Here's the relevant code in my tools.py:

    # tools.py
    from django.core.cache import cache
    
    @method_tool()
    def get_shoes(self) -> str:
        """Get what shoes are in the database."""
    
        cache_key = "cached_shoe_data"
    
        shoe_data = cache.get(cache_key)
        if shoe_data is not None:
            return shoe_data
    
        shoes = CollectableShoe.objects.all()  # pyright: ignore
        if not shoes:
            return "Empty"
    
        shoe_data_list = []
        for shoe in shoes:
            shoe_info = {
                "brand": shoe.brand,
                "model": shoe.model,
                "color": shoe.color,
                "sku_code": shoe.sku_code,
                "rarity": shoe.rarity,
                "description": shoe.description,
                "collaboration_artist": shoe.collaboration_artist,
                "year_produced": shoe.year_produced,
                "retail_price": float(shoe.retail_price),
                "market_price": float(shoe.market_price),
                "quantity_on_release": shoe.quantity_on_release,
                "size": float(shoe.size),
                "image": shoe.image.url,
            }
            shoe_data_list.append(shoe_info)
        shoe_data = json.dumps(shoe_data_list)
        cache.set(cache_key, shoe_data, timeout=3600)
    
        return shoe_data
    
  2. Signals to Clear Cache:
    I'm using Django signals to delete cached data whenever the CollectableShoe or ShoeDescription models are updated or deleted.

    Here's my signals.py:

    from django.db.models.signals import post_save, post_delete
    from django.dispatch import receiver
    from search_app.models import CollectableShoe, ShoeDescription
    from django.core.cache import cache
    
    @receiver([post_save, post_delete], sender=CollectableShoe)
    def update_retriever_cache(sender, **kwargs):
            cache.delete("cached_shoe_data")
            print("CollectableShoe was updated or deleted")
    

Questions:

  1. How to Confirm Redis Cache is Working?
    I’m hosting Redis via Render. Is there a way to check if the cache is actually being used and the cache keys are being set/deleted properly?

  2. Signal Configuration:
    Does the way I've set up signals look correct? Specifically, am I properly handling multiple senders with this signal setup?

  3. General Feedback:
    Are there better practices or optimizations I should consider when caching or using signals in Django?

Any inputs are appreciated, especially if you’ve worked with Redis Cache and Django signals in production. Thanks in advance!

stone garnet
#

Why do you have to clear the cache using signals?

crystal cave
# stone garnet Why do you have to clear the cache using signals?

Right now, the logic for updating the cache is in the @method_tool() function. If a CollectableShoe is added, updated, or deleted, the cache is cleared by the signal, and the next time someone requests the data, the @method_tool() function queries the database and re-caches it.

#

now that Im thinking about it, clearing the cache and relying on the next request to update it is a bit reactive. I guess i could improve this by moving the cache update logic directly into the signal whenever a change occurs?

#

is that correct thinking here?

cosmic glen
#

Caching is always fun. In terms of checking your redis server, I personally use Another Redis Desktop Manager. This lets me check the redis server with a GUI and i could validate the that my caching is working first thing. Then I would potentially look at maybe a writing a decorator where you would clean the cache on the update/delete view (a signal would work too, but i feel like this adds a layer of abstraction that wouldn't be clear on the views that purge the cache). I'm not sure its worth doing it on a create, as the first request will trigger the cache if you have your settings configured correctly. The delete and updated makes sense (to me anyway) as that is where someone could get an older cache of either deleted data or different data to the DB.