我有一个相当特殊的要求:应用程序应该能够将自己的正常运行时间显示为总小时数。这意味着我需要远离请求 - 响应周期并更新相关模型中的当前时间戳。
考虑到这一点,我按照here给出的说明,将代码放在ready()
中我应用的apps.py
方法中。当然,问题是我遇到了Apps aren't loaded yet
错误。我该如何解决这个问题?
另一种想到的方法是取消模型并将时间戳写入文件,但这是一种无法扩展的脆弱方法。如果我想在启动时存储大量关系信息怎么办?
有人可以提出建议吗?
=======更新=========
我正在使用的代码如下(我的项目名为jremind
,我的应用程序名为remind
)。
这是我的模型实例:
class Monitor(models.Model):
# save automatically when object is saved()
app_init_timestamp = models.DateTimeField(null=False, auto_now=True)
应用的__init__
文件:
default_app_config = 'remind.apps.RemindConfig'
应用的apps.py
文件:
from django.apps import AppConfig
from remind.models import Monitor
class RemindConfig(AppConfig):
name = 'remind'
def ready(self):
# There's only one instance
monitor = Monitor.objects.get()[0]
#Auto-update timestamp
monitor.save()
当我运行./manage.py runserver
时,这是完整的堆栈跟踪:
(env) jremind$ ./manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
July 13, 2016 - 15:12:08
Django version 1.9, using settings 'jremind.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
^C(env) jremind$ ./manage.py runserver
Traceback (most recent call last):
File "./manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
utility.execute()
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 342, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 176, in fetch_command
commands = get_commands()
File "/media/common/code/python/projects/jremind/env/lib/python3.4/functools.py", line 448, in wrapper
result = user_function(*args, **kwds)
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/core/management/__init__.py", line 71, in get_commands
for app_config in reversed(list(apps.get_app_configs())):
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/apps/registry.py", line 137, in get_app_configs
self.check_apps_ready()
File "/media/common/code/python/projects/jremind/env/lib/python3.4/site-packages/django/apps/registry.py", line 124, in check_apps_ready
raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
答案 0 :(得分:2)
您需要从方法内导入模型:
def ready(self):
from remind.models import Monitor
但是,您还应该注意warning in the documentation:
虽然您可以按上述方法访问模型类,但请避免在
ready()
实现中与数据库进行交互。这包括执行查询的模型方法(save()
,delete()
,管理器方法等。)...您的ready()
方法将在每个管理命令启动期间运行。例如,即使测试数据库配置与生产设置分开,manage.py test
仍然会对生产数据库执行一些查询!
另外:
在通常的初始化过程中,ready方法仅由Django调用一次。但是在某些极端情况下,特别是在摆弄已安装应用程序的测试中,就可以不止一次调用ready。在这种情况下,要么写出幂等方法,要么在AppConfig类上放置一个标志,以防止重新运行应该执行一次的代码。
举旗会这样做:
class RemindConfig(AppConfig):
name = 'remind'
ready_has_run = False
def ready(self):
if self.ready_has_run:
return
# Do your stuff here, and then set the flag
self.ready_has_run = True