Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否可以从Django管理页面禁用缓存?_Python_Django_Caching_Django Admin - Fatal编程技术网

Python 是否可以从Django管理页面禁用缓存?

Python 是否可以从Django管理页面禁用缓存?,python,django,caching,django-admin,Python,Django,Caching,Django Admin,[其他信息] 我询问了一种禁用站点范围缓存的方法这可能有点过分了,因为我所需要的只是一种方法,当数据库或生成页面的程序被修改时,能够查看页面的最新版本 人们普遍认为在运行时修改设置是一个非常糟糕的主意 因此,一些想法:清除缓存可能会起作用,发送标志以指定我不希望看到缓存版本,或者指定来自IP地址的请求不应看到缓存页面 [原始问题] 我在有一个基于Django的网站,我经常重写部分编程或更改页面内容 每次处理它时,我都修改settings.py以禁用缓存,以便实时查看我的修改 完成后,我将重新启用

[其他信息]

我询问了一种禁用站点范围缓存的方法这可能有点过分了,因为我所需要的只是一种方法,当数据库或生成页面的程序被修改时,能够查看页面的最新版本

人们普遍认为在运行时修改设置是一个非常糟糕的主意

因此,一些想法:清除缓存可能会起作用,发送标志以指定我不希望看到缓存版本,或者指定来自IP地址的请求不应看到缓存页面

[原始问题]

我在有一个基于Django的网站,我经常重写部分编程或更改页面内容

每次处理它时,我都修改settings.py以禁用缓存,以便实时查看我的修改

完成后,我将重新启用缓存

我正在使用基于文件的缓存。以下是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
以下POC已在一个小型测试项目中进行了检查,结果为阳性

首先,编写“proxy”类,该类的行为可以是FileBasedCache或DummyCache:

文件“project/mycache.py”:

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非常缺乏经验,任何看过我的项目的人都可能会畏缩。我会稍微修改一下解决方案……想到有一个不受保护的地址会影响缓存,我不禁发抖。这项技术正是我所需要的。非常感谢。不客气!作为旁注:视图已受到保护,不受影响