我有一个相当特殊的要求:应用程序应该能够将其自己的正常运行时间显示为总小时数。这意味着我需要摆脱请求-响应周期并更新相关模型中的当前时间戳。
考虑到这一点,我按照 here 给出的说明进行操作。 ,将代码放入我的应用程序的 apps.py
中的 ready()
方法中。当然,问题是我遇到了应用程序尚未加载
错误。我该如何解决这个问题?
我想到的另一种方法是取消模型并将时间戳写入文件,但这是一种脆弱的方法,无法扩展。如果我想在启动时存储大量的关系信息怎么办?
有人可以建议一下吗?
======更新========
我使用的代码如下(我的项目称为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.
最佳答案
您需要从方法内部导入模型:
def ready(self):
from remind.models import Monitor
但是,您还应该注意 warning in the documentation :
Although you can access model classes as described above, avoid interacting with the database in your
ready()
implementation. This includes model methods that execute queries (save()
,delete()
, manager methods etc.)... Yourready()
method will run during startup of every management command. For example, even though the test database configuration is separate from the production settings,manage.py test
would still execute some queries against your production database!
另外:
In the usual initialization process, the ready method is only called once by Django. But in some corner cases, particularly in tests which are fiddling with installed applications, ready might be called more than once. In that case, either write idempotent methods, or put a flag on your AppConfig classes to prevent re-running code which should be executed exactly one time.
放置一个标志可以像这样完成:
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
关于django - 在服务器初始化时执行模型操作(仅一次),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341793/