【问题标题】:Where should custom statup code live in django projects?自定义状态代码应该放在 django 项目中的什么位置?
【发布时间】:2019-07-01 08:48:59
【问题描述】:

虽然在我当前的项目中切换到 gunicorn,但我明白我在启动时处理 模型缓存 的方式并不好。

设置

  • 应用名称:网站
  • 项目名称:personal_cms

我为几个模型配备了load 方法。

class SomeModel(models.Model):
    something      = models.CharField(max_length=60)
    something_else = models.URLField()

    @classmethod
    def load(cls):
        cache.set('{}'.format(cls.__name__), cls.objects.all(), None)

通常,每次模型发生变化时,信号都会调用这些方法。要加载那些在启动服务器时,我只是在wsgi.py 中添加了以下内容:

import os

from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'personal_cms.settings')

from website.models import SomeModel, SomeOtherModel
SomeModel.load()
SomeOtherModel.load()

application = get_wsgi_application()

问题

上面的代码有效,但仅在使用python manage.py runserver 时使用,而不是gunicorn personal_cms.wsgi:application。据我了解,原因是运行manage.py 带有特定的上下文。没有它,当 gunicorn 命中 wsgi.py 时,应用程序不会加载:

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

现在我想起来了,从项目的wsgi.py 加载应用程序的模型似乎是错误的。那么,我应该在哪里调用load 方法,以便在启动时缓存模型,而不管选择的 wsgi 服务器是什么?

【问题讨论】:

    标签: python django gunicorn startup wsgi


    【解决方案1】:

    所有启动代码都应该放在 AppConfig 的 ready 方法中。然后在 IBSTALLED_APPS 上引用配置类,而不是应用名称。这保证在启动时被调用。

    AppConfig docs

    【讨论】:

    • 我试过了,但问题是,当我第一次初始化我的应用程序实例 (docker-compose up) 时,表还不存在,我得到一个 django.db.utils.ProgrammingError: (1146, "Table 'cms_db_prod.website_somemodel' doesn't exist")。我对此有点不稳定:即使在entrypoint.sh 中添加python manage.py migrate,我也会收到此错误
    • 但这与我认为 devop 部分不正确有关。感谢您的回答@Daniel
    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 2021-06-08
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 2011-09-29
    相关资源
    最近更新 更多