13👍
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' %}
.
0👍
For anyone willing to have multiple servers or ports for the same Django app, but is actually just trying to implement a monolitic project hosting both backend and frontend for your project, a very simple solution is to add prefixes to each "server", or just add a prefix for backend endpoints, like /api/
.
Example:
urls.py
import myproject.apps.website.views.example_view as example_view
import myproject.apps.apis.v1.example_view as api_example_view
import myproject.apps.apis.v1.example_view_2 as api_example_view_2
urlpatterns = [
path("admin/", admin.site.urls, name="admin"),
...
# Docs
path("iapi/doc/schema/", SpectacularAPIView.as_view(), name="schema"),
...
# Backend
path("api/be_page/", api_example_view.get, name="some_be_view"),
path("api/be_page_2/<str:id>/", api_example_view_2.edit, name="some_be_view_2_edit"),
# Frontend
path("", example_view.get, name="root_fe_view"),
path("fe_page/list", example_view.get, name="some_fe_view_list"),
path("fe_page/edit/<str:id>/", example_view.edit, name="some_fe_view_edit"),
]
- [Django]-Django admin – prevent objects being saved, and don't show the user confirmation message
- [Django]-Django log errors and traceback in file in production environment
- [Django]-Django Custom User Model Best Practice: User = get_user_model()?
- [Django]-Encode ImageField in base64 and store it in DB instead of path of the image