Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python script for Django app to access models without using 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)
like image 283
Trindaz Avatar asked Nov 08 '11 07:11

Trindaz


People also ask

What is manage py shell in Django?

The reason I use management commands is because Django puts a bunch of stuff on the Python path when it starts up (such as django ) and using a management command harnesses this. python manage.py shell starts up a regular version of the python interrupter but with the added environment.

What does manage py shell do?

When you run python manage.py shell you run a python (or IPython) interpreter but inside it load all your Django project configurations so you can execute commands against the database or any other resources that are available in your Django project.


3 Answers

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) 
like image 155
Michael Avatar answered Sep 21 '22 01:09

Michael


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()
like image 29
Rebs Avatar answered Sep 20 '22 01:09

Rebs


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()
like image 28
Alkindus Avatar answered Sep 17 '22 01:09

Alkindus