Python 是否可以从Django管理页面禁用缓存?
[其他信息] 我询问了一种禁用站点范围缓存的方法这可能有点过分了,因为我所需要的只是一种方法,当数据库或生成页面的程序被修改时,能够查看页面的最新版本 人们普遍认为在运行时修改设置是一个非常糟糕的主意 因此,一些想法:清除缓存可能会起作用,发送标志以指定我不希望看到缓存版本,或者指定来自IP地址的请求不应看到缓存页面 [原始问题] 我在有一个基于Django的网站,我经常重写部分编程或更改页面内容 每次处理它时,我都修改settings.py以禁用缓存,以便实时查看我的修改 完成后,我将重新启用缓存 我正在使用基于文件的缓存。以下是settings.py的相关部分:Python 是否可以从Django管理页面禁用缓存?,python,django,caching,django-admin,Python,Django,Caching,Django Admin,[其他信息] 我询问了一种禁用站点范围缓存的方法这可能有点过分了,因为我所需要的只是一种方法,当数据库或生成页面的程序被修改时,能够查看页面的最新版本 人们普遍认为在运行时修改设置是一个非常糟糕的主意 因此,一些想法:清除缓存可能会起作用,发送标志以指定我不希望看到缓存版本,或者指定来自IP地址的请求不应看到缓存页面 [原始问题] 我在有一个基于Django的网站,我经常重写部分编程或更改页面内容 每次处理它时,我都修改settings.py以禁用缓存,以便实时查看我的修改 完成后,我将重新启用
CACHES = {
'default': {'BACKEND':
#'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/www/mysite.com/cache',
当我在站点上工作时,我注释掉最后两行并取消注释虚拟缓存行
这意味着SSH进入站点,修改settings.py,在站点上工作,然后重新修改它
是否有任何方法可以在/admin with admin.py中的某个位置将其设置为复选框?对于主请求,您可以使用 另一种方法是使用中间件将接收请求的IP与您可以存储在设置中的特定IP进行比较。大概是这样的:
from django.http import HttpRequest
def get_user_ip(request):
client_address = request.META['HTTPS_X_FORWARDED_FOR']
if your_ip == client_address:
save_user_ip()
使用单独的站点进行开发总是一件非常好的事情。 尽管如此,在生产站点上轻松禁用缓存可能会带来一些额外的好处:
- 调查与缓存相关的细微错误
- 用实际生产数据衡量有效的性能增益
- Django在启动时实例化一个缓存“default”对象,将其视为一个单例,并永远使用它
- 在我们的定制缓存后端中,我们将保留两个独立对象(一个“虚拟”和一个“基于文件的”缓存)的内部实例,并通过所需的接口方法仅公开其中一个对象
- 这样,我们实际上充当FileBasedCache或DummyCache的类代理
- 我们可以通过变量轻松控制哪个对象处于活动状态,从而在运行时切换行为,而无需重新启动Django
from django.core.cache.backends.filebased import FileBasedCache
from django.core.cache.backends.dummy import DummyCache
from django.core.cache.backends.base import DEFAULT_TIMEOUT
from constance import config
class MyCache(DummyCache):
def __init__(self, *args, **kwargs):
self.dummy_cache = DummyCache(*args, **kwargs)
self.file_cache = FileBasedCache(*args, **kwargs)
def _active_cache(self):
"""
Select either DummyCache or FileBasedCache based on configuration
"""
return self.file_cache if config.CACHING_ENABLED else self.dummy_cache
def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
return self._active_cache().add(key, value, timeout, version)
def get(self, key, default=None, version=None):
return self._active_cache().get(key, default, version)
def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
self._active_cache().set(key, value, timeout, version)
def touch(self, key, timeout=DEFAULT_TIMEOUT, version=None):
return self._active_cache().touch(key, timeout, version)
def delete(self, key, version=None):
self._active_cache().delete(key, version)
def has_key(self, key, version=None):
return self._active_cache().has_key(key, version)
def clear(self):
self._active_cache().clear()
并在项目设置中引用它,如下所示:
CACHES = {
'default': {
'BACKEND': 'project.mycache.MyCache',
'LOCATION': '/var/www/mysite.com/cache,
}
}
请注意,根据当前值config.CACHING\u ENABLED,实际操作被委托给两个内部对象之一。代理模型中没有重新实现缓存逻辑
最后,要控制管理员(简单部分)的切换标志,请为django constance定义一个布尔值“CACHING_ENABLED”(一个提供编辑动态设置的管理员界面的流行应用程序)
将其添加到项目的设置中:
INSTALLED_APPS = [
...
'constance',
'constance.backends.database',
]
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
CONSTANCE_CONFIG = {
'CACHING_ENABLED': (True, 'Set to False to disable caching'),
}
然后:
您可以使用该模块。首先要安装它,请在bash终端中键入以下内容:
pip安装django管理缓存
安装后,将这段代码添加到settings.py
中,使其自动注册:
settings.INSTALLED\u应用=[
#...
“django_管理_缓存”,
#...
]
这将在django管理页面上启用缓存。如果您只是想随意使整个缓存无效,您可以创建一个简单的视图来实现此目的: 文件
views.py
:
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.views.decorators.cache import never_cache
@never_cache
def clear_cache(request):
if not request.user.is_superuser:
raise PermissionDenied
cache.clear()
return HttpResponse('Cache has been cleared')
from django.urls import path
from . import views
urlpatterns = [
...
path('clear_cache/', views.clear_cache),
]
文件url.py
:
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.views.decorators.cache import never_cache
@never_cache
def clear_cache(request):
if not request.user.is_superuser:
raise PermissionDenied
cache.clear()
return HttpResponse('Cache has been cleared')
from django.urls import path
from . import views
urlpatterns = [
...
path('clear_cache/', views.clear_cache),
]
然后使用浏览器调用它:
http://HOST/clear_cache
我最终做了什么:
from django.core.cache import cache
def PageView(request):
...
if request.GET.get('clear') == 'cache':
if request.user.is_superuser:
title = request.GET.get('flag') + ' ' + title
cache.clear()
...
return render(request, template, context)
现在我可以转到
缓存将被清除(如果我登录到管理页面)
注二:
我开始认为我需要维护一个单独的站点进行开发。可能在部署站点的机器上放置一个脚本(shell),在某个特定的操作上执行该脚本并修改设置文件?可能使用django constance从管理员处设置一个动态布尔标志,然后创建一个自定义缓存后端,其行为类似于DummyCache或FileBasedCache,根据标志值?长镜头,但让您有机会将环境变量用作django设置中的值。您可以在管理中创建一个按钮,更改环境变量并重新启动服务器。“我开始认为我需要维护一个单独的站点进行开发。”-您真的应该这样做。或者,实际上,你需要这样做。看起来这是为了缓存管理页面,而不是主站点。我弄错了吗?这看起来是一个很好的解决方案,但我现在没有时间或专业知识来使用它。当我在整个项目中走得更远,需要一个更健壮的解决方案时,我会回到这个问题上来。我对Django非常缺乏经验,任何看过我的项目的人都可能会畏缩。我会稍微修改一下解决方案……想到有一个不受保护的地址会影响缓存,我不禁发抖。这项技术正是我所需要的。非常感谢。不客气!作为旁注:视图已受到保护,不受影响