On Django startup I need to run some code that requires access to the database. I prefer to do this via models.
Here's what I currently have in 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()
# Here should go the file loading code
However, this gives the following exception:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
So is there a place in Django to run some startup code after the models are initialized?
The problem is that you import .models at the top of your file. This means that, when the file app.py file is loaded, Python will load the models.py file when it evalutes that line. But that is too early. You should let Django do the loading properly.
You can move the import in the def ready(self) method, such that the models.py file is imported when ready() is called by the Django framework, like:
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()
# Here should go the file loading code
Related
I currently have 2 admin.py files.
project/admin.py
project/pages/basicpage/admin.py
I would like to use the registered classes inside the second admin.py along with the first admin.py such that they can both be reached at the same admin endpoint.
FILE ONE: project/admin.py
from django.contrib import admin
from project import models
from project.pages.basicpage import admin as BP_admin
#admin.register(models.Test)
class TestAdmin(admin.ModelAdmin):
pass
FILE TWO: project/pages/basicpage/admin.py
from django.contrib import admin
from project import models
#admin.register(models.Platform)
class PlatformAdmin(admin.ModelAdmin):
pass
#admin.register(models.Type)
class TypeAdmin(admin.ModelAdmin):
pass
In file one, I have imported the second admin as BP_admin, not that it is used yet. However when I access my http://127.0.0.1:8000/admin endpoint, understandably I only can view the "Test" class that is registered in the first file. Any idea how to get my other 2 classes from my second file registered to the first file's endpoint?
Thanks!
Admin is just the models so importing the models should be enough. You can just add:
from project.pages.basicpage import models as BP_models
#admin.register(models.Test)
...
#admin.register(BP_models.Platform)
class Platform(models.Platform):
pass
You can also simplify and not use the class:
#admin.register(models.Test, BP_models.Platform,....)
Here is my problem, i'm trying to update database through django-model on shutdown signal which is declared on init.py file but database on model object is None
import logging
import os
import signal
import sys
from django.db import transaction
logger = logging.getLogger("logger")
def my_signal_handler(*args):
if os.environ.get("RUN_MAIN") is not "true":
return
from mymodels import MyModel
logger.info("update models")
with transaction.atomic():
for model in MyModel.objects.all():
if model.my_flag:
model.my_flag = False
model.save()
sys.exit(0)
signal.signal(signal.SIGINT, my_signal_handler)
Also when i'm trying to import model outside my_signal_handler function application throws exception "django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet."
The question is: what's the better way to append shutdown hook that can access application context
if you want to use django models in standalone mode you should manually call django.setup() then you can import and work with your models so change your code to something like this:
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
from mymodels import MyModel
so in short first run django.setup() then import and work with models
check django docs on this subject
I am attempting to import a model from another app in django.
The following attempt fails:
from venueadmin.models import VenuePermissions
fails how:
Python is not able to located VenuePermissions, i guess circular reference?
from django.apps import apps
suitscity = apps.get_model('suitsandtablesadmin', 'City')
fails how:
raise AppRegistryNotReady("Models aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
so then I tried importing using __import__
suitscity = __import__('suitsandtablesadmin.models')
suitscity = getattr(suitscity, 'City')
and
suitscity = __import__('suitsandtablesadmin/models')
suitscity = getattr(suitscity, 'City')
all of which did not work because City is in a different directory suitsandtablesadmin
How can I make any one of these work?
The directory is as follows:
First I am trying to import models into my venue app models folder
suitsandtables
suitsandtables
__init__
permissions
settings
urls
wsgi
suitsandtablesadmin
__init__
apps
models <-- im trying to import a model from here
serializers
urls
views
suitsusers
__init__
apps
models
etc.....
venueadmin
__init__
apps
models
views
venues
__init__
apps
models <-- into here
views
I've updated from Django 1.8 to 1.9.
apps/comment/__init__.py (in 1.8)
from .models import Mixin
In Django 1.9 this no longer works but I still want to import Mixin in the same way.
So I tried this:
apps/comment/__init__.py
default_app_config = 'comment.apps.CommentConfig'
apps/comment/apps.py
# Django imports.
from django.apps import AppConfig
class CommentConfig(AppConfig):
name = 'comments'
def ready(self):
"""
Perform initialization tasks.
"""
from .models import CommentMixin
This however, does not appear to work, i.e. I cannot do from comment import Mixin, why?
Adding from .models import CommentMixin imports CommentMixin so that you can use it inside the ready() method. It does not magically add it to the comment module so that you can access it as comments.CommentMixin
You could assign it to the comments module in the ready() method.
# Django imports.
from django.apps import AppConfig
import comments
class CommentConfig(AppConfig):
name = 'comments'
def ready(self):
"""
Perform initialization tasks.
"""
from .models import CommentMixin
comments.CommentMixin = CommentsMixin
However I would discourage you from doing this, you might end up with hard-to-debug import errors later on. I would just change your imports to from comment.models import CommentMixin.
I use Django (1.8.1).
I need some python code to run at Django startup (apscheduler initialization), so in one of my project application, named for example my_app I created apps.py and declared appconfig ready method according to Django docs.
from apscheduler.schedulers.background import BackgroundScheduler
from django.apps import AppConfig
from my_app.views import some_shecheduled_method
class ManagerConfig(AppConfig):
name = 'my_app'
verbose_name = "My Application"
scheduler = None
def ready(self):
ManagerConfig.scheduler = BackgroundScheduler()
ManagerConfig.scheduler.add_job(some_shecheduled_method, 'interval', seconds=15)
ManagerConfig.scheduler.start()
Also in application __init__.py:
default_app_config = 'my_app.apps.ManagerConfig'
But after adding this to __init__.py in application log I see next message for all models in project:
05/04 16:00:25|py.warnings:116:WARNING ./authsystem/models.py:51: RemovedInDjango19Warning: Model class authsystem.models.UserActionLog doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. This will no longer be supported in Django 1.9.
class UserActionLog(Model):
Also when I use this apscheduler in Django it hangs sometimes when I reload application (I use uwsgi+py-autoreload=5), may be there are some mistakes in my approach and I need to use another way to initialize scheduler