在Django中,我在哪里可以运行需要模型的启动代码?

14 浏览
0 Comments

在Django中,我在哪里可以运行需要模型的启动代码?

在Django启动时,我需要运行一些需要访问数据库的代码。我更喜欢通过模型来实现这一点。

以下是我目前在apps.py中的代码:

from django.apps import AppConfig
from .models import KnowledgeBase
class Pqawv1Config(AppConfig):
    name = 'pqawV1'
    def ready(self):
        to_load = KnowledgeBase.objects.order_by('-timestamp').first()
        # 这里应该放入文件加载代码

然而,这会导致以下异常出现:

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

那么,在Django中有没有一个地方可以在模型初始化后运行一些启动代码?

0
0 Comments

在Django中,我们有时需要在应用启动时运行一些需要使用模型的代码。然而,如果我们在文件的顶部导入.models,就会出现问题。这是因为当Python加载app.py文件时,它会在评估该行时加载models.py文件,这就太早了。我们应该让Django正确地进行加载。

解决方法是将导入语句放在def ready(self)方法中,这样当Django框架调用ready()时,models.py文件会被导入,示例如下:

from django.apps import AppConfig
class Pqawv1Config(AppConfig):
    name = 'pqawV1'
    
    def ready(self):
        from .models import KnowledgeBase
        to_load = KnowledgeBase.objects.order_by('-timestamp').first()
        # 在这里应该放置文件加载代码

一旦在ready()中加载了数据或资源,我们如何在views中使用它们呢?可以使用appconfig来获取给定应用的appconfig,示例如下:

from django.apps import apps
config = apps.get_app_config('app_name')
loaded_data = config.to_load

需要注意的是,这应该在函数中执行,因为模型在ready函数触发之前就已经加载完毕。

另外,值得注意的是,使用from .models import *会导致失败("SyntaxError: import * only allowed at module level"),而使用from .models import KnowledgeBase则会成功。

需要明确指出的是,官方文档明确不推荐这样做。原因是如果运行测试,ready()代码仍然会针对生产数据库而不是测试数据库运行。详情请参见此处的讨论。

0