Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
276 views
in Technique[技术] by (71.8m points)

python - Django serving each app separately in each its port

I've got a very simple project running on Django (no models yet) and I need to do the following:

I have created 2 apps, 'Ebony' and 'Ivory' that need to communicate with each other through JSON messages (originally designed to run on different machines but for now one is good enough).

The problem is that the Django Debug server is just one process which runs in a specific port. What I want to do is make each 'App' listen to its own port on the same server and if possible under the same Django project. Is such a scenario possible? And if yes, how should I go about it?

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is possible, but not the way you're conceptualizing it. A Django app is one part of what runs on a given web server. Thus a Django project, which has one or more apps, runs as a part of one web server.

The solution is to run multiple instances of Django. Not sure how well this is going to work for you with the debug servers. You can run each server on its own port by giving it a parameter telling it where to open the port, for example:

./manage.py runserver 8000

runs a debug server on 127.0.0.1:8000, and

./manage.py runserver 8080

runs another debug server on 127.0.0.1:8080. Usually this is done in separate shells.

You will need to make sure that the INSTALLED_APPS setting on one of these has 'Ebony' in it, and the other has 'Ivory'. You will also need to figure out some way to tell each instance how to connect to the other (usually by specifying a root URL).


That said, later on you will need to figure out if your two apps will be sharing the same database. If so, make sure that both machines can get to it. If not, make sure the DATABASES value in settings.py is different for each one. If you're sharing the database, Django's sites framework can help you keep things straight in your models.


To have both running from the same project, you have to tell Django which one to run. I prefer to use an environment variable. This changes the above runserver commands to:

SHARD=Ebony ./manage.py runserver 8000

and

SHARD=Ivory ./manage.py runserver 8080

In your settings.py file, this variable can be accessed through os.environ. So, for example, for the INSTALLED_APPS setting to have different values for each shard, you write something like:

SHARD = os.environ["SHARD"]

# Apps common to all shards go here.
LOCAL_APPS = [
    commonApp,
]

# Add apps specific to each shard.
if SHARD == "Ebony":
    LOCAL_APPS += [
        Ebony,
    ]
elif SHARD == "Ivory":
    LOCAL_APPS += [
        Ivory,
    ]

# Add them to the apps that aren't mine.
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.admin',
    # ... omitted for brevity ...
    'django_extensions',
    'south',
    'debug_toolbar',
) + LOCAL_APPS

By defining SHARD as a setting in this file, you avoid having to have all your code access the environment variable, and you confine the logic for setting SHARD to settings.py, in case you want to change it later. Your other Python files, if needed, can get the setting with from django.conf.settings import SHARD.

A similar mechanism can be used to give each shard its own DATABASES setting, too. And anything else in settings.py.

Then later in your urls.py file, you use that to pull in your apps' URLs:

from django.conf.urls import *
from django.conf import settings
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    url(r'^$', 'commonApp.views.get_homepage', name='home'),
    url(r'^login$', 'django.contrib.auth.views.login', name="login"),
    url(r'^logout$', 'django.contrib.auth.views.logout', 
        {"next_page": "/"}, name="logout"),
# Admin
    url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
    url(r'^admin/', include(admin.site.urls)),
)

# Auto-add the applications.
for app in settings.LOCAL_APPS:
    urlpatterns += patterns('',
        url(r'^{0}/'.format(app), include(app + '.urls', namespace=app)),
    )

This means your apps need their own urls.py files, and your app URL names get prefixed with your app names. So if the app Ebony defines a URL pattern with name="index", you would get that URL in a template with {% url 'Ebony:index' %}.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...