4

I trying to use Django Cache to make better my views. Works great, 400ms to 8ms is perfect. But when user access page for the first time, Django cache page with user info in header and when I try log out, page continue with user info.

I try use cache in template too, but isn't good, my problem come from view, so continue 400ms.

My settings.py

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
    }
}

My view.py

@cache_page(60 * 15)
def list(request, tag_slug=None):
    page = request.GET.get('page')
    data = questions_controller.list_questions(request, tag_slug, None, page)
    if data:
        return render(request, 'questions/list.html', data)
    return page_not_found(request, "Page not found")
2
  • 1
    Could you provide some example code of how you are using caching in your current views now? Commented Sep 15, 2017 at 14:01
  • Have a look at this answer: stackoverflow.com/a/11703958/3342089 Commented Sep 15, 2017 at 14:22

2 Answers 2

5

I faced the same problem with per-view caching. User info of the first cached user shows for all users. And I can't use Template caching as it is slow.

Best approach is to cache the final result of the view using low-level cache API. If the data is dynamic then use django-signals to clear the stale cached data. Tweak the below code to your requirement.

Views:

from django.core.cache import cache    
def sample(request):
        cached_data = cache.get_many(['query1', 'query2'])
        if cached_data:
            return render(request, 'sample.html', {'query1': cached_data['query1'], 'query2': cached_data['query2']})
        else:
            queryset1 = Model.objects.all()
            queryset2 = Model2.objects.all()
            cache.set_many({'query1': queryset1 , 'query2': queryset2 }, None)
            return render(request, 'sample.html', {'query1': queryset1 , 'query2': queryset2})

Models:

from django.db.models.signals import post_save
from django.core.cache import cache

@receiver(post_save, sender=Model1)
@receiver(post_save, sender=Model2)
def purge_cache(instance, **kwargs):
    cache.delete_many(['query1', 'query2'])

Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

1

Per-view caching will cache the entire view, so it's a good fit for something like a contact page, but it isn't a good fit for views that have dynamic content.

It sounds like template caching is what you'll need here. For parts of the template that can change, you can add an argument to the {% cache %} tag to uniquely identify it (from the Django docs):

{% load cache %}
{% cache 500 header request.user.username %}
    .. header for logged in user ..
{% endcache %}

Everything in the {% cache %} tag will now be cached per-user so you don't end up with a situation where one user is seeing another user's header.

2 Comments

but my problem come from view. Continue with 400ms using template cache.
@GuilhermeIA The comment from Tirzono suggests pulling in the user information via AJAX so it doesn't get cached with the rest of the view. If template caching isn't sufficient, that sounds like your best bet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.