Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  1. Copy the app folder into the Django project folder
  2. Add it to INSTALLED_APPS in settings.py
  3. 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.

like image 622
mpen Avatar asked Sep 06 '11 16:09

mpen


2 Answers

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.

like image 148
Ski Avatar answered Sep 27 '22 22:09

Ski


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"
like image 31
shmakovpn Avatar answered Sep 27 '22 23:09

shmakovpn