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

24๐Ÿ‘

โœ…

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.

๐Ÿ‘คMelug

156๐Ÿ‘

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)
๐Ÿ‘คMichael

142๐Ÿ‘

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()
๐Ÿ‘คRebs

49๐Ÿ‘

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()
๐Ÿ‘คAlkindus

41๐Ÿ‘

I think the best way is to create your custom management command(s). Then you can call manage.py <yourcommand> from anywhere.

๐Ÿ‘คDrTyrsa

11๐Ÿ‘

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()
๐Ÿ‘คHenhuy

4๐Ÿ‘

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
๐Ÿ‘คjdm

2๐Ÿ‘

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)
๐Ÿ‘คISP

2๐Ÿ‘

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()
๐Ÿ‘คjuan Isaza

2๐Ÿ‘

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

๐Ÿ‘คMartin Nowosad

1๐Ÿ‘

Try:

os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"

if os.environ.setdefault doesnโ€™t work. (Windows 10, python3.6.4, django 2.0.3)

๐Ÿ‘คyvesva

0๐Ÿ‘

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()
๐Ÿ‘คuser1422543

0๐Ÿ‘

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()
๐Ÿ‘คleafmeal

Leave a comment