Djangoでサブドメインを扱う(django-hosts)
はじめに
この記事は プロコンゼミ(SPC同好会) その1 Advent Calendar 2018 15日目の記事です
adventar.org
今年の高専プロコン、弊部課題部門はPythonのDjangoと戯れていました
その際、機能ごとにサブドメインで分けようという話になったのですが・・・
目的のモノを見つけるのにかなり手こずってしまったので、ここに書いておこうと思います
探す
求めているものは
「一つのDjangoプロジェクトの中で、複数のサブドメインを扱うための何か」
です
django subdomains
等で探してみると、django-subdomains というものに行き当たると思います
ですが、これは罠です
実際に使ってみると分かりますが、少なくとも現時点のdjango-subdomainsはDjango 2.Xに対応しておらず、使おうとするとエラーが出ます
結論
django-hosts を使いましょう
実際に使ってみる
基本 ドキュメント を見れば使い方は書いてありますが、やっぱり例がないとどうしてもわかりにくいですよね
ここでは実際にプロコンで書いたコードを紹介しながら説明していきたいと思います
インストール
まあここは普通にpipで入れます
pip install django-hosts
前提
こういうプロジェクトだと仮定します 今回は、もともと一つのドメイン内で管理していたものを、機能(アプリ)ごとにドメインを使い分けるようにします
- プロジェクト名:mysite
- サブドメインとそれに対応させるアプリ名:
- example.com -> myapp1
- app2.example.com -> myapp2
- app3.example.com -> myapp3
myapp1/urls.pyはmysite/urls.pyから読み込んでいるものとします
(例えばmysite/urls.pyのurlpatternsに path('', include('myapp1.urls'))
と書いておく、など)
プロジェクト内で使えるようにする
mysite/settings.pyを変更します
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'myapp1', 'myapp2', 'myapp3', 'django_hosts', # <- 追加 ] MIDDLEWARE = [ 'django_hosts.middleware.HostsRequestMiddleware', # <- 追加 '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', # <- 追加 ] ROOT_URLCONF = 'mysite.urls' ROOT_HOSTCONF = 'mysite.hosts' # <- 追加 DEFAULT_HOST = '' # <- 追加
DEFAULT_HOSTにはデフォルトにしたいサブドメインを設定します
www.example.comをデフォルトにしたいのなら DEFAULT_HOST = 'www'
と書きます
サブドメインの設定を書く
mysite/hosts.pyというファイルを新たに追加し、urls.py的な要領で書いていきます
from django.conf import settings from django_hosts import patterns, host host_patterns = patterns( '', host(r'', settings.ROOT_URLCONF, name='app1'), host(r'app2', 'myapp2.urls', name='app2'), host(r'app3', 'myapp3.urls', name='app3'), )
patterns()の最初の引数 ''
はプレフィックス(接頭辞)らしいので、たぶんドメインの頭に共通で何か入れたい時に使うのでしょう
果たしてそんな時があるのかどうか、疑問ではありますが・・・
仕上げ
もしmysite/urls.pyでmyapp2/urls.pyやmyapp3/urls.pyを読み込んでいる場合は、読み込まないようにしましょう
例えば path('', include('myapp2.urls'))
などがあれば全て消します
なぜかというと、hosts.pyで
- mysite/urls.py
- myapp2/urls.py
- myapp3/urls.py
これらを読み込んでいる(配置している)からです
せっかくサブドメインに配置したのに、example.comにも配置しておく意味はありません
消し忘れには注意しましょう
おわりに
django-hostsは実装がとても楽です
djangoでサブドメインを扱うときは、ぜひこれを使ってみて下さい
Advent Calendar、16日目の記事は弊部部長が担当です
さぞ素晴らしい記事を書いてくれることでしょう