简体   繁体   中英

Using Django models in external python script

I was very confused today.

I was trying to use my django app models in my python script.

here is my approach

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
from django.contrib.auth.models import User

I was confused why its giving me

ImportError: Could not import settings 'openstack_dashboard.settings' (Is it on sys.path?): cannot import name auth

Upon checking I created aa file called creds that includes

export PYTHONPATH=$PYTHONPATH:/var/www/cloudloon/horizon/; 
export DJANGO_SETTINGS_MODULE=openstack_dashboard.settings; django-admin.py shell;

and from terminal window where creds file is located, I do

source creds

and from that django-admin.py shell, I could import any of my django app models without any errors.

Why it doesn't work in my python script?

I am done with Django, What I need to do is to create a python-daemon script that will access my django app models.

I am working with in Ubuntu 12.04 that has django 1.5

As I looking for solutions, I did this:

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
sys.path.append("/var/www/cloudloon/horizon/openstack_dashboard")
# os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                          "openstack_dashboard.settings")

print os.environ["DJANGO_SETTINGS_MODULE"]
for s in sys.path:
    print s

from django.contrib.auth.models import User

heres the output: http://paste.openstack.org/show/48787/

as you can see, the directory where settings.py is located are present on my sys.path, however, It was still unable to import openstack_dashboard.settings.

Thanks everyone.

You need to write a custom management command , instead of doing these weird acrobatics.

Create a module called management (in other words, create a directory management and inside it create an empty __init__.py file) inside the directory of any app that you have listed in INSTALLED_APPS . So if you have myapp , you would create:

myapp
 |
 > management
 | | __init__.py
 > models.py
 > views.py

Then in the management directory, create another module commands and in it create a file which is the name of your command; for example my_command.py , like this:

myapp
 |
 > management
 | | __init__.py
 | | commands
 | | | __init__.py
 | | | my_command.py
 > models.py
 > views.py

In my_command.py , write this boilerplate code:

from django.core.management.base import BaseCommand, CommandError
from myapp.models import MyModel

class Command(BaseCommand):
    help = 'Does some magical work'

    def handle(self, *args, **options):
        """ Do your work here """
        self.stdout.write('There are {} things!'.format(MyModel.objects.count()))

Once you save the file, you'll be able to do python manage.py my_command and it will have access to all your models and settings.

If you need to run it as a daemon, Daniel Roseman wrote django-initd which does exactly that. Once you have installed it:

from django.core.management.base import CommandError
from daemon_command import DaemonCommand
from myapp.models import MyModel

class Command(DaemonCommand):
    help = 'Does some magical work'

    def loop_callback(self, *args, **options):
        """ Do your work here """
        self.stdout.write('There are {} things!'.format(MyModel.objects.count()))

Once you have that done from the github readme :

The important parts of such a process are these:

    * it comes up automatically on server startup
    * it logs errors and information to a named location, which is configurable
    * if the process dies, it restarts itself straight away 

[...]

Run the command as normal, but pass one of --start, --stop or --restart to 
work as a daemon. Otherwise, the command will run as a standard application.

The below script should work provided that the layout of your project (and the path to your settings file) looks like this:

/var/www/cloudloon/horizon/openstack_dashboard/settings.py

#!/usr/bin/env python
import os, sys

sys.path.append("/var/www/cloudloon/horizon")
os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
from django.contrib.auth.models import User

I believe the problem you're seeing is due to the arrangement of your project, or that you need to append another directory level to the sys.path call in the script.

Edit:

Looking at your github project, horizon and openstack_dashboard are on the same directory level. What you'd want to do is set your sys.path to one level higher:

sys.path.append("/var/www/cloudloon")

This worked for me:

from django.conf import settings
import myfolder.settings as app_settings

settings.configure(INSTALLED_APPS=app_settings.INSTALLED_APPS,DATABASES=app_settings.DATABASES)

import django
django.setup()

from myapp123.models import Sample
for s in Sample.objects.all():
    print(s)

My solution (inspired by http://blog.gabrielsaldana.org/using-django-models-in-external-python-scripts/ ):

import os
import sys
sys.path.append( os.path.join(os.path.dirname(__file__), 'MyDjangoProject'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyDjangoProject.settings")
import django
from django.conf import settings
django.setup()

from myapp.models import MyModel
for s in MyModel.objects.all():
    print(s) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM