2016-07-13 21 views
1

私はかなり独特の要件があります。アプリケーションは、独自の稼働時間を合計時間として表示できる必要があります。つまり、私はリクエスト・レスポンス・サイクルから離れ、関連するモデルの現在のタイムスタンプを更新する必要があります。サーバの初期化時にモデル操作を実行します。

これを念頭に置いて、私はready()メソッドのコードをapps.pyに入れてhereの指示に従っています。問題は、もちろん、私はApps aren't loaded yetエラーに遭遇したことです。これを回避するにはどうしたらいいですか?

もう1つのアプローチは、モデルを削除してファイルにタイムスタンプを書き込むことですが、これはスケーリングしない脆弱な方法です。ブート時に広範なリレーショナル情報を保存したい場合はどうすればよいですか?

誰かが何か提案できますか?次のように

======= UPDATE =========

私が使用しているコードは(私のプロジェクトが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ファイル:私は./manage.py runserverを実行したときに

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() 

そして、ここでは、完全なスタックトレースですが、 :

(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. 
+1

'準備が'メソッドを*と呼ばれます。 "Appsがまだロードされていません"というメッセージが表示されたら、 'ready()'メソッドの外で何か間違ったことをしています。コードと関連するスタックトレースを送信します。 – solarissmoke

+0

@solarissmoke質問に追加されました。助けてください! – dotslash

答えて

2

あなたは、メソッド内からモデルをインポートする必要があります。上記のように、あなたがモデルクラスにアクセスすることができますが

、避ける:

def ready(self): 
    from remind.models import Monitor 

しかし、あなたはまたwarning in the documentation注意してくださいあなたのready()実装でデータベースとやりとりします。これには、クエリを実行するモデルメソッドが含まれます(save()delete()、マネージャメソッドなど)... ready()メソッドは、すべての管理コマンドの起動時に実行されます。たとえば、テストデータベースの設定がプロダクション設定とは別になっていても、manage.py testは運用データベースに対していくつかのクエリを実行します。

また

:通常の初期化プロセスで

、準備メソッドは、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 
+0

ありがとう!それがそれでした。しかし、テストやすべてに関する警告を考慮すると、私の問題に対するよりよい解決策は何でしょうか? – dotslash

+0

@dotslash私は、コードが2回実行されるのを防ぐために、(ほとんどの場合に対処すべき)コードでの回答を編集しました。それは、おそらく、あなたの特定のセットアップで試して、それが動作することを確認する必要があると言いました。私はこの段階でDBを使用しようとしていない以外に、他にどのような選択肢があるのか​​本当に分かりません。 – solarissmoke

+0

さて、本当にありがとう! :-) – dotslash

関連する問題