将 Django CMS 添加到我的项目后,管理命令因缓存错误而失败。我该如何解决?
After adding Django CMS to my project, management commands fail with a cache error. How can I fix it?
这是使用 Django 1.7 和 Django CMS 3.1.0。
我有一个大型 Django 项目,该项目已经投入生产几个月没有任何问题。我目前正在向其中添加 Django CMS,发现如果我的缓存处于脱机状态,我将无法发出任何管理命令而不会出现异常。 在我将 Django CMS 添加到我的项目之前,它曾经工作得很好。
这可以通过以下方式复制:
按照 documentation.
中的说明手动安装 Django CMS
设置连接到可以脱机的缓存服务的默认缓存。在我的例子中,我连接到一个仅供我的 Django 项目使用的 Redis 服务器。该服务器是在我 运行 manage.py runserver
开发之前和我的 Web 应用程序在生产环境中联机之前手动启动的。打开缓存服务可以解决问题,但有时我想 运行 在关闭缓存服务的情况下执行一些管理命令。
如果我在我的 Redis 实例离线时 运行 任何管理命令,我都会失败。例如,如果我只是 运行 ./manage.py
而没有命令,我会得到这样的跟踪:
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute
django.setup()
File "env/local/lib/python2.7/site-packages/django/__init__.py", line 21, in setup
apps.populate(settings.INSTALLED_APPS)
File "env/local/lib/python2.7/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "env/local/lib/python2.7/site-packages/django/contrib/admin/apps.py", line 22, in ready
self.module.autodiscover()
File "env/local/lib/python2.7/site-packages/django/contrib/admin/__init__.py", line 23, in autodiscover
autodiscover_modules('admin', register_to=site)
File "env/local/lib/python2.7/site-packages/django/utils/module_loading.py", line 74, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "env/local/lib/python2.7/site-packages/cms/admin/__init__.py", line 11, in <module>
plugin_pool.plugin_pool.discover_plugins()
File "env/local/lib/python2.7/site-packages/cms/plugin_pool.py", line 33, in discover_plugins
invalidate_cms_page_cache()
File "env/local/lib/python2.7/site-packages/cms/views.py", line 335, in invalidate_cms_page_cache
version = _get_cache_version()
File "env/local/lib/python2.7/site-packages/cms/views.py", line 280, in _get_cache_version
version = cache.get(CMS_PAGE_CACHE_VERSION_KEY)
File "env/local/lib/python2.7/site-packages/django_redis/cache.py", line 30, in _decorator
raise e.parent
redis.exceptions.ConnectionError: Error 2 connecting to unix socket: /var/tmp/foo/redis/foo_dev.redis.sock. No such file or directory.
如果我只是从 INSTALLED_APPS
中删除 cms
应用程序,这足以防止出现问题,但这不是一个可接受的修复方法。
有没有一种方法可以在不删除 Django CMS 或在发出任何管理命令之前打开缓存服务的情况下修复此问题?
问题
对于 Django 1.7 和 1.8 以及可预见的未来版本,该问题是相同的。 1.6 和更早版本并非不可能发生,但不太可能。
问题是,如果您使用最有可能用于 Django 项目的配置,那么每当初始化 cms
应用程序时,Django CMS 都会导致对缓存的访问。
以下是当您 运行 管理命令时发生的情况,省略了一些不相关的步骤:
Django 完成应用程序初始化过程。 (已记录 here。)当它到达 django.contrib.admin
时,它使用此应用程序的默认值 AppConfig
。
admin
的默认 AppConfig
调用 admin
的 autodiscover()
函数。 (记录here。)
最终 autodiscover()
获取 cms
自己的 admin.py
文件,并加载它。该文件启动 Django CMS 插件的发现,这反过来导致 Django CMS 使其页面缓存无效。所以你在那里获得了一个缓存访问,但是失败了,因为你的缓存服务没有打开。
解决方案
你可以做的是,正如关于管理员 explains 的文档,在你的 INSTALLED_APPS
中使用 django.contrib.admin.apps.SimpleAdminConfig
而不是 django.contrib.admin
。此应用程序配置不会自动调用 autodiscover()
。当你使用这个配置时,那么你必须自己调用autodiscover()
。在您的项目范围内进行调用 urls.py
,就像我们在 1.7 之前被要求做的那样,是您最好的选择:
from django.contrib import admin
admin.autodiscover()
以上应该清楚地表明 OP 的问题不太可能发生在 1.6 之前的 Django 版本中。按照 Django 的文档配置他们的项目的人会在他们的 urls.py
文件中调用 autodiscover()
,该文件只在进行网络查询时才被读取。然而,问题 可以 发生在那些偏离推荐做法并最终在其他地方调用 autodiscover()
的项目的人身上。
这是使用 Django 1.7 和 Django CMS 3.1.0。
我有一个大型 Django 项目,该项目已经投入生产几个月没有任何问题。我目前正在向其中添加 Django CMS,发现如果我的缓存处于脱机状态,我将无法发出任何管理命令而不会出现异常。 在我将 Django CMS 添加到我的项目之前,它曾经工作得很好。
这可以通过以下方式复制:
按照 documentation.
中的说明手动安装 Django CMS
设置连接到可以脱机的缓存服务的默认缓存。在我的例子中,我连接到一个仅供我的 Django 项目使用的 Redis 服务器。该服务器是在我 运行
manage.py runserver
开发之前和我的 Web 应用程序在生产环境中联机之前手动启动的。打开缓存服务可以解决问题,但有时我想 运行 在关闭缓存服务的情况下执行一些管理命令。
如果我在我的 Redis 实例离线时 运行 任何管理命令,我都会失败。例如,如果我只是 运行 ./manage.py
而没有命令,我会得到这样的跟踪:
Traceback (most recent call last):
File "./manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute
django.setup()
File "env/local/lib/python2.7/site-packages/django/__init__.py", line 21, in setup
apps.populate(settings.INSTALLED_APPS)
File "env/local/lib/python2.7/site-packages/django/apps/registry.py", line 115, in populate
app_config.ready()
File "env/local/lib/python2.7/site-packages/django/contrib/admin/apps.py", line 22, in ready
self.module.autodiscover()
File "env/local/lib/python2.7/site-packages/django/contrib/admin/__init__.py", line 23, in autodiscover
autodiscover_modules('admin', register_to=site)
File "env/local/lib/python2.7/site-packages/django/utils/module_loading.py", line 74, in autodiscover_modules
import_module('%s.%s' % (app_config.name, module_to_search))
File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "env/local/lib/python2.7/site-packages/cms/admin/__init__.py", line 11, in <module>
plugin_pool.plugin_pool.discover_plugins()
File "env/local/lib/python2.7/site-packages/cms/plugin_pool.py", line 33, in discover_plugins
invalidate_cms_page_cache()
File "env/local/lib/python2.7/site-packages/cms/views.py", line 335, in invalidate_cms_page_cache
version = _get_cache_version()
File "env/local/lib/python2.7/site-packages/cms/views.py", line 280, in _get_cache_version
version = cache.get(CMS_PAGE_CACHE_VERSION_KEY)
File "env/local/lib/python2.7/site-packages/django_redis/cache.py", line 30, in _decorator
raise e.parent
redis.exceptions.ConnectionError: Error 2 connecting to unix socket: /var/tmp/foo/redis/foo_dev.redis.sock. No such file or directory.
如果我只是从 INSTALLED_APPS
中删除 cms
应用程序,这足以防止出现问题,但这不是一个可接受的修复方法。
有没有一种方法可以在不删除 Django CMS 或在发出任何管理命令之前打开缓存服务的情况下修复此问题?
问题
对于 Django 1.7 和 1.8 以及可预见的未来版本,该问题是相同的。 1.6 和更早版本并非不可能发生,但不太可能。
问题是,如果您使用最有可能用于 Django 项目的配置,那么每当初始化 cms
应用程序时,Django CMS 都会导致对缓存的访问。
以下是当您 运行 管理命令时发生的情况,省略了一些不相关的步骤:
Django 完成应用程序初始化过程。 (已记录 here。)当它到达
django.contrib.admin
时,它使用此应用程序的默认值AppConfig
。admin
的默认AppConfig
调用admin
的autodiscover()
函数。 (记录here。)最终
autodiscover()
获取cms
自己的admin.py
文件,并加载它。该文件启动 Django CMS 插件的发现,这反过来导致 Django CMS 使其页面缓存无效。所以你在那里获得了一个缓存访问,但是失败了,因为你的缓存服务没有打开。
解决方案
你可以做的是,正如关于管理员 explains 的文档,在你的 INSTALLED_APPS
中使用 django.contrib.admin.apps.SimpleAdminConfig
而不是 django.contrib.admin
。此应用程序配置不会自动调用 autodiscover()
。当你使用这个配置时,那么你必须自己调用autodiscover()
。在您的项目范围内进行调用 urls.py
,就像我们在 1.7 之前被要求做的那样,是您最好的选择:
from django.contrib import admin
admin.autodiscover()
以上应该清楚地表明 OP 的问题不太可能发生在 1.6 之前的 Django 版本中。按照 Django 的文档配置他们的项目的人会在他们的 urls.py
文件中调用 autodiscover()
,该文件只在进行网络查询时才被读取。然而,问题 可以 发生在那些偏离推荐做法并最终在其他地方调用 autodiscover()
的项目的人身上。