How use Django Cache in view without cache all page

你。 提交于 2020-06-26 14:43:47

问题


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")

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/46241407/how-use-django-cache-in-view-without-cache-all-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!