package that works inside and outside django. Is this a good design?
django, python
Solution
When deploying a django project with mod_wsgi, one have to write a wsgi (python) script, that does the "sys.path" dance and sets the DJANGO_SETTINGS_MODULE environment variable, then create the wsgi application object etc.
Why do I mention this ? Because, IMHO, you should not try to handle this part of the problem within "myapp", but from a distinct python script that would be the application entry point when using your app outside a django project context, and keep "myapp" as a pure library package. This launcher script would then take care of setting up the correct environement (sys.path, settings, whatever). For the record, the settings module is just a Python module, which at runtime is an ordinary python object (instance of class "module"), and there are quite a few ways (other than the default import mechanism) to create a module instance and add it to sys.modules (which is the important point here).
As a side note, having the settings in the packages doesn't make sense IMHO, it's a configuration file.
Edit : well, I knew there was something about using part of django standalone, and here it is: https://docs.djangoproject.com/en/dev/topics/settings/#using-settings-without-setting-django-settings-module
Problem
I'm relative new to django and in generall to the python world. But I have experience with ruby (been working with rails for 2 years) so many concepts of python/django are not that new to me. Anyway, I am writing an small package in python that will have a database connection and I want to use this package inside django but also in the feature outside django. So I decided take advantage of django.db and not worry about writing any database connection and managment stuff. So I started writing my first models and wanted to make a first test outside of a django environment and I'm finding myself with some difficulties. I thought about having the same configuration mechanism for my package as for any django application (I mean the settings.py file). I wrote a file (called nodjango_settings.py as a template) that only contains the DATABASES dictionary and added two custom variables to it: ``` MYAPP_DB_ID = "myappdb" MYAPP_DB_PREFIX = "myapp_" DATABASES = { MYAPP_DB_ID: { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'myappdb', } } ``` The directory structure of my package is: ``` . |-- README.txt |-- doc | `-- db.txt |-- setup.py |-- src | |-- __init__.py | `-- myapp | |-- __init__.py | |-- exceptions.py | |-- models.py | |-- nodjango_settings.py | `-- nodjango_settings.pyc `-- test `-- test.py ``` I was reading a little bit of djangos own code to see how to handle the DJANGO_SETTINGS_MODULE environment variable and read the configuration file, so added the following code to `myapp/__init__py`. ``` import os # try to look after the DJANGO_SETTINGS_MODULE environment variable # if not present raise an import error # code abstract from python2.6/site-packages/django/conf/__init__.py try: settings_module = os.environ["DJANGO_SETTINGS_MODULE"] if not settings_module: # If it's set but is an empty string. raise KeyError except KeyError: raise ImportError("The DJANGO_SETTINGS_MODULE environment variable is not present.") # TODO: look at python2.6/site-packages/django/conf/__init__.py +93 # if you print sys.path then the project directory gets added # in django/core/management/__init__.py with sys.path.append from django.utils import importlib p = importlib.import_module(settings_module) print p.MYAPP_DB_ID ``` I wanted to test that `__init__.py` works as intended so on the root directory of my package I ran: ``` $ DJANGO_SETTINGS_MODULE="src.myapp.nodjango_settings" python src/myapp/__init__.py Traceback (most recent call last): File "src/myapp/__init__.py", line 22, in <module> p = importlib.import_module(settings_module) File "/home/yanez/devpython/lib/python2.6/site-packages/django/utils/importlib.py", line 35, in import_module __import__(name) ImportError: No module named src.myapp.nodjango_settings ``` I didn't expect that. When you create a new django application a `manage.py` file is created. And this file sets `DJANGO_SETTINGS_MODULE` the variable to the settings.py file from the perspective of the root directory of the application. I read more code of django and realized that in `django/core/management/__init__.py` the root directory of the application is added to `sys.path`. This could also be the solution to my problem but I'm not quite sure whether it's a good idea to mess with `sys.path` or not. I'm not quite sure whether my idea is a good one or a bad one. I'd like to know what you think about it and where/how I can improve it. Beside, if I stick to my idea, how can I read my custom varaibles in `settings.py` without having to reimport the settings module over and over?