简体   繁体   中英

After adding Django CMS to my project, management commands fail with a cache error. How can I fix it?

This is using Django 1.7 and Django CMS 3.1.0.

I've had a large Django project that has been in production for months without any issue. I'm currently adding Django CMS to it and found that if my cache is offline, I cannot issue any management commands without getting an exception. It used to work fine until I added Django CMS to my project.

This can be replicated by:

  1. Manually installing Django CMS by following the instructions in the documentation .

  2. Setting a default cache that connects to a cache service that can be offline. In my case I connect to a Redis server which is for my Django project's use only. This server is started manually before I run manage.py runserver in development and before my web application is brought online in production. Turning on the cache service makes the issue go away but sometimes I want to run some management commands with the cache service turned off.

If I run any management command when my Redis instance is offline, I get a failure. For instance, if I just run ./manage.py without a command, I get a trace like this one:

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.

If I just remove the cms app from INSTALLED_APPS , this is enough to prevent the problem but this is not an acceptable fix.

Is there a way I can fix this without removing Django CMS or having to turn on my cache service before I issue any management command?

The Problem

The issue is the same for Django 1.7 and 1.8 and for foreseeable future version. It is not impossible to happen with 1.6 and earlier versions but unlikely.

The issue is that if you use the configuration most likely to be used for a Django project, then Django CMS will cause an access to the cache to be made whenever the cms application is initialized.

Here is what happens when you run a management command, with some irrelevant steps omitted:

  1. Django goes through the app initialization procedure. (Documented here .) When it gets to django.contrib.admin , it uses the default AppConfig for this app.

  2. The default AppConfig for admin calls admin 's autodiscover() function. (Documented here .)

  3. Eventually autodiscover() gets to cms ' own admin.py file, and loads it. This file initiates the discovery of Django CMS' plugins, which in turn causes Django CMS to invalidate its page cache. So you get a cache access there, which fails because your cache service is not turned on.

The Solution

What you can do is, as the documentation about admin explains , use django.contrib.admin.apps.SimpleAdminConfig in your INSTALLED_APPS rather than django.contrib.admin . This app configuration does not call autodiscover() automatically. When you use this configuration, then you must call autodiscover() yourself. Putting the call in your project-wide urls.py , like we were required to do prior to 1.7, is your best bet:

from django.contrib import admin
admin.autodiscover()

The above should make it clear that the OP's problem is unlikely to happen with Django versions prior to 1.6. People who followed Django's documentation to configure their project would have the call to autodiscover() in their urls.py file, which is read only when a network query is made. However, the problem can happen for for people who diverged from the recommended practices and ended up with a project that calls autodiscover() elsewhere.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM