3
10

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.

QuasarFramework(Vue.js) + Django でアプリケーション開発(導入編)

Posted at

QuasarFrameworkという、マテリアル風なVue.jsのCSSテンプレートと、Djangoでアプリケーションを作る際の導入部分をまとめました。
今回はDjangoのプロジェクトはすでに作成済み(開発用サーバーが動くところくらいまで)ということで説明をしていきます。

環境

  • mac os High Sierra 10.13.3
  • Djangoのプロジェクトを作成済み

参考

django インストール
https://docs.djangoproject.com/ja/2.0/intro/install/

チュートリアル1
https://docs.djangoproject.com/ja/2.0/intro/tutorial01/

QuasarFramework
http://quasar-framework.org/

ファイル構成

以下のように、backendと、frontendを分けています。

quasar-django

┣ backend/ (今回はDjango)
│ ┣ src/...
│ ┣ ..
│ ┣ ..
│ ┣ ..

┣ frontend/ (今回はQuasarFramework)
│ ┣ src/...
│ │ ┣ static/quasar
│ ┣ ..
│ ┣ ..
│ ┣ ..

QuasarFrameworkを設定する

QuasarFrameworkをinstallする

# quasar cli install
$ npm install -g quasar-cli
# quasar プロジェクトの作成
$ quasar init default quasar-django
$ cd quasar-django
$ npm install

# 確認する
$ quasar dev

QuasarFrameworkの出力モードを変更する

routesの設定を、history modeに変更します

routes.js
...
mode: 'history',
...

config/index.js をhistory mode用に修正します。

...
build: {
  env: require('./prod.env'),
  publicPath: '/',
  productionSourceMap: false,
}
...

ビルドしたファイルの出力先を変更する

ビルドしたファイルの出力先をbackend側に設定します。(quasar buildで出力されるファイルの保存先です。)

staticファイルの出力先を変更します。

script.build.js
targetPath = path.join(__dirname, '../../backend/src/static/quasar')

index.htmlを出力先を変更します。

webpack.prod.conf.js
new HtmlWebpackPlugin({
  filename: path.resolve(__dirname, '../../backend/src/static/quasar/index.html'),
...
}),

webpack.base.conf.jsを修正する。

webpack.base.conf.js
output: {
  path: path.resolve(__dirname, '../../backend/src/static/quasar'),
  publicPath: config[env.prod ? 'build' : 'dev'].publicPath,
  filename: 'js/[name].js',
  chunkFilename: 'js/[id].[chunkhash].js'
},

cssファイルの出力先のcss-utils.jsを修正します。

css-utils.js
...
module.exports.purify = function(cb) {
  var css = glob.sync(path.join(__dirname, '../../backend/src/static/quasar/**/*.css'))
  var js = glob.sync(path.join(__dirname, '../../backend/src/static/quasar/**/*.js'))
...
}

script.clean.jsを修正します。これは、quasar cleanを実行したときに削除されるファイルを削除します。

script.clean.js
shell.rm('-rf', path.resolve(__dirname, '../../backend/src/static/quasar/*'))
shell.rm('-rf', path.resolve(__dirname, '../../backend/src/static/quasar/.*'))

Django側の設定:ハッシュ値が入ったjavascriptファイルをdjangoで読み込む

Djangoで、ハッシュ値が入ったcssファイルを読み込む必要があるため、django-webpack-loaderを使って実装します。

  • $ pip install django-webpack-loader で django-webpack-loaderをinstallする
  • settings.py に以下のように設定を追記する。
settings.py
INSTALLED_APPS = (
  ...
  'webpack_loader'
  ...
  )

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

# 読み込みたいハッシュ値入りのファイルパスが、STATICFILES_DIRS + '/' + BUNDLE_DIR_NAME になるように設定します。例えば、static/quasar/app.hash7.js のようにファイルが配置されている場合、以下のように設定します。
WEBPACK_LOADER = {
    'DEFAULT': {
        'BUNDLE_DIR_NAME': 'quasar/',
        'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json')
    }
}

QuasarFramework側の設定: webpack.prod.conf.js にwebpack-stats.jsonを作成するように設定する

まず、webpack-bundle-trackerをnpm installします。

$ npm install --save-dev webpack-bundle-tracker
webpack.prod.conf.js

var BundleTracker = require('webpack-bundle-tracker')

plugins: [
...  
// ここは、frontend側のフォルダを基準にしてpathを設定する
new BundleTracker({
  filename: '../backend/src/webpack-stats.json'
}),
...
]

あとめちゃめちゃはまったのが、webpack-stats.jsonのpublicPathです。
webpack.prod.conf.js で必ずpublicPathの設定します。これがないと、django側で、render_bundleでrenderingするときに、pathの設定がうまくされません。

webpack.prod.conf.jsに直接指定する場合は以下のように指定します。

output: {
    path: config.build.assetsRoot,
    publicPath: '/static/quasar/',
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  // filename: utils.assetsPath('js/[name].js'),
  // chunkFilename: utils.assetsPath('js/[id].js')
},

もしくは、index.jsにpublicPathを追加して、指定することもできます。

build: {
  env: require('./prod.env'),
  publicPath: '/static/quasar/',
  productionSourceMap: false,

  // Remove unused CSS
  // Disable it if it has side-effects for your specific app
  purifyCSS: true
},

quasar buildを実行して、backend/src/webpack-stats.jsonが出力されていれば成功です。

Django側: index.htmlを作成する

quasar buildで出力されるindex.htmlファイルを利用して, templates/index.htmlファイルを以下のようなコードで作成します。

{% load staticfiles %}
{% load render_bundle from webpack_loader %}

<!DOCTYPE html>
<html lang=en>
  <head>
    <meta charset=utf-8>
    <meta name=format-detection content="telephone=no">
    <meta name=msapplication-tap-highlight content=no>
    <meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width">
    <title>Quasar App</title>
    <link rel=icon href=statics/quasar-logo.png type=image/x-icon>
    <!-- <link href=/static_in_pro/our_static/quasar/app.636237cac568b3b5bca021d177df3447.css rel=stylesheet> -->
    {% render_bundle 'app' 'css' %}
  </head>
  <body>
    <div id=q-app></div>
    <script type=text/javascript src="{% static 'quasar/js/manifest.js' %}"></script>
    <script type=text/javascript src="{% static 'quasar/js/vendor.js' %}"></script>
    <script type=text/javascript src="{% static 'quasar/js/app.js' %}"></script>
  </body>
</html>

また、urls.pyに、上記のindex.htmlのTemplateViewを作成します。

urls.py
from django.urls import path
from django.views.generic import TemplateView

# django2.0 以降では、re-pathを使う
urlpatterns = [
  re_path('.*', TemplateView.as_view(template_name='index.html'), name='index_quasar'),
]

$ python manage.py collticstaticと、$ python manage.py runserverを実行して、http://127.0.0.1:8000/にアクセスして、QuasarFrameworkで作成したページが表示されていれば成功です!

まとめ

初めの設定がちょっと面倒ですが、Djangoは、DjangoRestFrameworkがあるので、フロントエンドと、バックエンドを分けて作成しやすそうですね。

3
10
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
3
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?