前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django二级域名路由配置方案django-hosts

Django二级域名路由配置方案django-hosts

作者头像
菲宇
发布2019-07-31 15:05:41
1.5K0
发布2019-07-31 15:05:41
举报
文章被收录于专栏:菲宇菲宇

最终效果

  • http://www.mydomain.cn/api/ --> http://api.mydomain.cn/
  • http://www.mydomain.cn/blog/ --> http://blog.mydomain.cn/
  • http://www.mydomain.cn/ --> http://www.mydomain.cn/ 保持不变

项目结构

基础配置

代码语言:javascript
复制
# blogs/settings.py

ALLOWED_HOSTS = [
    '.mydomain.cn',  # 匹配.mydomain.cn的所有域名
]

修改主机的hosts,以支持域名访问本地服务,且服务运行在80端口run server 0.0.0.0:80测试。

代码语言:javascript
复制
127.0.0.1 www.mydomain.cn
127.0.0.1 blog.mydomain.cn
127.0.0.1 api.mydomain.cn

项目主urls

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('blog/', include('blog.urls', namespace='blog')),
    path('api/', include('api.urls', namespace='api')),
    path('', include('www.urls', namespace='www')),
]

项目 www - url

代码语言:javascript
复制
from django.urls import path
from .views import index

app_name = 'www'

urlpatterns = [
    path('', index, name='index'),
]
代码语言:javascript
复制
<!-- apps/www/templates/www/index.html --> 
<h2>项目主页</h2>
<h4><a href="{% url 'blog:index' %}">博客</a></h4>
<h4><a href="{% url 'api:index' %}">接口</a></h4>

访问 http://www.mydomain.cn/

博客blog urls apps/blog/urls.py

代码语言:javascript
复制
from django.urls import path
from .views import index, blog_list, blog_detail

app_name = 'blog'

urlpatterns = [
    path('', index, name='index'),
    path('list/', blog_list, name='list'),
    path('detail/<str:blog_id>/', blog_detail, name='detail'),
]
代码语言:javascript
复制
<!-- apps/blog/templates/blog/index.html -->

<h2>BLOG主页</h2>
<a href="{% url 'blog:list' %}">进入BLOG列表</a>
BLOG_20190521_154929_12
BLOG_20190521_154929_12
代码语言:javascript
复制
<!-- apps/blog/templates/blog/list.html -->

<h4><a href="{% url 'blog:index' %}">返回BLOG主页</a></h4>
<ul>
    <li><a href="{% url 'blog:detail' 1 %}">进入BLOG详情1</a></li>
    <li><a href="{% url 'blog:detail' 2 %}">进入BLOG详情2</a></li>
</ul>
BLOG_20190521_154918_40
BLOG_20190521_154918_40
代码语言:javascript
复制
<!-- apps/blog/templates/blog/detail.html -->

<h2>BLOG详情</h2>
<h4><a href="{% url 'blog:list' %}">返回BLOG列表</a></h4>
<b>BLOG正文:</b>
当前访问的ID:{{ blog_id }}
BLOG_20190521_154907_35
BLOG_20190521_154907_35

django-hosts配置

实现 http://www.mydomain.cn/blog/ --> http://blog.mydomain.cn/

现在如果直接访问 http://blog.mydomain.cn/ 是显示的项目主页,因为没有具体路径的url都由path('', include('www.urls', namespace='www')),去匹配

BLOG_20190521_154855_18
BLOG_20190521_154855_18

安装

代码语言:javascript
复制
pip install django-hosts

配置settings.py

添加 django_hostsINSTALLED_APPS

代码语言:javascript
复制
# blogs/settings.py

INSTALLED_APPS = [
    ......
    'django_hosts',  # pip install django-hosts 安装,添加app(第1步)
    ......
]

MIDDLEWARE = [
    'django_hosts.middleware.HostsRequestMiddleware',  # django-hosts 必须添加到最前面(第2步)
    '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  必须添加到最后面(第3步)
]

在主项目下创建hosts.py 文件,创建一个包含默认主机模式的新模块

第4步,在ROOT_URLCONF之后增加,指定hosts.py文件可引用位置,设置 ROOT_HOSTCONF 包含hosts.py文件的模块

代码语言:javascript
复制
# blogs/settings.py

ROOT_HOSTCONF = 'blogs.hosts'  

第5步,设置DEFAULT_HOST,没匹配到的就用该模式,django-hosts ROOT_HOSTCONF之后增加,设置默认模式匹配。如果没有其他模式匹配,或者没有为host_url模板标记指定名称,则将使用它。

代码语言:javascript
复制
# blogs/settings.py

DEFAULT_HOST = 'www'

第6步设置PARENT_HOST显示域部分,如果想在呈现的URL的域部分附加一个默认域名,否则就只有“blog/index/”,而不是“blog.domain.cn/index/”

代码语言:javascript
复制
# blogs/settings.py

PARENT_HOST = 'mydomain.cn' 

配置hosts.py

代码语言:javascript
复制
# blogs/hosts.py

"""
创建一个包含默认主机模式的新模块的hosts.py文件中。
"""
from django.conf import settings
from django_hosts import patterns, host

host_patterns = patterns('',  # 配置模式的正则表达式,如果要使用https,在需要的host中增加 scheme='https://' 属性(第7步)
    host(r'www', settings.ROOT_URLCONF, name='www'),  # http://www.domain.cn/ 直接请求主urls中配置的路由
    host(r'api', 'api.urls', name='api'),   # http://api.mydomain.cn/
    host(r'blog', 'blog.urls', name='blog'),  # http://blog.mydomain.cn/
)

此时刷新 http://blog.mydomain.cn/ 是会报错的

django.urls.exceptions.NoReverseMatch: 'blog' is not a registered namespace

配置html

在模板中,可以使用host_url()template tag来反向使用Django的URL template tag,需要添加{% load hosts %}

  • BLOG主页
代码语言:javascript
复制
<!-- apps/blog/templates/blog/index.html -->

{% load hosts %}
<h2>BLOG主页</h2>
{#<a href="{% url 'blog:list' %}">进入BLOG列表</a>#}
<h4><a href="{% host_url 'list' host 'blog' %}">进入BLOG列表(django-hosts)</a></h4>

就不能使用<a href="{% url 'blog:list' %}">进入BLOG列表</a>,这会导致报错。

注意:任何与该App有关的用过host_url的模板中,都不能出现Django中的url,否则会出现问题'app' is not a registered namespace

BLOG_20190521_154811_72
BLOG_20190521_154811_72

现在BLOG列表的链接就是http://blog.mydomain.cn/list/

  • BLOG列表
代码语言:javascript
复制
<!-- apps/blog/templates/blog/list.html -->


{% load hosts %}
<h4><a href="{% host_url 'index'   host 'blog' %}">返回BLOG主页</a></h4>
<ul>
{#    <li><a href="{% url 'blog:detail' 1 %}">进入BLOG详情1</a></li>#}
{#    <li><a href="{% url 'blog:detail' 2 %}">进入BLOG详情2</a></li>#}
    <li><a href="{% host_url 'detail' 1  host 'blog' %}">进入BLOG详情1</a></li>
    <li><a href="{% host_url 'detail' 2  host 'blog' %}">进入BLOG详情2</a></li>
</ul>
BLOG_20190521_154749_97
BLOG_20190521_154749_97

如果是需要传递参数<li><a href="{% url 'blog:detail' 1 %}">进入BLOG详情1</a></li>,也要做类似的改动<li><a href="{% host_url 'detail' 1 host 'blog' %}">进入BLOG详情1(django-hosts)</a></li>

现在BLOG详情的链接就是http://blog.mydomain.cn/detail/1/

  • BLOG详情
代码语言:javascript
复制
<!-- apps/blog/templates/blog/detail.html -->

{% load hosts %}
<h2>BLOG详情</h2>
<h4><a href="{% host_url 'list' host 'blog' %}">返回BLOG列表</a></h4>
<b>BLOG正文:</b>
当前访问的ID:{{ blog_id }}
BLOG_20190521_154735_79
BLOG_20190521_154735_79

视图中反向url

在Python方面,比如视图,类似于Django的单向函数。只需使用django_hosts中的reverse()函数

代码语言:javascript
复制
# apps/blog/views.py

from django.shortcuts import render
from django_hosts.resolvers import reverse


def index(request):
    blog_99_url = reverse('detail', args=(99,), host='blog')
    return render(request, 'blog/index.html', {'blog_99_url': blog_99_url})

在模板中显示该url

代码语言:javascript
复制
<!-- apps/blog/templates/blog/index.html -->

<!DOCTYPE html>
{% load hosts %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BLOG主页</title>
</head>
<body>
<h2>BLOG主页</h2>
{#<a href="{% url 'blog:list' %}">进入BLOG列表</a>#}
<h4><a href="{% host_url 'list' host 'blog' %}">进入BLOG列表(django-hosts)</a></h4>
<a href="{{ blog_99_url }}" target="_blank">推荐阅读  {{ blog_99_url }}</a>
</body>
</html>
BLOG_20190521_154717_23
BLOG_20190521_154717_23

得到blog_99_url的连接为http://blog.mydomain.cn/detail/99/

点进去就可以得到

BLOG_20190521_154657_52
BLOG_20190521_154657_52

media文件加载404问题

修改原App urls.py

代码语言:javascript
复制
# blog urls  apps/blog/urls.py

from django.conf import settings
from django.conf.urls.static import static
from django.urls import path
from .views import index, blog_list, blog_detail

app_name = 'blog'

urlpatterns = [
    path('', index, name='index'),
    path('list/', blog_list, name='list'),
    path('detail/<str:blog_id>/', blog_detail, name='detail'),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

当DEBUG模式时,增加media的路径,而不用hosts时,media是配置到项目主 urls.py 中的

Nginx的配置只需要将子域名都绑定到对应的启动端口即可,后端根据子域名进行不同的路由。 另外这也会存在跨域问题,比如http://blog.mydomain.cn/登录是在http://www.mydomain.cn/usercenter/login/这个链接。

https://github.com/fungitive/blogs-domian

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 最终效果
  • 项目结构
    • 项目主urls
      • 项目 www - url
        • 博客blog urls apps/blog/urls.py
          • django-hosts配置
            • 安装
            • 配置settings.py
            • 配置hosts.py
            • 配置html
            • 视图中反向url
            • media文件加载404问题
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档