我是Django和python的新手,所以请耐心等待。我想创建一个非常简单的SaaS应用程序来开始使用Django和python。我的设计要求所有域都在相同的代码库上运行。每个网站之间唯一不同的是数据库连接细节。 (IE每个域都接收自己的数据库。所有数据库都包含相同的模式)
我如何使用Django进行此操作?我已经看过网站框架,但我不确定这是我在寻找什么。基本上,我想要
A)Django在加载页面时从MASTER数据库中查找数据库连接详细信息,然后在连接到站点数据库时使用这些详细信息
B)有一个settings.py per-site并让django在运行时包含正确的文件(IE settings_domain.py)
C)索引WSGI包含基于访问域的相应设置文件(这似乎可以工作,但我确定我错过了这个实现的潜在缺陷)D)我没想过的其他一些实现......
我是否比这更复杂?如何在新的django项目中轻松实现此功能?
答案 0 :(得分:3)
嗯,有一个有趣的项目:https://bitbucket.org/uysrc/django-dynamicsites。它试图让你拥有完全独特的网站,所有网站都运行在同一个项目中。但是,目前我认为它不会对你有太大帮助,因为你需要比设置更多的自定义设置。
我实际上只是自己做了这个,并且最初尝试使用django-dynamicsites,但发现它有点过于敏感而且不适合我的项目。结果,我最终采取了一些不同的方法。
我的项目有一个“网站”模块,每个独立网站都有一个模块。每个模块都有自己的settings.py和urls.py以及templates目录。例如:
sites
- __init__.py
- site1
- __init__.py
- settings.py
- urls.py
- templates
- base.html
- site 2
- __init__.py
- settings.py
- urls.py
- templates
- base.html
每个settings.py看起来大致如下:
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'
因此,这样做是导入项目设置文件,然后覆盖网站特有的设置。然后,您所要做的就是确保您使用的服务器加载特定网站的settings.py而不是主项目settings.py。我正在使用nginx + Gunicorn的组合,所以这里大致是该配置的外观:
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;
}
}
我使用主管来管理Gunicorn服务器,所以这是我的配置:
site1.conf(主管)
[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
重要的一点是,没有花哨的Django中间件或对特定主机进行此类检查,并采取相应的方式。你为uwsgi,Gunicorn等指向正确的settings.py文件的每一个启动一个Django实例,你的web服务器将每个子域的请求代理到匹配的上游连接。
答案 1 :(得分:0)
执行此操作的最佳方法是在您的网络服务器上进行重写/代理,无论是apache还是nginx。在apache中,您可以使用类似的东西设置hosts文件以捕获所有域。 django将获得一个URL,然后可以确定它是哪个域。
<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>