Django项目下有三个应用:blog、work、yuge,然后有两个域名,codenotes.cn 和 yugemetal.com,希望blog对应codenotes.cn,work对应codenotes.cn/work/,yuge对应yugemetal.com。
参考各种资料及踩坑后,完成相应配置,记录下。
1. 安装 django-hosts
pip install django-hosts
2. 添加应用及配置参数
# 非完整代码,仅参考
# codenotes/settings.py
# 增加应用
INSTALLED_APPS = [
# ... 内置应用等
'django_hosts', # 新增
'blog',
'work',
'yuge',
]
# 增加 django_hosts 中间件
# 'django_hosts.middleware.HostsRequestMiddleware' 必须在所有中间件最前面
# 'django_hosts.middleware.HostsResponseMiddleware' 必须在所有中间件最后面
MIDDLEWARE = [
'django_hosts.middleware.HostsRequestMiddleware', # <--- 放在最前面
# ... 其他常规中间件 (Security, Session, Common, Csrf, Auth, Message, Clickjacking等)
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django_hosts.middleware.HostsResponseMiddleware', # <--- 放在最后面
]
# 配置 django-hosts
ROOT_HOSTCONF = 'codenotes.hosts' # 指向创建的 hosts.py 文件
DEFAULT_HOST = 'blog' # 默认主机名
3. 创建 hosts 文件
# codenotes/hosts.py
from django_hosts import patterns, host
# 域名与应用路由的映射
host_patterns = patterns(
'',
# codenotes.cn 绑定 blog 应用的 urls
host(r'^codenotes\.cn$', 'codenotes.urls', name='blog'),
# yugemetal.com 绑定 yuge 应用的 urls,注意,此处需新增一个 urls_yuge.py 文件
host('^yugemetal\.com$', 'yuge.urls_yuge', name='yuge'),
)
4. codenotes/urls.py
# 非完整代码,仅参考
# codenotes/urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('work/', include(('work.urls', 'work'), namespace='work')),
path('', include(('blog.urls', 'blog'), namespace='blog')),
]
5. blog/urls.py
# 非完整代码,仅参考
# blog/urls.py
# 必须添加app_name
app_name = 'blog'
urlpatterns = [
path('about/', views.about, name='about'),
path('timeline/', views.timeline, name='timeline'),
path('article/<int:article_id>', views.article, name='article'),
path('', views.index, name='index'),
]
6. work/urls.py
# 非完整代码,仅参考
# work/urls.py
app_name = 'work'
urlpatterns = [
path('condition/core/', views.monitor_core, name='monitor_core'),
]
7. yuge/urls.py
# 非完整代码,仅参考
# yuge/urls.py
app_name = 'yuge'
urlpatterns = [
path('', views.index, name='index'),
]
8. 新增 yuge/urls_yuge.py
# yuge/urls_yuge/py
from django.urls import path, include
urlpatterns = [
# yugemetal.com/ 根路径对应yuge应用
path('', include(('yuge.urls', 'yuge'), namespace='yuge')),
]
9. templates 中使用
<!-- templates/app/xxx.html -->
<!-- 页面模板中使用时,必须先加载 hosts -->
{% load hosts %}
<ul class="nav-menu" id="navMenu">
<!-- 用 host_url 替换默认的 url,参数照常放,在最后面增加 host 对应名称 -->
<li><a href="{% host_url 'yuge:index' host 'yuge' %}#home" class="nav-link active">首页</a></li>
<li><a href="{% host_url 'blog:tag' tag.id host 'blog' %}" class="tag"></li>
</ul>
10. nginx 正常配置
# 动态请求 (Django/uWSGI)
location / {
# 使用 uWSGI 协议
uwsgi_pass django_codenotes;
include uwsgi_params;
# uWSGI 专用参数设置 (比 proxy_set_header 更准确)
uwsgi_param Host $host; # !!留意此条,根据域名区分!!
uwsgi_param X-Real-IP $remote_addr;
uwsgi_param X-Forwarded-For $proxy_add_x_forwarded_for;
uwsgi_param X-Forwarded-Proto $scheme;
}
OVER…
其中折腾最久的是页面提示 NoReverseMatch, 一开始是 hosts 中的 blog 的 url 未对应正确,对应到应用 blog 下的 urls.py 去了,实际需要对应项目的 urls.py,即 codenotes/urls.py;然后 yuge 用现有的 urls.py 无法正常显示页面,一直提示 NoReverseMatch,新建了 yuge/yuge_ursl.py 并配置相关内容后,页面及相关链接全部显示正常。
至此,目标达成,记录下。
https://codenotes.cn 正常显示博客,
https://codenotes.cn/work/ 正常显示 work 相关内容
https://yugemetal.com 正常显示宇格金属