views:

343

answers:

3

Hello,

If you were to write an app for a site, but wanted to make the app plug&play so you can just drop it in any Django project, set the main URL and there you go, how would you do that if you wanted to keep all the other required utility apps included in your portable app.

Example:

site/
site/site-app1
site/templates/site-app1
site/util-app1
site/util-app2
site/util-app3

Note: that the site-app1 makes the use of all three util-apps. It works great in this manner. But now, you decide to send the app to someone, but just that app with all its dependencies.

If we could package and send the apps like this?:

site/site-app1
site/site-app1/template
site/site-app1/util-app1
site/site-app1/util-app2
site/site-app1/util-app3

Then you just send site-app1 and everything goes with it.

Is there a way to make portable with utility apps as subdirctories?

Note: the idea is that we don't want to send the whole project, but one site-app within the project only.

+1  A: 

There have been a few presentations about reusable django apps, so search around. These should get you going:

Gerry
Excellent, thanks
VN44CA
+1  A: 

The presentations @Gerry links to are good sources of general info. To answer your question more directly, there isn't a way to package one app inside of another one (EDIT sorry, this is just plain wrong. You can put one app inside of another one's namespace, and it works just fine. It's an odd thing to do though: you're implying that the one app is a part of the other one; if that's true they'd be easier to use as a single app. So I'd still recommend one of the below options). AFAICT your options are:

  1. If possible, make those external dependencies optional (i.e. enhanced functionality if util_app1 is available, fallback behavior if it isn't). This is how many apps behave with respect to, say, django-tagging or django-mailer.

  2. Roll all the functionality into a single app. Depending how much code you actually depend on from the utility apps, if the dependencies are absolutely necessary for your app to function, this might be the best option to make things easy on your users.

  3. Package and distribute all the apps separately and note the dependencies both in the documentation and in the setup.py install_requires. If all the apps are independently useful, this approach may be best. If they aren't all independently useful, why are they all separate apps?

Carl Meyer
well, I have an app with no views that is just to provide location info. Other apps user it, so I need to put it outside any of the other apps. But if I need to send someone one of the apps that use the Location app, now I have to send him two apps. The other reason is, I have a simple utility function that does operation X on a string. So, I can't copy the string utility into all apps, I have to keep it out, but now there are dependencies. So, things are not as simple as the seem.
VN44CA
It never is simple ;-) If you want to package apps for generic reuse, you do have to think a bit differently than if you're writing them for use in a particular project. Sometimes there are tradeoffs between what's easiest/most performant/DRY and what allows for generic reuse. Without seeing the code details, though, it's hard to give more specific commentary.
Carl Meyer
A: 

Django applications can be made portable by adhering to certain practices. Ofcourse, these are not mandated

Application Location

The convention is to add applications in an apps/ directory, and to modify the manage.py (and eventually the apache config) to include

import sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))

Your directory structure will look something like

site
site/apps/
site/apps/app1/
site/apps/app2/

Templates

Templates are located in the templates directory in the application. The convention is not to force the user to copy them in any other location. Eventually the user can have global templates to override the ones in the application.

Settings

Keep all default settings in a local file within the app directory. The settings would be overridden by the global settings. The local settings file will have the following structure..

from django.conf import settings

def get(key, default):
    return getattr(settings, key, default)

SETTING_1 = get('SETTTING_1', 10)

These conventions should cover most major issues.

Chirayu Patel
Quick Questions: 1- Can we just put the Apps directory on the python path? what is the need for manage.py or Apache config change? Can this be done by setting the PYTHONPATH? 2- I understand the need for a local setting file in the app directory, but why would it get overwritten by the global one? I guess I don't understand the code in your "settings" explanation. Thx
VN44CA
Ofcourse you can change PYTHONPATH. I had mentioned manage.py from the perspective of conventions..
Chirayu Patel