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

最终效果

●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/ 保持不变

项目结构


基础配置

# blogs/settings.py

ALLOWED_HOSTS = [

    '.mydomain.cn',  # 匹配.mydomain.cn的所有域名

]

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

127.0.0.1 www.mydomain.cn

127.0.0.1 blog.mydomain.cn

127.0.0.1 api.mydomain.cn

项目主urls

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

from django.urls import path

from .views import index

app_name = 'www'

urlpatterns = [

    path('', index, name='index'),

]

项目主页

博客

接口

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

博客blog urls  apps/blog/urls.py

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//', blog_detail, name='detail'),

]

BLOG主页

进入BLOG列表

返回BLOG主页

 

  • 进入BLOG详情1
  •    

  • 进入BLOG详情2
  • BLOG详情

    返回BLOG列表

    BLOG正文:

    当前访问的ID:{{ blog_id }}

    django-hosts配置

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

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

    安装

    pip install django-hosts

    配置settings.py

    添加 django_hosts 到 INSTALLED_APPS

    # 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文件的模块

    # blogs/settings.py

    ROOT_HOSTCONF = 'blogs.hosts' 

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

    # blogs/settings.py

    DEFAULT_HOST = 'www'

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

    # blogs/settings.py

    PARENT_HOST = 'mydomain.cn'

    配置hosts.py

    # 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主页

    {% load hosts %}

    BLOG主页

    {#进入BLOG列表#}

    进入BLOG列表(django-hosts)

    就不能使用进入BLOG列表,这会导致报错。

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

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

    ●BLOG列表

    {% load hosts %}

    返回BLOG主页

    如果是需要传递参数

  • 进入BLOG详情1
  • ,也要做类似的改动
  • 进入BLOG详情1(django-hosts)
  • 现在BLOG详情的链接就是http://blog.mydomain.cn/detail/1/

    ●BLOG详情

    {% load hosts %}

    BLOG详情

    返回BLOG列表

    BLOG正文:

    当前访问的ID:{{ blog_id }}

    视图中反向url

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

    # 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

    {% load hosts %}

       

        BLOG主页

    BLOG主页

    {#进入BLOG列表#}

    进入BLOG列表(django-hosts)

    推荐阅读  {{ blog_99_url }}

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

    点进去就可以得到

    media文件加载404问题

    修改原App urls.py

    # 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//', 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 

    你可能感兴趣的:(Django二级域名路由配置方案django-hosts)