美文网首页
Django 二级域名配置

Django 二级域名配置

作者: yuchanns | 来源:发表于2018-08-05 20:12 被阅读548次

    Django 二级域名配置

          在部署网站的时候我发现django的urls并不支持二级域名的配置,而在实际工作环境中,我们经常会遇到需要使用二级域名的情况。比如网站的pc版面和手机版面,域名分别是www.mysite.comm.mysite.com。虽然可以通过mysite.com/home/mysite.com/wap/这样的方式进行访问,但这并不是一个很好的解决方案。
          接着我在github上发现一个"django-hosts"插件可以为django提供这个功能,经过漫长的折腾之后总算配置成功。
    github地址:https://github.com/jazzband/django-hosts
    官方说明文档地址:https://django-hosts.readthedocs.io/en/latest/
    下面总结一下配置步骤。

    >>>原文地址

    初始状态

    • 环境:ubuntu 16.04
    • 版本:python2.7
    • webserver:nginx + uwsgi
    • 通过pip安装django_hosts插件:
    pip install django-hosts
    

          关于如何部署nginx+uwsgi+django请查阅我的另一篇日志《用Nginx部署Django+uwsgi》
          以下是我部署好的可以正确访问的项目的结构树:

    .
    ├── db.sqlite3
    ├── home
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   │   └── __init__.py
    │   ├── models.py
    │   ├── templates
    │   │   └── home
    │   │       └── index.html
    │   ├── tests.py
    │   ├── urls.py
    │   └── views.py
    ├── manage.py
    └── mysite
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py
    
    4 directories, 15 files
    

          其中关键文件的配置如下:

    # mysite/urls.py
    
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^$', include('home.urls')),
    ]
    
    # home/urls.py
    
    from django.conf.urls import url
    import views
    
    urlpatterns = [
        url(r'^$', views.index),
    ]
    
    # home/views.py
    
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.shortcuts import render
    
    # Create your views here.
    
    def index(request):
        return render(request, 'home/index.html', locals())
    
    <!-- home/templates/home/index.html -->
    
    <DOCTYPE html>
    <html>
    <head>
    <title>home</title>
    </head>
    <body>
    <p>here is home</p>
    </body>
    </html>
    

          nginx和uwsgi的配置则如下:

    # /etc/nginx/conf.d/www.conf
    
    server{
            listen 80;
            server_name www.mysite.com;
            location / {
                include uwsgi_params;
                uwsgi_pass 127.0.0.1:9001;
                uwsgi_param UWSGI_CHDIR /python/mysite;
                uwsgi_param UWSGI_SCRIPT mysite.wsgi;
                client_max_body_size 35m;
            }
    }
    
    # /etc/nginx/conf.d/m.conf
    
    server{
            listen 80;
            server_name m.mysite.com;
            location / {
                include uwsgi_params;
                uwsgi_pass 127.0.0.1:9001;
                uwsgi_param UWSGI_CHDIR /python/mysite;
                uwsgi_param UWSGI_SCRIPT mysite.wsgi;
                client_max_body_size 35m;
            }
    }
    
    # /python/uwsgi/uwsgi9001.ini
    
    [uwsgi]
    socket = 127.0.0.1:9001
    master = true
    vhosts = true
    no-site = true
    workers = 2
    reload-mercy = 10
    vacuum = true
    max-requests = 1000
    limit-as = 512
    buffer-szie = 30000
    pidfile = /python/uwsgi/uwsgi9001.pid
    daemonize = /python/uwsgi/uwsgi9001.log
    pythonpath = /usr/local/lib/python2.7/dist-packages
    

          访问www.mysite.comm.mysite.com均可以成功看到页面:

    C073C910-AA74-4953-B29B-3356F36F8A0F.png
    73B04A50-9F33-4386-81EF-348350B58915.png

          请先确保网站可以正常访问,便于后续如果报错方便排查

    配置步骤

    • 首先,我们注销掉mysite/urls.py中的路由,这样访问网站将会变成django默认的It worked!,方便后面观察配置效果
    # mysite/urls.py
    
    from django.conf.urls import url, include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        #url(r'^$', include('home.urls')),
    ]
    
    • 然后,创建一个mysite/hosts.py文件,作为插件的配置文件。内容如下:
    # mysite/hosts.py
    
    from django_hosts import patterns, host
    
    host_patterns = patterns('',
        host(r'www', 'home.urls', name='www'),
    )
    
    • 接着,在mysite/settings.py里注册django-hosts的app以及中间件,以及添加两个参数供插件调用:
    # mysite/settings.py
    
    # ...省略未变动内容
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'home',
        'django_hosts',  # 注册django_hosts的app
    ]
    
    MIDDLEWARE = [
        'django_hosts.middleware.HostsRequestMiddleware',  # 在中间件列表开头加入django_hosts的中间件
        '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.HostsRequestMiddleware',  # 在中间件列表结尾加入django_hosts的中间件
    ]
    
    ROOT_URLCONF = 'mysite.urls'
    ROOT_HOSTCONF = 'mysite.hosts'  # 添加ROOT_HOSTCONF参数
    DEFAULT_HOST = 'www'  # 添加默认的host
    # ...省略未变动内容
    
    • 重新加载uwsgi9001.ini。再次访问网页(www.mysite.com)。此时又可以见到显示着"here is home"的页面。实际上,在这一步操作,我得到了"Error 500--Internal Server Error"报错。查询uwsgi的日志得知是找不到pkg_resource模块。在踩了很多坑,浪费了几个小时后,我发现问题仅仅是因为setuptools版本不够新而已。执行
    pip install setuptools --upgrade
    

    即可解决问题。

    • 到这里,我们已经确保了插件可以正常工作(这样拆解步骤的流程有利于在出问题时快速定位到出错的环节!)。下面我们开始配置二级域名m.mysite.com。
    • 在项目根目录执行
    python manage.py startapp wap
    

    创建wap的app(记得到mysite/settings.py里注册wap的app!)。修改views.py以及创建wap/urls.py和wap/templates/wap/index.html文件,内容如下:

    # wap/urls.py
    
    from django.conf.urls import url
    import views
    
    urlpatterns = [
        url(r'^$', views.index),
    ]
    
    <!-- wap/templates/wap/index.html -->
    
    <DOCTYPE html>
    <html>
    <head>
    <title>wap</title>
    </head>
    <body>
    <p>here is wap</p>
    </body>
    </html>
    
    # wap/views.py
    
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.shortcuts import render
    
    # Create your views here.
    
    def index(request):
        return render(request, 'wap/index.html', locals())
    
    • 在mysite/hosts.py文件里添加路由:
    # mysite/hosts.py
    
    from django_hosts import patterns, host
    
    host_patterns = patterns('',
        host(r'www', 'home.urls', name='www'),
        host(r'm', 'wap.urls', name='m'),  # 新增的二级域名
    )
    
    • 最后,再次加载uwsgi9001.ini,分别访问www.mysite.comm.mysite.com成功地访问到了home和wap各自的页面:
      C073C910-AA74-4953-B29B-3356F36F8A0F.png
      D4F79360-12D4-47C6-82D8-A63EE2371E8B.png

    总结

          通过上面的配置,我们可以知道,django-hosts这个插件的原理就是在hosts.py里通过识别二级域名将路由导向到各自app指定的的urls.py。然后我们再对各自的urls.py进行配置就完成了。

    补充

          在使用了django-hosts这个插件之后,reverse不应该再使用django自带的django.shortcuts.reverse而应该使用django_hosts.resolvers.reverse。

    from django_hosts.resolvers import reverse
    reverse("user:login", host="www")  # host参数指明了reverse到哪个host 
    

    相关文章

      网友评论

          本文标题:Django 二级域名配置

          本文链接:https://www.haomeiwen.com/subject/npqivftx.html