Multiple Domain Hosting With One Django Project

隐身守侯 提交于 2019-11-29 15:47:21

问题


I'm new to Django and python in general, so please bear with me. I want to create a very simple SaaS app to get started with Django and python. My design dictates that all domains will run on the same codebase. The only thing that will differ between each website is the database connection details. (IE each domain receives its own database. All databases contain the same schema)

How would I go about this with Django? I've seen the Sites framework, but I'm not sure that's what I'm looking for. Essentially, I'd like to either

A) Have Django look up the database connection details from a MASTER database, when the page loads, and then use those details when connecting to the site database

B) Have a settings.py per-site and have django include the correct file at runtime (IE settings_domain.py)

C) Have the index WSGI include the appropriate settings file based on the accessing domain (This seems like it could work, but I'm sure I'm missing a potential pitfall of this implementation)

D) Some other implementation I haven't thought of....

Am I making this more complicated than it needs to be? How can I easily implement this functionality into a new django project?


回答1:


Well, there's an interesting project at: https://bitbucket.org/uysrc/django-dynamicsites. It attempts to let you have entirely unique sites all running off the same project. However, currently, I don't think it will do much for you since you're going to need a bit more customization over settings than it offers.

I actually just did this myself, and originally tried to use django-dynamicsites, but found it a little too touchy and not quite right for my project. As a result, I ended up taking a little bit different approach.

My project has a "sites" module and in that a module for each unique site. Each module has it's own settings.py and urls.py and templates directory. For example:

sites
    - __init__.py
    - site1
        - __init__.py
        - settings.py
        - urls.py
        - templates
            - base.html
    - site 2
        - __init__.py
        - settings.py
        - urls.py
        - templates
            - base.html

Each settings.py looks roughly like this:

from myproject.settings import *

SITE_ID = 1
URL_CONF = 'sites.site1.urls'

SITE_ROOT = os.path.dirname(__file__)
TEMPLATE_DIRS = (
    os.path.join(SITE_ROOT, 'templates')
)

CACHE_MIDDLEWARE_KEY_PREFIX = 'site1'

So, what this does is import your projects settings file, and then overrides the settings that are unique to the site. Then, all you have to do is make sure whatever server you're using loads the particular site's settings.py instead of the main project settings.py. I'm using a combo of nginx+Gunicorn, so here's roughly how that config looks:

site1.conf (nginx)

upstream site1 {
    server 127.0.0.1:8001 fail_timeout=0;
}

server {
    listen 80;
    server_name site1.domain.com;

    root /path/to/project/root;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 30;
        proxy_pass http://site1;
        proxy_redirect off;
    }

}

I use supervisor to manage the Gunicorn server, so here's my config for that:

site1.conf (supervisor)

[program:site1]
command=/path/to/virtualenv/bin/python manage.py run_gunicorn --settings=sites.site1.settings
directory=/path/to/project/root
user=www-data
autostart=true
autorestart=true
redirect_stderr=True

The important part is that there's no fancy Django middleware or such checking for particular hosts and going this way or that accordingly. You fire up a Django instance for each on uwsgi, Gunicorn, etc. pointing to the right settings.py file, and your webserver proxies the requests for each subdomain to the matching upstream connection.




回答2:


The best way to do this is to do rewrites/proxying on your webserver, whether it be apache or nginx. In apache, you can set up your hosts file with something like this to catch all domains. The django will get a URL where it can then determine which domain it is.

<VirtualHost *:80>
     ServerName domain.com
     ServerAlias *
     DocumentRoot /var/www/domain.com/DjangoProj/public

     Alias /media/ /var/www/domain.com/DjangoProj/misc/media/
     Alias /static/ /var/www/domain.com/DjangoProj/misc/static/

     <Directory /var/www/domain.com/DjangoProj/public>
         Order deny,allow
         Allow from all
     </Directory>

     WSGIScriptAlias / /var/www/domain.com/DjangoProj/app/wsgi.py

     <Directory /var/www/domain.com/DjangoProj/app>
     <Files wsgi.py>
     Order deny,allow
     Allow from all
     </Files>
     </Directory>

     <IfModule mod_rewrite.c>
          RewriteEngine on
          RewriteCond %{HTTP_HOST} ^(.*) [NC] # Catch domain
          RewriteCond %{REQUEST_URI} !userdomain [NC] # Don't rewrite if we already have it
          RewriteRule ^(.*)$ /userdomain/%1$1 [PT,L] # Pass in PT to give the URL back to mod_python!
     </IfModule>

     ErrorLog /var/www/domain.com/logs/error.log
     CustomLog /var/www/domain.com/logs/access.log combined
</VirtualHost>


来源:https://stackoverflow.com/questions/10557590/multiple-domain-hosting-with-one-django-project

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!