##基本的な構成
- Django (バックエンド)
- Vue (フロントエンド)
Django + Vueはただバラバラに作るだけではうまく連携できないので、こういう構成にする必要がある(ざっくり)
###注意事項
文中でDjango REST frameworkをインストールしますが、この記事では特に触れません。
Django + Vueで開発を行う際にはおそらく必要となるので最小構成としてインストールしています。
###詰まったところ
- それぞれのパッケージのバージョンの互換性
- フォルダ構成
###環境構築
※この記事での開発環境OSはWindows 10です
最初に直接Windowsにインストールするもの
- (必須)Python 3.8.3
- pipを使う
- (必須)node.js 12.18.0
- npmを使う
- (必須)PyCharm Community
- Python用のIDEなので本来は必須ではないが、仮想環境も立ち上げてくれるし便利。いつもありがとう
- このチュートリアルではターミナルを含め、積極的に使っています
- (任意)git
- いれたほうがベター
それぞれのパッケージマネージャからインストールしたもの
※インストールするタイミングは追々手順の中で示します
- Python(pip)
- Django 3.0.8
- djangorestframework 3.11.0
- django-webpack-loader 0.7.0
- node.js(npm)
- @vue/cli @4.4.6
- webpack-bundle-tracker @0.4.3
##手順はここから
###1.PyCharm上で仮想環境を作る
PyCharm上の[File→New Project]から新規プロジェクトを立ち上げる
ターミナルを立ち上げて、仮想環境(venv)に入ってることを確認する
新しいフォルダを作ってその階層にターミナルで移動する
- 今回は
django_vue
フォルダを作った -
cd django_vue
で移動する - これは
venv
フォルダをgitに含ませたくないから(.gitignore
で直接指定でもOKのはず)
Gitリポジトリにしておく
-
git init
で空のGitリポジトリを作る - この先は適宜好きなタイミングでcommitしてね
###2. Pythonの仮想環境上に必要なものをインストールする
この先pipでインストールする際にpipのバージョンが古いと怒られた時はこんなコマンドも使えます
-
python -m pip install --upgrade pip --force-reinstall
- PyCharmの仮想環境(venv)にデフォルトで入っているpipのバージョンが古いのでこのメッセージが出る
まずDjango
pip install django
次にdjangorestframework
pip install djangorestframework
最後にdjango-webpack-loader
pip install django-webpack-loader
この時点でpip freeze
コマンドでインストールされたPythonパッケージを見てみる
- インストールした3つ以外にも関連するパッケージがインストールされているのが見えるはず
ちなみに今はこんなフォルダ構成
###3. Djangoプロジェクトを立ち上げて、ちょっと設定をする
Djangoプロジェクトを立ち上げる
django-admin startproject django_project
- プロジェクト名がdjango_projectのプロジェクトが立ち上がる
django_project
フォルダに移動する
cd django_project
Django上でアプリを立ち上げる
python manage.py startapp myapp
- アプリ名がmyappのアプリが作成される
今のところのフォルダ構成はこんな感じ
さらに一階層下のdjango_project
フォルダ内にあるsettings.py
を開き、編集する
- INSTALLED_APPS
- どのアプリが使われるかを指定してあげる
rest_framework
myapp.apps.MyappConfig
webpack_loader
- どのアプリが使われるかを指定してあげる
...
INSTALLED_APPS = [
'rest_framework',
'myapp.apps.MyappConfig',
'webpack_loader',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...
- WEBPACK_LOADER
- こんな感じのものを
settings.py
の最後に追加してあげる - これから後に作る
frontend
フォルダ内のwebpack-stats.json
というファイルを使ってwebpackをロードするよ、という話
- こんな感じのものを
...
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
# ↑ここまではDjangoプロジェクト作成時にもともと記述されているところ
# ↓追加
# Webpack loader
WEBPACK_LOADER = {
'DEFAULT': {
'STATS_FILE': os.path.join(BASE_DIR, 'frontend', 'webpack-stats.json'),
}
}
-
settings.py
保存してね
ここでDjangoのWebサーバーを立ち上げてみる
まずはDjangoプロジェクトを立ち上げた際の初期設定がDBに反映されていないのでマイグレートする
python manage.py migrate
マイグレーションが終わったら開発用Webサーバーを立ち上げる
python manage.py runserver
ブラウザで http://127.0.0.1:8000/ にアクセスすると、こんな画面が出るはず
Djangoプロジェクトが立ち上がりました!やったね!
次の作業に進むためにWebサーバーを止めましょう
- Webサーバーを止める時はターミナルで
Ctrl + C
を押す
###4. npmで基本的なものをインストールする
frontend
という名前のフォルダをmanage.py
と同階層に作る
フォルダ構成はこんな感じ
ターミナルでfrontend
に移動する
cd frontend
@vue/cli
をインストールする
npm i -g @vue/cli
-
i
はインストールの意味 -
-g
はグローバルでインストールするという意味で、cliが関わるものは-g
でインストールしよう
Vueのプロジェクトを作成する
vue create .
-
.
が大事で、現在のディレクトリにプロジェクトを作成できる
- 現在のディレクトリにインストールするか聞かれるので、
Y
と答える
- プリセットを選べと言われるので
default (babel, eslint)
を選ぶ- ここでは矢印キーで移動する
- インストールが終わるのを待つ
- インストールが終わったらVueの開発用Webサーバーを立ち上げてみる
npm run serve
- ブラウザで表示されているURL(今回は http://localhost:8081 、つまり http://127.0.0.1:8081 と同義)にアクセスすると、こんな画面になる
- これでVue.jsアプリが立ち上がりました!やったね!
- 終了させる時はターミナルで
Ctrl + C
-
バッチ ジョブを終了しますか (Y/N)?
と聞かれた場合はY
と入力してEnter
でOK
- 終了させる時はターミナルで
###5. npmで今回必要なものをインストールする
インストールするもの
- webpack-bundle-tracker
- さっきDjangoの
settings.py
で設定したwebpack-stats.json
を吐いてくれるやつ - webpack自体は@vue/cli内部で使われている
- さっきDjangoの
バージョンを指定してwebpack-bundle-trackerをインストールする
-
npm i -D webpack-bundle-tracker@0.4.3
- webpack-bundle-trackerのバージョン0.4.3をインストールしろ、という意味
-
-D
は開発用のdevDependenciesとして登録される -
-D
は--save-dev
でも良い - バージョン指定しないと最新のバージョン1.0.0alpha.1が入ってしまい、これを使うとDjango側で
TypeError: string indices must be integers
のようなエラーが出てしまう
ここまででこんなファイル構成になるはず
-
frontend
フォルダ内にたくさんのファイルができました
###6. Vueプロジェクトの設定ファイルを作る
frontend
フォルダ直下(package.json
と同じ階層)にvue.config.js
というファイルを作る
vue.config.js
に以下のように書く
const BundleTracker = require('webpack-bundle-tracker')
// Change this to match the path to your files in production (could be S3, CloudFront, etc.)
const DEPLOYMENT_PATH = '/static/dist/'
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? DEPLOYMENT_PATH : 'http://localhost:8080/',
outputDir: '../myapp/static/dist',
devServer: {
public: 'localhost:8080',
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
plugins: [
new BundleTracker({ path: __dirname, filename: 'webpack-stats.json' }),
],
},
}
-
outputDir
のところが重要で、ここで一階層上の**myapp
**フォルダ内、その中のstatic
フォルダ内、さらにはその中のdist
フォルダの中にVueアプリで作成したjsなどを吐くことを指定する -
configureWebpack
のところは、webpackの情報を保存しておくファイルのファイル名とディレクトリを指定している(先にDjangoのsettings.py
で指定したwebpack-stats.json
というファイル)
###7. Vueプロジェクトをビルドする
ビルドするとwebpackの情報が入ったwebpack-stats.json
や、Vueプロジェクトファイルなどがバンドルされたファイルが生成される
- そのまま
frontend
フォルダ内でnpm run build
コマンドを実行する
- ファイル構成はこんな感じになる
-
frontend
フォルダ内にwebpack-stats.json
が生成される -
myapp
フォルダ内にstatic
、その中のdist
内にバンドルされたファイルが生成される
-
###8. Djangoに戻り、表示するためのHTMLファイルを作る
Djangoに表示させるためのHTMLファイルを作る
-
-
myapp
フォルダ内にtemplates
フォルダを作る
-
-
-
templates
フォルダ内に再度myapp
フォルダを作る
-
-
- この
myapp
フォルダ内にindex.html
を作る
- Djangoは
templates/<Djangoアプリ名>
という名前のフォルダからHTMLを探します
- この
階層はこうなる
index.html
を以下の内容に編集する
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Vue.js + Django</title>
</head>
<body>
{% load render_bundle from webpack_loader %}
<div id="app">
<app></app>
</div>
{% render_bundle "chunk-vendors" %}
{% render_bundle "app" %}
</body>
</html>
- webpack_loaderの中のrender_bundleをロードし、"chunk-vendors"と"app"を呼び出させるHTML
-
{% load render_bundle from webpack_loader %}
のロードがうまくいかないとDjangoからOSError
で怒られる- その場合は
webpack-stats.json
の正しいパスが指定できていなかったりする
- その場合は
###9. 指定したURLに表示する項目をDjangoで指定する
一番奥のdjango_project
フォルダにあるurls.py
を編集する
- 以下のスクリーンショットでハイライトされている
urls.py
を開く
もともと入っているコードもあるが、それを以下のように追記する
"""django_project URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.views.generic import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('', TemplateView.as_view(template_name='myapp/index.html'), name='myapp_index'),
]
-
path('', ...
というのはURLのrootを叩いた時の表示の設定をしてますよ、という意味- 開発環境の場合 http://127.0.0.1:8000 がrootになる
-
template_name='myapp/index.html'
と指定してあげることで「myapp/templates/myapp/index.html
を開く」とDjangoが理解してくれる -
本来はこのようなURLの設定方法は行わない
- 本来は各アプリに対して
urls.py
を作成し、そこで表示させるURLなどを指定する - 今回は簡便に済ませるために指定したディレクトリにある
index.html
を直接開くようにしている
- 本来は各アプリに対して
###10. Djangoの開発用Webサーバーを立ち上げる
ターミナルに戻り、現在はfrontend
ディレクトリに入っているはずなので一階層上(manage.py
がある階層)まで出る
cd ../
Webサーバーを立ち上げる
python manage.py runserver
ブラウザで http://127.0.0.1:8000/ にアクセスする
Vue.jsを使ったHTMLがDjangoで表示されました!やったね!
##最後に
自分で環境構築する時にうまくいかない時も結構あったので、この記事が誰かの参考になれば幸いです!