Q: Django App Install Script - How to add app to INSTALLED_APPS setting? I've written a Django app, and now I want to make it easy to deploy on multiple servers.
The basic installation is:


*

*Copy the app folder into the Django project folder

*Add it to INSTALLED_APPS in settings.py

*Run ./manage.py collectstatic
This particular app doesn't need to use the DB, but if it did, I'd use south and run ./manage.py migrate, but that's another story.
The part I'm having trouble with is #2. I don't want to have to manually edit this file every time. What's the easiest/most robust way to update that?
I was thinking I could use the inspect module to find the variable and then somehow append it, but I'm not having any luck. inspect.getsourcelines won't find variables.

A: You can modify your settings.py using bash.
#set $SETTINGS_FILE variable to full path of the your django project settings.py file
SETTINGS_FILE="/path/to/your/django/project/settings.py"
# checks that app $1 is in the django project settings file
is_app_in_django_settings() {
    # checking that django project settings file exists
    if [ ! -f $SETTINGS_FILE ]; then
        echo "Error: The django project settings file '$SETTINGS_FILE' does not exist"
        exit 1
    fi
    cat $SETTINGS_FILE | grep -Pzo "INSTALLED_APPS\s?=\s?\[[\s\w\.,']*$1[\s\w\.,']*\]\n?" > /dev/null 2>&1
    # now $?=0 if app is in settings file
    # $? not 0 otherwise
}

# adds app $1 to the django project settings
add_app2django_settings() {
    is_app_in_django_settings $1
    if [ $? -ne 0 ]; then
        echo "Info. The app '$1' is not in the django project settings file '$SETTINGS_FILE'. Adding."
        sed -i -e '1h;2,$H;$!d;g' -re "s/(INSTALLED_APPS\s?=\s?\[[\n '._a-zA-Z,]*)/\1    '$1',\n/g" $SETTINGS_FILE
        # checking that app $1 successfully added to django project settings file
        is_app_in_django_settings $1
        if [ $? -ne 0 ]; then
            echo "Error. Could not add the app '$1' to the django project settings file '$SETTINGS_FILE'. Add it manually, then run this script again."
            exit 1
        else
            echo "Info. The app '$1' was successfully added to the django settings file '$SETTINGS_FILE'."
        fi
    else
        echo "Info. The app '$1' is already in the django project settings file '$SETTINGS_FILE'"
    fi
}

Use:
add_app2django_settings "my_app"


A: Here are my reasons why I think this would be wrong:


*

*it is extra code complexity without any big need, adding one line to settings every time is not that bad, especially if you are doing step #1 and #3.

*it will become not explicit what apps your project is using. When another developer will  work on your project, he might not know that your app is installed.

*you should do step #1 and step #2 on code versioning system, test the whole system and then commit the changes and just then deploy it.


I think you have something wrong (from my point of view) in your develop/deploy process if you are looking for such an "optimization". I think it is much easier and better to use INSTALLED_APPS. 
If you are building something for public use and you want to make it as easy as possible to add modules then it would be nice. In this case I would recommend to package project and it's apps as python eggs and make use of entry points. Then you could deploy an app into project like this:
pip install my-app-name

Without even step #1 and #3! Step #1 will be done by pip, and step #2 and #3 will be done by setup hooks defined in your project.
Paste script is a good example of entry-points utilization:
# Install paste script:
pip install pastescript

# install django templates for pastescript:
pip install fez.djangoskel

# now paste script knows about fez.djangoskel because of entry-points

# start a new django project from fez's templates:
paste create -t django_buildout

Here is a portion of setup.py from fez.djangoskel package:
...
entry_points="""
[paste.paster_create_template]
django_buildout=fez.djangoskel.pastertemplates:DjangoBuildoutTemplate
django_app=fez.djangoskel.pastertemplates:DjangoAppTemplate
...

zc.buildout is another great tool which might make your deployments much easier. Python eggs plays very nice with buildout.
