Eclipse configuration setup for Django can't find external libraries - python

I am in the process of migrating my Django project dev environment to Eclipse.
I have Python and Django working properly in Eclipse. However, when I try to add external libraries, the project doesn't find them.
Here is how I have been adding the modules required:
Right-clicking on project and selecting Properties
Selecting the External Libraries tab
Either adding the source folder (which is in my virtual environment) or the egg (which is also there).
However, in both cases when I do this (for the Messages module) I get this error when doing a syncdb:
Error: No module named messages
I have tried restarting Eclipse, but still no luck.

I'm new to django, so that may be not a best practice, but it works fine for me:
Are you using PyDev? If yes, your external libraries are stored in your_workspace/your_project/.pydevproject file like this:
<path>/usr/local/lib/python2.7/dist-packages/django_annoying-0.7.6-py2.7.egg</path>
It seems to me that this paths are used in development time for code completion and checking types and so on... but they must be in your pythonpath when your run your project and Eclipce doesn't put them to PATH automatically.
To ensure that django apps are in PATH I add something like that to my settings_local.py:
# v PATHS SETTINGS v #
import os
import sys
PROJECT_ROOT = os.path.join(os.path.dirname(__file__), '..')
# v 3d-party django-apps v #
DJANGO_APPS_ROOT = os.path.join(PROJECT_ROOT, '..', '..', 'djaddons')
sys.path.insert(0, os.path.join(DJANGO_APPS_ROOT, 'south'))
sys.path.insert(0, os.path.join(DJANGO_APPS_ROOT, 'annoying'))
if CONF_APP_REGISTRATION_ENABLED:
sys.path.insert(0, os.path.join(DJANGO_APPS_ROOT, 'registration'))
# v python libs v #
PYTHON_LIBS_ROOT = os.path.join(PROJECT_ROOT, '..', '..', 'pylibs')
sys.path.insert(0, os.path.join(PYTHON_LIBS_ROOT, 'oauth2'))
sys.path.insert(0, os.path.join(PYTHON_LIBS_ROOT, 'httplib2'))
# ^ END OF PATHS SETTINGS ^ #
(it's a part of my settings.py which is specific for environment and differs on development computer and on the server)
Or you can add sys.path.insert statements to your .wsgi file on server (if using mod_wsgi) and to your manage.py file for testing with manage.py runserver

The most common thing would be that you're adding the wrong paths... compare what you have in the command line with the paths you really added inside Eclipse by running:
import sys
print('\n'.join(sorted(sys.path)))
and fix the paths inside Eclipse.

Related

how to correctly set environment setting for more than one projects in Django?

I have a project called "myplanet" and my manage.py‍ file looks like:
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myplanet.settings")
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)
I know that I have to set a system variable DJANGO_SETTINGS_MODULE:myplanet.settings and also set the PYTHONPATH to my settings.py file. I was wondering what I should do in the case of another project that is called gMaps ? I tried to do the same but it does not simply work. My OS is Windows 7 x64
You can set up two independent virtual environments for each project. It's best practice I think. In that case you can even install different versions of python packages for each project as it required.
You can read about using virtualenv and it's wrapper here:
http://virtualenvwrapper.readthedocs.org/en/latest/index.html
You don't need to set PYTHONPATH variable environment to your django project for running that, when your settings.py is inside a package or is a module that is importable with manage.py.
The PYTHONPATH is a list of directories Python goes through to search for modules and files.
If you need to add a path of one library or your root path of project to it, you can do that in your code.
For example in manage.py with:
import sys
sys.path.append("/home/my/project")
Or:
import os
BASE_PATH = os.path.abspath(os.path.dirname(__file__))
sys.path.append(BASE_PATH + '/src/folder/of/my/project/')
And each django project has own manage.py‍ file that set DJANGO_SETTINGS_MODULE enivoronment itself, and you don't need to set that.
I think if your manage.py have this line:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myplanet.settings")
Then, you just need to have this structure for your project:
myplanet # It's a project folder
myplanet # It's a package
__init__.py
settings.py
manage.py
And you can run your project with python manage.py runserver without set PYTHONPATH environment variable.

django import local settings from the server

In my home directory, I have a folder called local. In it, there are files called __init__.py and local_settings.py. My django app is in a completely different directory. When the app is NOT running in DEBUG mode, I want it to load the local_settings.py file. How can this be acheived? I read the below:
Import a module from a relative path
Importing files from different folder in Python
http://docs.python.org/tutorial/modules.html
Basically, those tutorials are allowing to import from another directory, but what about a completely different working tree? I don't want to keep doing .., .., .. etc. Is there a way to goto the home directory?
I tried the following code:
import os, sys
os.chdir(os.path.join(os.getenv("HOME"), 'local'))
from local_settings import *
But i keep seeing errors in my apache error.log for it...
os.chdir just affects the current working directory, which has nothing whatsoever to do with where Python imports modules from.
What you need to do is to add the the local directory to the Pythonpath. You can either do this from the shell by modifying PYTHONPATH, or from inside Python by modifying sys.path:
import sys
import os
sys.path.append(os.path.expanduser("~/local"))
import local_settings
In response to your concerns about source control, you can just set the source control to ignore that file, and/or have a symlink installed as part of your deploy script to link the file on the os into another. I do both , though not in django. but it's a trivial task.
your deploy layout could look like this:
/current ( symlink to /releases/v3 )
/settings/local_settings.py
/releases/v1
/releases/v2
/releases/v3
and a task runs as part of your deploy:
cd /current
ln -s /settings/local_settings.py local_settings.py
if you're deploying with fab or capistrano, it's a few lines of configuration. i'm sure you could do this with puppet/chef simply too.

django manage.py settings default

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)

How do I setup and alternate directory structure for django?

I'm starting on my first large django project and have realized that the default directory structure isn't going to work well.
I saw this question and answer and decided to implement something similar.
Large Django application layout
What do I need to do to make something like this work? How can I change where django looks for apps/modules?
Python works automatically with deep directory structures. That's porbably you didn't find any instructions on how to do it.Here are some instructions on how to get classes and models to work.
If you want to have a module in folder yourproject/apps/firstapp you can just add it to INSTALLED_APPS by adding line 'apps.firstapp',. You will have to add a __init__.py file to each of the directories so that they are recognized as python packages.
When you import classes you can simply use from yourproject.apps.firstapp.filename import yourclass.
You should also make sure all template directories are listed in TEMPLATE_DIRS.
I have two methods to handle this; one for production and one for development.
In development:
Append the path to your apps in your settings.py. In my case, I have my main project in ~/hg/django/project/ and my apps are in ~/hg/django/apps/. So I use:
if DEVEL:
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'apps'))
I also use the production method on my development box. This method has a knock on effect of letting me roll back to the most recent production version by simply commenting out the line path insertion in the settings.py.
In production:
I install the apps using distutils so that I can control deployment per server, and multiple projects running on each server can all access them. You can read about the distutils setup scripts here. Then, to install, you simply:
./setup.py install
if you add:
import os
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
to your settings .py and the following to your manage.py:
sys.path.insert(0, join(settings.PROJECT_ROOT, "apps"))
sys.path.insert(0, join(settings.PROJECT_ROOT, "lib"))
then you can include them in your installed apps just as you would if they were in your project root:
INSTALLED_APPS = (
#local apps
'myapp',
#local libs
'piston_dev',
)
this allows you a bit more freedom to move apps around without having to redeclare imports and such.

How to import a Django project settings.py Python file from a sub-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

Categories