Best Practices to Work with 3rd Party Apps (and Making yours Portable)
This is a guide to setting up your django projects and django apps structure in an efficient way so you can work on portable/reusable applications and project specific applications simultaneously, use 3rd party apps, run them painlessly in the development server and happily deploying them to a production server (apache/modpython at this moment only) without any namespace headaches. Working with 3rd party / reusable applications used to be a pain for me as they are meant to live outside of your project folder structure, they either needed to live in your python site-packages folder or added to the python path; otherwise you would not be able to include them in your INSTALLED_APPS, use them in your project at all and you will end up seeing lots of “ImportError: No module named ...” type of errors.
Having to put 3rd party (and your own reusable apps) in your site-packages or having to add them to the python path was definitely not a way to go for me as I work for an agency and we are always developing and maintaining multiple applications so I would have to document which (out of all folders and files in site-packages) are the 3rd party or reusable apps used in each project, whether they need to be symlinked somewhere, etc.. so other people on the development team can collaborate on the project and I don't forget how everything is supposed to be setup once we are ready to deploy the project to a production server.
So finally after getting feedback from the community and testing different approcaches I have come up with a project setup that works like a charm.
Folder structure for a django project
/var/django_root/my_project_name/ urls.py settings.py apps/ /my_project_specific_app_1/ /my_project_specific_app_2/ /my_project_specific_app_3/
Folder structure for 3rd partygeneric/portable apps
/var/django_root/my_project_name/ urls.py settings.py apps/ /my_project_specific_app_1/ /my_project_specific_app_2/ /my_project_specific_app_3/
Development Setup
Added the following to the top of my_project_name/settings.py so it appends the portable/generic apps folder to the python path run time while testing the app using the development server.
DEVELOPMENT = True if DEVELOPMENT: import sys sys.path.append('/var/django_root/shared')
Note: don't forget to set DEVELOPMENT = False or remove those lines when deploying to a production server.
For extended convenience I symlinked my portable/generic apps folder to my django project so I can quickly make changes to my generic apps without having to go outside my django project folder structure
ln -s /var/django_root/shared /var/django_root/my_project_name/shared
Production Setup
Apache conf file:
<VirtualHost *> ServerName mydomain.tld ServerAlias *.mydomain.tld SetHandler python-program PythonPath "['/var/django_root', '/var/django_root/shared'] + sys.path" PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE my_project_name.settings PythonDebug On </VirtualHost>
Note how '/var/django_root' and '/var/django_root/shared' are both added the PythonPath