找回密码
 立即注册
首页 业界区 安全 Django缓存

Django缓存

赶塑坠 2025-9-30 11:26:49
Django提供了强大的缓存框架,可以帮助你提高网站性能。
1、缓存配置

Django 支持多种缓存后端,你可以根据项目规模、性能需求和基础设施来灵活选择。配置在 settings.py的 CACHES设置中完成
  1. # settings.py
  2. CACHES = {
  3.     'default': {
  4.         'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
  5.         'LOCATION': 'unique-snowflake',
  6.         'TIMEOUT': 300,  # 默认缓存时间(秒),None 表示永不过期,0 表示立即过期
  7.         'OPTIONS': {
  8.             'MAX_ENTRIES': 1000,  # 最大缓存条目数
  9.             'CULL_FREQUENCY': 3,  # 当达到 MAX_ENTRIES 时删除 1/CULL_FREQUENCY 的缓存
  10.         },
  11.         'KEY_PREFIX': 'myapp_',  # 所有缓存键的前缀
  12.         'VERSION': 1,  # 默认缓存版本
  13.     }
  14. }
复制代码
支持的缓存后端
  1. # 内存缓存(开发环境常用)
  2. 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
  3. # 文件系统缓存
  4. 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache'
  5. 'LOCATION': '/var/tmp/django_cache'
  6. # 数据库缓存
  7. 'BACKEND': 'django.core.cache.backends.db.DatabaseCache' # python manage.py createcachetable [table_name]  # table_name 是配置中 LOCATION 的值
  8. 'LOCATION': 'my_cache_table'
  9. # Memcached
  10. 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache'
  11. 'LOCATION': '127.0.0.1:11211'
  12. # Redis(需要 django-redis 包)
  13. 'BACKEND': 'django_redis.cache.RedisCache'
  14. 'LOCATION': 'redis://127.0.0.1:6379/1'
复制代码
2、缓存API使用

2.1 常见语法
  1. from django.core.cache import cache
  2. # 设置缓存
  3. cache.set('my_key', 'hello, world!', 30)  # 缓存30秒
  4. # 获取缓存
  5. value = cache.get('my_key')
  6. print(value)  # 输出: hello, world!
  7. # 如果键不存在,返回默认值
  8. value = cache.get('my_key', 'default_value')
  9. # 添加缓存(仅当键不存在时)
  10. cache.add('add_key', 'new_value')
  11. # 获取或设置缓存
  12. value = cache.get_or_set('my_key', 'default_value', 30)
  13. # 删除缓存
  14. cache.delete('my_key')
  15. # 清空所有缓存
  16. cache.clear()
  17. # 自增/自减(针对数字)
  18. cache.set('num', 1)
  19. cache.incr('num')  # 2
  20. cache.decr('num')  # 1
  21. # 设置多个值
  22. cache.set_many({'a': 1, 'b': 2, 'c': 3})
  23. # 获取多个值
  24. values = cache.get_many(['a', 'b', 'c'])  # {'a': 1, 'b': 2, 'c': 3}
  25. # 删除多个值
  26. cache.delete_many(['a', 'b', 'c'])
复制代码
2.2 基本使用

2.2.1 缓存数据库查询结果
  1. from django.core.cache import cache
  2. from myapp.models import Product
  3. def get_popular_products():
  4.     # 尝试从缓存获取
  5.     cache_key = 'popular_products'
  6.     products = cache.get(cache_key)
  7.    
  8.     if products is None:
  9.         # 缓存中没有,从数据库获取
  10.         products = list(Product.objects.filter(
  11.             is_popular=True
  12.         ).select_related('category')[:10])
  13.         
  14.         # 存入缓存,1小时过期
  15.         cache.set(cache_key, products, 60 * 60)
  16.    
  17.     return products
复制代码
2.2.2 缓存模板渲染结果
  1. from django.core.cache import cache
  2. from django.template.loader import render_to_string
  3. def get_rendered_template(context):
  4.     cache_key = f'rendered_template_{hash(str(context))}'
  5.     rendered = cache.get(cache_key)
  6.    
  7.     if rendered is None:
  8.         # 渲染模板
  9.         rendered = render_to_string('my_template.html', context)
  10.         
  11.         # 存入缓存
  12.         cache.set(cache_key, rendered, 60 * 30)  # 30分钟
  13.    
  14.     return rendered
复制代码
3、视图缓存
  1. from django.views.decorators.cache import cache_page
  2. from django.utils.decorators import method_decorator
  3. from django.views import View
  4. from django.http import HttpResponse
  5. import time
  6. # 函数视图缓存
  7. @cache_page(60 * 15)  # 缓存15分钟
  8. def my_view(request):
  9.     # 模拟耗时操作
  10.     time.sleep(2)
  11.     return HttpResponse("This content is cached for 15 minutes.")
  12. # 基于类的视图缓存
  13. class MyCachedView(View):
  14.     @method_decorator(cache_page(60 * 5))  # 缓存5分钟
  15.     def dispatch(self, *args, **kwargs):
  16.         return super().dispatch(*args, **kwargs)
  17.    
  18.     def get(self, request):
  19.         time.sleep(2)
  20.         return HttpResponse("Cached class-based view.")
复制代码
3、模板片段缓存
  1. {% load cache %}
  2. {% cache 500 sidebar %}
  3.    
  4.         
  5.         <h3>Popular Posts</h3>
  6.         <ul>
  7.             {% for post in popular_posts %}
  8.                 <li>{{ post.title }}</li>
  9.             {% endfor %}
  10.         </ul>
  11.    
  12. {% endcache %}
  13. {% cache 500 footer request.user.username %}
  14.     <footer>
  15.         
  16.         <p>User: {{ request.user.username }}</p>
  17.     </footer>
  18. {% endcache %}
复制代码
4、其他

4.1 多个缓存后端
  1. # settings.py
  2. CACHES = {
  3.     'default': {  # 默认缓存,通常使用速度较快的内存型缓存
  4.         'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
  5.         'LOCATION': 'unique-snowflake',
  6.         'TIMEOUT': 300,  # 全局默认缓存时间(秒)
  7.         'OPTIONS': {
  8.             'MAX_ENTRIES': 1000,  # 最大缓存条目数
  9.             'CULL_FREQUENCY': 3,   # 当缓存数达到MAX_ENTRIES时,删除1/CULL_FREQUENCY的缓存
  10.         }
  11.     },
  12.     'special': {  # 另一个缓存配置,例如使用文件缓存
  13.         'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
  14.         'LOCATION': '/var/tmp/django_special_cache',  # 缓存文件存放目录
  15.         'TIMEOUT': 600,  # 此缓存后端的默认超时时间
  16.     }
  17.     }
  18. }
复制代码
4.1.1 使用caches字典

django.core.cache模块提供了一个caches字典,通过缓存的别名(你在 CACHES中定义的键)来获取特定的缓存后端实例
  1. from django.core.cache import caches
  2. def my_view(request):
  3.     # 获取别名为 'special' 的缓存后端
  4.     special_cache = caches['special']
  5.    
  6.     # 使用该缓存进行操作
  7.     value = special_cache.get('my_key')
  8.     if value is None:
  9.         value = get_expensive_data()  # 计算或获取昂贵的数据
  10.         special_cache.set('my_key', value, timeout=300)  # 缓存5分钟
  11.    
  12.     # 同样,可以使用 'redis' 缓存
  13.     redis_cache = caches['redis']
  14.     redis_cache.set('redis_key', 'some_value')
复制代码
4.1.2 使用 using参数

许多 Django 的内置缓存工具(如 cache_page装饰器)和低级缓存 API 都支持 using参数来指定缓存别名。
  1. from django.views.decorators.cache import cache_page
  2. @cache_page(60 * 15, cache='special')  # 使用 'special' 缓存后端,缓存15分钟
  3. def my_special_view(request):
  4.     # ... 视图逻辑
  5.     return HttpResponse("This view uses the 'special' cache.")
复制代码
4.1.3 故障转移与降级

当缓存不可用时,应用应能继续运行
  1. from django.core.cache import caches
  2. from django.core.cache.backends.base import InvalidCacheBackendError
  3. def get_data_safely(key):
  4.     try:
  5.         # 首先尝试从 Redis 获取
  6.         return caches['redis'].get(key)
  7.     except (InvalidCacheBackendError, ConnectionError) as e:
  8.         # 如果 Redis 不可用,回退到本地内存缓存或数据库
  9.         logger.warning(f"Redis cache failed: {e}, falling back to default.")
  10.         data = caches['default'].get(key)
  11.         if data is None:
  12.             data = get_data_from_db(key)
  13.             caches['default'].set(key, data, timeout=60)
  14.         return data
复制代码
4.2 缓存版本控制

Django底层的缓存框架原生支持版本控制。当设置或获取缓存值时,你可以提供一个版本号。缓存系统会存储该版本号,并且在检索时,只有当请求的版本号与缓存值的版本号完全匹配时,数据才会被返回。
  1. from django.core.cache import cache
  2. cache.set('my_key', 'some_value', timeout=None, version=2)
  3. # 获取版本 2 的缓存值
  4. cache.get('my_key', version=2)  # 返回 'some_value'
  5. # 获取版本 1 的缓存值(如果存在)
  6. cache.get('my_key', version=1)  # 返回 None,因为版本不匹配
  7. # 增加缓存键的版本号(例如当数据结构发生变化时)
  8. cache.incr_version('my_key', version=2)  # 将 'my_key' 的版本从 2 增加到 3
  9. cache.get('my_key', version=3)  # 返回 some_value
  10. cache.get('my_key', version=2)  # 返回 None
  11. # 删除特定版本的缓存值
  12. cache.delete('my_key', version=2)
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册