I'm on Chapter 4: Templates of the Django tutorial, and I'm trying to run the following in an Emacs inferior mode using Python:
>>> from django import template
>>> t = template.Template('My name is {{ name }}.')
>>> c = template.Context({'name': 'Adrian'})
>>> print t.render(c)
My name is Adrian.
>>> c = template.Context({'name': 'Fred'})
>>> print t.render(c)
My name is Fred.
But I get the error here.
A quick search suggests that I should do be setting my DJANGO_SETTINGS_MODULE like so:
>>> import os
>>> os.environ["DJANGO_SETTINGS_MODULE"] = "settings.py"
However, I run into this error:
ImportError: Could not import settings 'settings.py' (Is it on sys.path?): No module named settings.py
I'm using Fedora 16. How do I correctly resolve this problem?
You can do this in the python manage.py shell, since that would have settings.py in . directory.
Otherwise:
Consider settings.py just another python library and you need to ensure its added to sys.path and then you can do as follows :
import settings
from django.core.management import setup_environ
setup_environ(settings) # Setting up the env settings
This sets up the settings to your environment. [ This is the right way ]
There is no secret recipe in settings.py and since django in itself is a library to python, so it could not be default set any paths to your sys.path unless imported and executed - as I suggested.
You should really use setup_environ as suggested in another answer.
A hint regarding this specific exception: DJANGO_SETTINGS_MODULE is a Python module name, so it may not end with ".py". Usually, this would be your_django_site.settings and the module/directory your_django_site has to be in sys.path.
All Django code not in a project should either be run from the Django REPL, available via ./manage.py shell, or run as a standalone script.
In order to test anything in the shell for Django, you should use the Django shell:
python manage.py shell
This will start up a Python interpreter which will magically have your settings file (and the rest of your project) on the Python path.
(This assumes you have a project already. If not, use django-admin.py startproject my_project_name.)
Related
How do I enter the Django Shell? I am not seeing clear instructions on how to achieve this.
You can run that code interactively in the dev shell.
python manage.py shell
For future reference, though: all you need to do to make a plain .py file "Django compatible" is that you set the DJANGO_SETTINGS_MODULE environment variable before importing any Django stuff:
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproj.settings")
from myapp.models import Stuff
# ...
Following on from my last question Error: No module named psycopg2.extensions, I have updated my mac OS to Mountain Lion and installed Xcode. I have also installed psycopg2 using 'sudo port install py27-psycopg2'. I am now trying to run 'python manage.py runserver' but am receiving this error
AttributeError: 'Settings' object has no attribute 'ROOT_URLCONF'
Any help on how to fix this and get my localhost running?
From django docs:
A Django settings file contains all the configuration of your Django installation.
When you use Django, you have to tell it which settings you're using.
Do this by using an environment variable, DJANGO_SETTINGS_MODULE.
The value of DJANGO_SETTINGS_MODULE should be in Python path syntax,
e.g. mysite.settings. Note that the settings module should be on the
Python import search path.
And
ROOT_URLCONF
Default: Not defined
A string representing the full Python import path to your root
URLconf. For example: "mydjangoapps.urls". Can be overridden on a
per-request basis by setting the attribute urlconf on the incoming
HttpRequest object. See How Django processes a request for details.
If you are using multiple settings files, be sure to import the base settings in all the other settings files. This was how I got this error.
If you're working on a Django project, the root of your project(ROOT_URLCONF= variable) isn't defined in your settings.py file, or at least it isn't defined properly.
If you don't have a settings.py file, this block of code should fix the issue:
from django.conf import settings
settings.configure(
# ...
ROOT_URLCONF=__name__,
# ...
),
)
What that does is specify the root of your project runserver knows where to find your project.
If do have a settings.py file, then find that variable and add __name__ to it.
I have a settings.py file and a dev_settings.py file that I use to override some values for dev purposes. Everytime I run the ./manage.py command, I have to specify --settings=whatever.local_settings. This becomes very tedious to do every time and I am trying to find a way to force manage.py to load my dev_settings.py file every by default so that I don't have to type that long argument every time I want to run a command.
I have tried setting DJANGO_SETTINGS_MODULE, however, it appears that manage.py overrides this option.
Is it possible to make this happen or am I doomed to always specify that argument?
manage.py sets path to settings for you, that's why it's ignoring DJANGO_SETTINGS_MODULE (it's basically just script that wraps around django-admin.py).
There are 2 easy ways to fix your problem:
set DJANGO_SETTINGS_MODULE and use django-admin.py to run all commands instead of manage.py. This is even better if you use vitualenv.
copy manage.py and name it local.py (that's the name in my case) and rename all settings mentions to dev_settings.
For example:
#!/usr/bin/env python
from django.core.management import execute_manager
import imp
try:
import settings_local
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings_local.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__)
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings_local)
You can run all commands by ./local.py now.
The way this is typically done is you have settings.py with all settings that are common between environments (things like INSTALLED_APPS, etc.). Then, you have something like settings_local.py, that defines settings particular to the environment in context. You then import settings_local.py in settings.py.
# settings.py
from settings_local import *
settings.py gets added to your source code repository, but settings_local.py does not. (However, you would normally add something like settings_local.py.example to the repo.)
When you first move your app over to production, for example, you pull down the code base from your repo. You then copy settings_local.py.example to settings_local.py and make any necessary environment specific changes.
You then have separate settings_local.py files in each environment, and it all just works.
You can make a bash alias by adding these lines to your .bash_profile file:
mymanage()
{
python manage.py $1 --settings=settings_debug
}
alias mng=mymanage
Then when you run this command:
mng runserver
settings_debug.py file will be used for settings.
You can use django-admin.py with that environment variable. Commands are interchangeable, only django-admin.py doesn't override the variable you're trying to use.
If a settings file is common to all installation, you can just import it e.g.
from settings_local import *
but usually settings_local are changed and tweaked per installation and as my installation script directly copy files to target sites (without worrying what is local what is not), which mean settings_local may get overwritten, to avoid that I just keep settings_local in parent folder of the installation target and manually import it in settings.py e.g.
local_settings_file = os.path.join(prevFolder, "settings_local.py")
if os.path.exists(local_settings_file):
execfile(local_settings_file)
I have problems with importing correctly a module on appengine. My app generally uses django with app-engine-patch, but this part is task queues using only the webapp framework.
I need to import django settings for the app to work properly.
My script starts with:
import os
import sys
sys.path.append('common/')
# Force Django to reload its settings.
from django.conf import settings
settings._target = None
# Must set this env var before importing any part of Django
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
I always get this error, or something related:
<type 'exceptions.ImportError'>: No module named ragendja.settings_pre
because the settings.py file starts with
from ragendja.settings_pre import *
I think I need to add ragendja to sys.path again but I had several tries that didn't work.
Here is my directory:
project/
app.yaml
setting.py
common/
appenginepatch/
ragendja/
setting_pre.py
myapp/
script.py
Is it only a sys.path problem and how do I need to modify it with the correct syntax?
Thanks
App engine patch manipulates sys.path internally. Background tasks bypass that code, so your path will not be ready for Django calls. You have two choices:
Fix the paths manually. The app engine documentation (see the sub-section called "Handling import path manipulation") suggests factoring the path manipulation code into a module that can be imported by your task script.
Eliminate dependencies on django code, if possible. If you can write your task to be pure python and/or google api calls, you're good to go. In your case, this might mean refactoring your settings code.
Why not:
sys.path.append('common/appenginepatch')
since the ragendja is in this directory?
I created a sub-directory of my Django project called bin where I want to put all command-line run Python scripts. Some of these scripts need to import my Django project settings.py file that is in a parent directory of bin.
How can I import the settings.py file from a sub-directory of the project?
The code that I use in my command-line script to set into the "Django context" of the project is:
from django.core.management import setup_environ
import settings
setup_environ(settings)
This works fine if the script is in the root directory of my project.
I tried the following two hacks to import the settings.py file and then setup the project:
import os
os.chdir("..")
import sys
sys.path = [str(sys.path[0]) + "/../"] + sys.path
The cruel hack can import settings.py, but then I get the error:
project_module = __import__(project_name, {}, {}, [''])
ValueError: Empty module name
I think your approach may be over-complicating something that Django 1.x provides for you. As long as your project is in your python path, you can set the environment variable DJANGO_SETTINGS_MODULE at the top of your script like so:
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
In your command line script where you need to read your settings, simply import the settings module from 'django.conf' as you would do in your application code:
from django.conf import settings
And presto, you have your settings and a Django-enabled environment for your script.
I personally prefer to set my DJANGO_SETTINGS_MODULE using '/usr/bin/env' in a bash script called 'proj_env' so I don't have to repeat it
#!/bin/bash
proj_env="DJANGO_SETTINGS_MODULE=myproject.settings"
/usr/bin/env $proj_env ${*}
With this, now I can run any python script with my Django application in context:
proj_env python -m 'myproject.bin.myscript'
If you use virtualenv, this also gives you a good place to source the activate script.
etc. etc.
This is going one level up from your question, but probably the best solution here is to implement your scripts as custom manage.py (django-admin.py) commands. This gives you all of Django's functionality (including settings) for free with no ugly path-hacking, as well as command-line niceties like options parsing. I've never seen a good reason to write Django-related command-line scripts any other way.
Add the parent directory to your path:
import sys
sys.path.append('../')
import settings
Update from comments:
Don't forget the __init__.py file in
the directory that has your
settings.py – S.Lott
Let's say your project directory is /opt/someProject/`
This has files like:
manage.py
Now you have you may have your sub directory anywhere, does not matter.
Eg. subdirectory could be like:
/opt/someproject/dir1/dir2
Now for you to import your project settings inside /opt/someProject/dir1/dir2
You need to set your PYTHONPATH variable
export PYTHONPATH=/opt/someproject/
Now to import modules from bin
from someproject import bin