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)
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
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)
Method 2
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()
Method 3
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()
Method 4
I think the best way is to create your custom management command(s). Then you can call manage.py <yourcommand> from anywhere.
Method 5
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.
Method 6
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()
Method 7
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
Method 8
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
Method 9
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)
Method 10
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()
Method 11
Try:
os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"
if os.environ.setdefault doesn’t work. (Windows 10, python3.6.4, django 2.0.3)
Method 12
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()
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0