Apps not loaded yet when using actstream django - python

So i'm trying to create an application for user interaction with stream_django. So far everything was going well until I got error:
'User model not registered. Please register model with actstream.registry'.
So after searching for some time, I modified my apps.py to be like this:
The project is called reviews
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "reviews.settings")
os.environ["DJANGO_SETTINGS_MODULE"] = "reviews.settings"
django.setup()
from django.apps import AppConfig
from django.contrib.auth.models import User
class MyappConfig(AppConfig):
name = 'myapp'
def ready(self):
from actstream import registry
registry.register(User,self.get_model('Post'),self.get_model('UserProfile'))
But now I'm getting error:
'AppRegistryNotReady("Apps aren't loaded yet")'
I'm not sure what to do anymore, any help is appreciated.

I faced the same problem but I found that the solution was to add the default_app_config setting in the __init__.py of your main project (same location as your settings.py).
For your case, that __init__.py file should look like this:
# reviews/__init__.py
default_app_config = 'myapp.apps.MyappConfig'

Related

Import django models to custom python script

I am trying to create a custom python script within my Django application. This script requires the use of my app models. I am unable to figure out how to import the models appropriately to be used within this script.
My project directory:
-my_proj(name:ais)
-my_app(name:pages)
-__init__.py
-models.py
-urls.py
...
-utils
-__init__.py
-custom_script.py
So if I wanted to access the pages.models from the custom_script.py how might I do this?
I have attempted various imports such as from django.core.management import settings and from django.core.wsgi import get_wsgi_application but I still get an error stating the following:
ModuleNotFoundError: No module named 'pages'
There is a lot of app configuration done by Django to make your models and settings properly available. The best way to get Django to do this configuration is to make your script a management command, which will be run by python manage.py <your_script_name>. How to make your own management commands is covered by the docs. https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/
I always use runscript for this, which is part of django-extensions. It requires installing this library, but it's well worth it. You can then create a scripts/ directory in your project root, and you'll have all your models available.
Simply
pip install django-extensions
and then follow the steps here
You can write a custom Command:
Add a management/commands directory to your app:
my_app/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
my_command.py
Then you can create the file my_app/management/commands/my_command.py, contains something like below:
from django.core.management.base import BaseCommand, CommandError
from my_ap.models import MyModel
class Command(BaseCommand):
help = 'Command to update some field'
def add_arguments(self, parser):
parser.add_argument('ids', nargs='+', type=int)
def handle(self, *args, **options):
for cur_id in options['ids']:
try:
obj = MyModel.objects.get(pk=my_id)
except MyModel.DoesNotExist:
raise CommandError('MyModel "%s" does not exist' % my_id)
obj.for_index = False
obj.save()
self.stdout.write(self.style.SUCCESS('Successfully closed "%s"' % my_id))
one way to see all of the models in your app is to import apps from django apps and use the get_models method.
from django.apps import apps
then you can use a comprehension in in order to view all of your models and their path. once you see the path you want you can import it at the top of your script.
models = { model.__name__: model for model in apps.get_models() }
input models into your shell to see the list of models in your app and the path from root
Also you make sure that you have import setup in your script

Automatically import custom files in Django

I have a Django project containing some files which are, obviously, not automatically discovered by Django. My workaround is to import them in urls.py so that Django can see them. This is how my urls.py looks like:
from django.contrib import admin
from django.urls import path
from custom_file_1 import * # "unused" import
from custom_file_2 import * # "unused" import
urlpatterns = [
...
]
My IDE considers the commented imports unused, since they are not used, but they are vital so that Django can process those files.
And the question: is there any nice way to let Django see those files? And how to do that?
It is usually not a good idea to import things with wildcards. Imagine that in one of the custom files some object with the name path is present, then it will override the reference to the path function you imported from django.urls.
Usually one imports such files (that for example contain signals, etc.) in the AppConfig.
In the directory of the app, there is an __init__.py file. You can write
# app/__init__.py
default_app_config = 'app.config.CustomAppConfig'
In your app directory, you then define the config of your app:
# app/config.py
from django.apps import AppConfig
class CustomAppConfig(AppConfig):
name = 'app'
def ready(self):
import custom_file_1 # noqa
import custom_file_2 # noqa
Here # noqa is used to ignore the flake8 warnings.

apps/goods/models.py 'apps.goods.models' apps is not package?

my project directories is:
apps/
goods/
models.py
views.py
base.py
trades/
users/
__init__.py
apps/goods/base.py
from django.views.generic.base import View
from apps.goods.models import Goods
class GoodsListView(View):
def get(self, request):
json_list = []
goods = Goods.objects.all()[:10]
for good in goods:
# json_dict = {}
# json_dict['name'] = good.name
# json_dict['category'] = good.category.name
# json_dict['market_price'] = good.market_price
# json_dict['add_time'] = good.add_time
# json_list.append(json_dict)
from django.forms.models import model_to_dict
for good in goods:
json_dict = model_to_dict(good)
json_list.append(json_dict)
from django.http import HttpResponse
import json
return HttpResponse(json.dumps(json_list), content_type='application/json')
i'm debug base.py not get data, but get the error:
from apps.goods.models import Goods
ModuleNotFoundError: No module named 'apps.goods'; 'apps' is not a package
and, i remove 'apps' in 'apps.goods.models', get the error:
from goods.models import Goods
ModuleNotFoundError: No module named 'goods'
env:
pycharm-2017.2
django-1.11.6
why get the error?
Use just from .models import Goods (look at "." before models - it means the module is from current folder ).Because base.py and models.py are in same folder (same app) so you dont need to specify from which app you want to import models. Just simply include it like this.
But if you want to import models from other apps, you should to make apps to be package.In Goods app folder add __init__.py.
Structure should look like:
apps/
goods/
__init__.py
models.py
views.py
base.py
trades/
users/
__init__.py
Than use from goods.models import Goods or from apps.goods.models import Goods
As in the others' comments, you need to create the init file in the folder that should be considered a package. It's called __init__.py however. You have one of these files in apps, make sure you have it in apps/goods as well.
If you still have the same problem, make sure your configuration in Django is correct, i.e. the folder above apps is loaded

Django Application: Model ImportError

I have a django 1.9 application using DRF with the following folder structure
- api/
- api/models.py
- api/serializers.py
- api/views.py
- manage.py
In serializers.py I have an import:
from api.models import Model1, Model2, ...
In views.py I have these imports:
from api.serializers import NotificationSerializer
from api.models import Model1, Model2, ...
Everything works fine until now. But after adding
from api.serializers import NotificationSerializer
in models.py, django starts complaining when I start the dev server:
File ".../api/serializers.py", line 3, in <module>
from api.models import Model1, Model2,...
ImportError: cannot import name Model1
I know that there must be a problem with the python import paths, but I can't figure it out.
This would cause a circular import, since serializers.py imports models.py, and vise versa.
How to resolve this depends on what NotificationSerializer does. If it does not use the models, you might consider moving it to a utils file.

How to have a Python script for a Django app that accesses models without using the manage.py shell?

I'm writing a script to import some model objects into the database my django application uses. In the past I've solved this by running ./manage.py shell and then import myscript. I'm sure there's a better way. I'd like to be able to call a script from anywhere on my HD using python scriptname.py, and in the first few lines of that script it would do whatever imports / other operations necessary so that it can access model objects and behave as though it was run using manage.py shell.
What do I need to add to my script to achieve this?
EDIT:
Based on #Melug's answer, with addition of dynamically setting Python path to address the 'anywhere on my HD' part of the question:
import sys
sys.path.append('c:\\my_projec_src_folder')
from myproject import settings
from django.core.management import setup_environ
setup_environ(settings)
Since Django 1.4 you should avoid using setup_environ(settings) (post by Melug) because it is deprecated. Use the following instead and you will be able to access your model
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project_name.settings")
# your imports, e.g. Django models
from your_project_name.models import Location
# From now onwards start your script..
Here is an example to access and modify your model:
if __name__ == '__main__':
# e.g. add a new location
l = Location()
l.name = 'Berlin'
l.save()
# this is an example to access your model
locations = Location.objects.all()
print locations
# e.g. delete the location
berlin = Location.objects.filter(name='Berlin')
print berlin
berlin.delete()
Example model:
class Location(models.Model):
name = models.CharField(max_length=100)
To get models loaded too, I had to combine this with this answer, otherwise I get django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")
import django
django.setup()
As an extra, I add this to the __init__.py of my django projects, it will automatically discover the app name so it is copy/paste-able:
import os
def setup():
module = os.path.split(os.path.dirname(__file__))[-1]
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{}.settings".format(module))
import django
django.setup()
Then I can just do:
from <app> import setup
setup()
For Django version 1.9 or later you can use this:
import sys
import os
import django
sys.path.append('your_project_directory')
os.environ['DJANGO_SETTINGS_MODULE'] = 'your_project.settings'
django.setup()
from yourapp.models import your_model
so you can use object as same django object:
from myapp.models import Locations
all_locations = Locations.object.all()
first_location = Locations.object.get(id=1)
print first_location.name()
first_location.save()
I think the best way is to create your custom management command(s). Then you can call manage.py <yourcommand> from anywhere.
You need to setup django environment first:
from your_project import settings
from django.core.management import setup_environ
setup_environ(settings)
At last import your models, everything goes just like django.
FOR DJANGO 1.11
Upper solutions did not work, but gave me an error:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
For me solution from here worked out:
import os
from django.core.wsgi import get_wsgi_application
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'
application = get_wsgi_application()
Since at least Django 1.11, your main app includes a wsgi module that does the neccessary setup on import. Assuming myproject/myproject is where your settings.py is, in your script just import:
from myproject.wsgi import application
Here is the answer for Django versions > 1.4:
from django.core.management import settings
from myproject.myproject import settings as project_settings
if not settings.configured:
settings.configure(default_settings=project_settings)
If you get:
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
Try:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
application = get_wsgi_application()
for django >= 2.0 it is enough to do these 2 imports
from your_project_path import settings as your_project_settings
from django.core.management import settings
then you can do just from my_app.models import MyModel
and work with your Model MyModel
Try:
os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"
if os.environ.setdefault doesn't work. (Windows 10, python3.6.4, django 2.0.3)
As Stavros pointed out here, you can just copy the wsgi.py and put it at the beginning of you script. Besides setting up DJANGO_SETTINGS_MODULE, you also need to get the applications. Hope it helps. It works for me at django 2.1.5.
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'revochem.settings')
application = get_wsgi_application()
Many of the above answers are correct, but don't reference the official documentation.
First you need to configure settings or set the DJANGO_SETTINGS_MODULE envrionment variable
from django.conf import settings
if not settings.configured:
settings.configure(myapp_defaults, DEBUG=True)
The docs then specify:
After you’ve either set DJANGO_SETTINGS_MODULE or called
configure() you’ll need to call django.setup() to load your
settings and populate Django’s application registry. For example:
import django from django.conf
import settings from myapp
import myapp_defaults
settings.configure(default_settings=myapp_defaults, DEBUG=True)
django.setup()
# Now this script or any imported module can use any part of Django it needs. from myapp import models ```
The docs also include an important caveat:
django.setup() may only be called once.
Therefore, avoid putting reusable application logic in standalone
scripts so that you have to import from the script elsewhere in your
application. If you can’t avoid that, put the call to django.setup()
inside an if block:
if __name__ == '__main__':
import django
django.setup()

Categories

Resources