7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DjangoとAngularを連携させる時の設定のお話

Posted at

はじめに

フロントにAngular、バックエンドでDjangoを採用した時、Apacheに載せるのにちょっと苦労したのでそのまとめです。

流れ

そもそもこの流れで正しいのかって話ですが、

  • クライアントがApacheにリクエストを投げる
  • APIへのリクエストかそれ以外へのリクエストかを振り分ける
    • APIへのリクエストなら対応するViewを実行してレスポンスを返す
    • 静的ファイルへのリクエストは普通に返す
    • それ以外へのリクエストならtemplateを返す

このような形です。

設定

以下の順で行います。

  • Apacheとpythonの連携
  • DjangoとAngularの連携

OSはLinux、pythonは3系の想定です。

Apacheとpythonの連携

mod_wsgiのインストール

公式のインストール方法に則ってインストール

mod_wsgiとは

Apache上でWSGI(Web Server Gateway Interface)を満たすPythonウェブアプリケーションを動かすためのモジュール。

プロジェクトの作成

django-admin startproject sample
cd sample
python3 manage.py startapp sampleapp

httpd.confの追加

Apacheの設定ファイルに追加をします。
httpd.confを直接編集しても良いのですが、httpd.conf内の
Include /private/..../*.conf
のように書いてあるフォルダに新規設定ファイルを追加すれば、設定が追加されます。

wsgi.conf
# mod_wsgiのロード
LoadModule wsgi_module <pythonのsite-packagesまでのパス>/mod_wsgi/server/mod_wsgi-py36.cpython-36m-darwin.so

# リクエストの振り分け

# staticへのリクエストは直接
Alias /static <プロジェクトのパス>/static
<Directory <プロジェクトのパス>/static>
Require all granted
</Directory>

# それ以外のリクエストはwsgi.pyへ流す
WSGIScriptAlias / <プロジェクトのパス>/sample/wsgi.py

# Pythonモジュールがどこにあるかの指定
WSGIPythonPath <pythonのsite-packagesまでのパス>

# プロジェクト以下のファイルに対する設定
<Directory <プロジェクトのパス>>
Order deny,allow
Require all granted
</Directory>

念のため、httpd -t コマンドでチェックしてください。

挙動確認

ここまでで、ApacheへリクエストするとDjangoからレスポンスが返ってくるはずなので、サンプルでリクエストを返すようにして確認します。

sample.wsgi.py
# デフォルトからの差分のみ表示

# application = get_wsgi_application()

def application(environ, start_response):
    status = '200 OK'
    output = b'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

この状態でApacheにアクセスして、レスポンスとして'Hello World'が表示されたらOKです。
確認が済んだら変更分を元に戻し、プロジェクトをモジュールとして実行させるために以下のように編集します。

sample.wsgi.py
# デフォルトからの差分のみ表示
import sys
path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if path not in sys.path:
    sys.path.append(path)

DjangoとAngularの連携

Angularプロジェクトの作成

ng new angular-sample

Djangoの設定編集

プロジェクトディレクトリ配下にtemplateフォルダとstaticフォルダを作成します。
setting.pyを以下のように編集します。

sample.setting.py
# 差分のみ
INSTALLED_APPS = [
    'sampleapp' 
]

TEMPLATES = [
    {
        # templateを探す場所を指定する
        'DIRS': [os.path.join(BASE_DIR, 'template')],
    },
]

# 静的ファイルの場所を指定
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
]

url.pyの編集

sample.urls.py
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.generic.base import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    # API呼び出しはsampleappの想定。
    # path('sampleapp/', include('sampleapp.urls')),
    # 上記以外のurlならテンプレートを返す
    re_path(r'.*', TemplateView.as_view(template_name='index.html'), name='home')
]

Angularプロジェクトのコンパイルとindex.htmlの修正

ng build --output-hashing=none
オプション(prod, output-hashing)は公式を確認して、ふさわしいものを選択します。
.angular-cli.jsonをいじっていなかったら、distフォルダにコンパイルされたプロジェクトができています。
その中からindex.htmlを先ほど作成したtemplateフォルダに、それ以外をstaticフォルダ配下に移動させます。
一度index.htmlを編集してしまえば、buildするときにstaticフォルダを指定すると楽です。

index.html内のパス(src属性等)を、Djangoのテンプレートエンジンを使用する方法に修正します。

template.index.html
{% load static %}
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>AngularSample</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="{% static 'favicon.ico' %}">
</head>

<body>
  <app-root></app-root>
  <script type="text/javascript" src="{% static 'inline.bundle.js' %}"></script>
  <script type="text/javascript" src="{% static 'polyfills.bundle.js' %}"></script>
  <script type="text/javascript" src="{% static 'styles.bundle.js' %}"></script>
  <script type="text/javascript" src="{% static 'vendor.bundle.js' %}"></script>
  <script type="text/javascript" src="{% static 'main.bundle.js' %}"></script>
</body>

</html>

この状態でApacheへ適当なリクエストをすると、Angularのホーム画面が見れるはずです。

終わりに

とりあえず動くようにはできていると思いますが、本番環境で静的ファイルをどのように管理するか等の課題は残ります。
不足や不備、アドバイス等があれば指摘をお願いします。

参考

https://www.codingforentrepreneurs.com/projects/angular-django/
https://docs.djangoproject.com/ja/2.1/howto/deployment/wsgi/
http://httpd.apache.org/docs/2.4/mod/core.html
https://docs.djangoproject.com/ja/2.1/ref/settings/

7
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?