【问题标题】:How use Django Cache in view without cache all page如何在视图中使用 Django Cache 而不缓存所有页面
【发布时间】:2018-02-24 18:06:24
【问题描述】:

我尝试使用 Django Cache 来改善我的观点。效果很好,400 毫秒到 8 毫秒是完美的。但是当用户第一次访问页面时,Django 缓存页面在标题中包含用户信息,当我尝试注销时,页面继续显示用户信息。

我也尝试在模板中使用缓存,但不好,我的问题来自视图,所以继续 400 毫秒。

我的settings.py

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

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

【问题讨论】:

标签: python django caching django-cache django-caching


【解决方案1】:

per-view 缓存也遇到了同样的问题。为所有用户显示第一个缓存用户的用户信息。而且我不能使用Template caching,因为它很慢。

最好的方法是使用low-level cache API 缓存视图的最终结果。如果数据是动态的,则使用django-signals 清除过时的缓存数据。根据您的要求调整以下代码。

观看次数:

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

型号:

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'])

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    按视图缓存将缓存整个视图,因此它非常适合联系页面之类的内容,但不适合具有动态内容的视图。

    听起来template caching 是您需要的。对于模板中可以更改的部分,您可以在{% cache %} 标签中添加一个参数以唯一标识它(来自Django docs):

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

    {% cache %} 标记中的所有内容现在都将按用户缓存,因此您最终不会出现一个用户看到另一个用户的标题的情况。

    【讨论】:

    • 但我的问题来自视图。使用模板缓存继续 400 毫秒。
    • @GuilhermeIA Tirzono 的评论建议通过 AJAX 提取用户信息,这样它就不会与视图的其余部分一起缓存。如果模板缓存还不够,那听起来是最好的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多