2016-07-13 2 views
1

У меня есть довольно своеобразное требование: приложение должно иметь возможность отображать собственное время безотказной работы как общее количество часов. Это означает, что мне нужно отойти от цикла запроса-ответа и обновить текущую временную метку в соответствующей модели.Выполнение операций модели (только один раз) на сервере init

Учитывая это, я выполнил приведенные ниже инструкции here, поставив код в методе ready() моего приложения в apps.py. Проблема, конечно, в том, что я столкнулся с ошибкой Apps aren't loaded yet. Как мне обойти это?

Другой подход, который приходит на ум, - это уничтожить модели и записать временную метку в файл, но это хрупкий метод, который не будет масштабироваться. Что делать, если я хочу хранить обширную реляционную информацию во время загрузки?

Может кто-нибудь предложить что-нибудь, пожалуйста?

======= ========= 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 файл приложения:

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

The() '' метод готов называется * после * приложения будут готовы. Если вы все еще получаете сообщение «Apps not yet yet yet», вы делаете что-то неправильно, вне метода '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 все равно выполнит некоторые запросы к вашей производственной базе данных!

также:

В обычном процессе инициализации, готовый метод вызывается только один раз Джанго. Но в некоторых случаях, особенно в тестах, которые работают с установленными приложениями, готовые могут быть вызваны более одного раза. В этом случае либо напишите idempotent методы, либо поместите флаг на своих классах 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 Я отредактировал ответ способом (предложенным в документах), чтобы предотвратить запуск кода во второй раз, что должно касаться большинства случаев. Тем не менее, это то, что вам, вероятно, нужно испытать в вашей конкретной установке и убедитесь, что оно работает. Я не знаю, какие другие альтернативы существуют, кроме как не пытаться использовать БД на данном этапе. – solarissmoke

+0

Хорошо, спасибо огромное! :-) – dotslash

Смежные вопросы