Alternative to the deprecated setup_environ() for one-off django scripts?
Asked Answered
H

6

48

I used setup_environ() a while back to write a one-off python script to be run from the command line that didn't really fit very well at all as a custom manage.py command (my preferred choice). It set up everything nicely. I assume we deprecated this function because non-django pythonistas make fun of djangonauts for magicky stuff like this and we got tired of feeling dirty. So if its deprecated, what's the alternative? Maybe this is a lazy question, but what do i need to run in place of setup_environ to acheive the same effect? I guess I could copy/paste the function into my script but I'm assuming that wasn't the point of deprecating it. (obviously I can still use a deprecated function, but I want my script to survive a few versions of django)

Henbane answered 24/2, 2013 at 5:24 Comment(0)
S
62

This has changed in Django 1.7

import os
import django
from myapp import models

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
django.setup()

print models.MyModel.objects.get(pk=1)
Seasonseasonable answered 28/3, 2014 at 20:16 Comment(4)
this does not work for me on 1.7.3 django.setup() AttributeError: 'module' object has no attribute 'setup'Motch
Double check to make sure you're importing things correctly (and make sure your path is correct). The setup function should be there in 1.7.3: github.com/django/django/blob/1.7.3/django/__init__.pySeasonseasonable
django.setup() was added in 1.8 django version. it will not work in 1.7. docs.djangoproject.com/en/1.8/topics/settingsConsignor
i was pulling my hair out trying to figure out why this did not work for me and it turned out to be a relative import issue. You have to import your models as if you were in your django folder (containing your apps) not relative to where this script is! (ie. from myapp import models and not from djangofolder.myapp import models)Lucey
U
28

To expand on miki725's answer, if before you had

from django.core.management import setup_environ

import fooproject.settings as settings
setup_environ(settings)

just replace with

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fooproject.settings")
from django.conf import settings

and your settings will loaded as settings.

For Django 1.7+, see the solution from Ben Davis.

Uigur answered 15/1, 2014 at 22:45 Comment(2)
This doesn't work for me with django 1.6 - I have added the project path (not the app) to sys.path, I have added the settings model to DJANGO_SETTINGS_MODULE then imported settings from django.conf, but if I then try and import one of my database models (from shoppinglist.models import ShoppingList) it gives an error "No module named models". That same import line works from within the shell launched via manage.py. Any ideas?Radish
If you can't import models, it sounds like your path values are not set up correctly, which is outside the scope of this question regarding settings. You should try testing in a regular python shell launched with "python" instead of the django shell launched with "manage.py shell" to debug your paths.Uigur
H
21

Django 1.4 release notes officially recommend to use django.conf.settings.configure() to set the settings. This is nice for small scripts for which you need to do everything the "pythonic" way. If however you have a bigger project, I like to use the Django approach which is to have a separate settings module/package and then its path in DJANGO_SETTINGS_MODULE environment variable. This is the approach which is used in manage.py:

# manage.py

# ...
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "fooproject.settings")
# ...

Release docs can be found here.

Hagar answered 24/2, 2013 at 5:53 Comment(1)
Using Django 1.6, manage.py now has the line as suggested: os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") and yet when I try to launch a shell it still throws the same error as in the original question.Misstep
O
2

To add to what Leandro N said (thank you, Leandro!), you have to add django.setup().

For example, my code:

import os, django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django.setup()
from app.models import ModelA, ModelB

FYI, I'm on Django 1.10.

Overalls answered 6/3, 2017 at 6:1 Comment(0)
T
2

I am using Django 2.0 and Ben Davis is close but I could not get it to work. What seems to have worked for me is

import os
import sys
import django

sys.path.append("/path/to/django/project") #only required if project not already in path
os.environ.setdefault('DJANGO_SETTINGS_MODULE','myapp.settings')

django.setup() #run django.setup BEFORE importing modules to setup the environ
from myapp.models import Thingy

t=Thingly.objects.all()

print(t)
Thacker answered 31/8, 2018 at 21:30 Comment(0)
H
1

Disclaimer: I'm using Django 1.8

Just adding my 2 cents: I've tried some of the solutions presented in this page, but they did't worked at all. I just came up with a solution that I'm sharing below.

Make sure you are in the root folder of your project. The same where manage.py is located.

#make sure basic imports are in place
>>> import os,django

#set the specific django settings file
>>> os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings.base")

# import your modules and use them just like you do in your
# web apps
>>> from apps.customers import models as c

# normal usage... for instance:
>>> dir(c)
['You', 'Will', 'See', 'Your', 'Models', ... ]
Harlene answered 25/2, 2016 at 20:34 Comment(1)
what should I do if i'm not in the root?Faucal

© 2022 - 2024 — McMap. All rights reserved.