├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── backend
├── __init__.py
├── settings.py
├── settingsdev.py
├── templates
│ └── index.html
├── urls.py
├── views.py
└── wsgi.py
├── frontend
├── App.vue
├── assets
│ └── logo.png
└── main.js
├── manage
├── package.json
├── requirements-dev.txt
├── requirements.txt
├── server.js
├── static
└── .gitkeep
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "modules": false }],
4 | "stage-2"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.json]
12 | indent_size = 2
13 |
14 | [.babelrc]
15 | indent_size = 2
16 |
17 | [*.md]
18 | trim_trailing_whitespace = false
19 |
20 | [Makefile]
21 | indent_style = tab
22 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | static/**/*.js
2 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: 'babel-eslint',
4 | parserOptions: {
5 | sourceType: 'module'
6 | },
7 | // https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
8 | extends: 'standard',
9 | // required to lint *.vue files
10 | plugins: [
11 | 'html'
12 | ],
13 | // add your custom rules here
14 | 'rules': {
15 | // allow paren-less arrow functions
16 | 'arrow-parens': 0,
17 | // allow async-await
18 | 'generator-star-spacing': 0,
19 | // allow debugger during development
20 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
21 | // 4 space indentation
22 | 'indent': ['error', 4],
23 | // Allow extra semicolons
24 | 'semi': 0
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | static/dist
4 | npm-debug.log
5 | .idea
6 | .venv
7 | db.sqlite3
8 | webpack-stats.json
9 | __pycache__
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
26 | Author: Rokas Kupstys
27 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Use development settings for running django dev server.
2 | export DJANGO_SETTINGS_MODULE=backend.settingsdev
3 |
4 | # Initializes virtual environment with basic requirements.
5 | prod:
6 | pip install -r requirements.txt
7 | npm install --production
8 |
9 | # Installs development requirements.
10 | dev:
11 | pip install -r requirements.txt
12 | pip install -r requirements-dev.txt
13 | npm install
14 |
15 | # Runs development server.
16 | # This step depends on `make dev`, however dependency is excluded to speed up dev server startup.
17 | run:
18 | npm run dev & python ./manage runserver
19 |
20 | # Creates migrations and migrates database.
21 | # This step depends on `make dev`, however dependency is excluded to speed up dev server startup.
22 | migrate:
23 | python ./manage makemigrations
24 | python ./manage migrate
25 |
26 | # Builds files for distribution which will be placed in /static/dist
27 | build: prod migrate
28 | npm run build
29 |
30 | # Cleans up folder by removing virtual environment, node modules and generated files.
31 | clean:
32 | rm -rf node_modules
33 | rm -rf static/dist
34 |
35 | # Run linter
36 | lint:
37 | @npm run lint --silent
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hello-vue + Django
2 |
3 | This is a boilerplate project for using vuejs with Django.
4 |
5 | ### 中文详细教程
6 | [Django + Vue 单页面应用的开发环境搭建步骤](http://www.jianshu.com/p/fe74907e16b9)
7 |
8 | ### Features
9 | * Django backend in `./backend`
10 | * vuejs (v2) frontend in `./frontend`
11 | * Hot-reload with vue-loader
12 | * eslint linter integration
13 | * Makefile to make your life easy
14 |
15 |
16 | ### Development environment setup
17 |
18 | These steps will install all required dependencies including development ones, run migrations and start dev server.
19 |
20 | ```bash
21 | make dev
22 | make migrate
23 | make run
24 | ```
25 |
26 | ### Deployment
27 |
28 | These steps will install productio dependencies and build vuejs application to `static/dist` folder.
29 |
30 | ```bash
31 | make prod
32 | make build
33 | ```
34 |
35 | ### Be aware
36 |
37 | For the sake of simplicity Django config is contained within it's own backend app. In real world setting you would
38 | probably want to remove `backend` from `INSTALLED_APPS`, create a new app and move `backend.views` to it.
39 |
40 | You probably want to create python virtual environment as well. Default python instance available will be used.
41 |
--------------------------------------------------------------------------------
/backend/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/hello-vue-django/65053fa67dbefaaf41246f232f67ec4c6d7ea23d/backend/__init__.py
--------------------------------------------------------------------------------
/backend/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for backend project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.10.4.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.10/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.10/ref/settings/
11 | """
12 |
13 | import os
14 |
15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17 |
18 | # Quick-start development settings - unsuitable for production
19 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
20 |
21 | # SECURITY WARNING: keep the secret key used in production secret!
22 | SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', 'VERY_SECRET_KEY_THAT_YOU_SHOULD_CHANGE')
23 |
24 | # SECURITY WARNING: don't run with debug turned on in production!
25 | DEBUG = False
26 |
27 | ALLOWED_HOSTS = []
28 |
29 | # Application definition
30 |
31 | INSTALLED_APPS = [
32 | 'django.contrib.admin',
33 | 'django.contrib.auth',
34 | 'django.contrib.contenttypes',
35 | 'django.contrib.sessions',
36 | 'django.contrib.messages',
37 | 'django.contrib.staticfiles',
38 | 'webpack_loader',
39 | 'backend'
40 | ]
41 |
42 | MIDDLEWARE = [
43 | 'django.middleware.security.SecurityMiddleware',
44 | 'django.contrib.sessions.middleware.SessionMiddleware',
45 | 'django.middleware.common.CommonMiddleware',
46 | 'django.middleware.csrf.CsrfViewMiddleware',
47 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
48 | 'django.contrib.messages.middleware.MessageMiddleware',
49 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
50 | ]
51 |
52 | ROOT_URLCONF = 'backend.urls'
53 |
54 | TEMPLATES = [
55 | {
56 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
57 | 'DIRS': [],
58 | 'APP_DIRS': True,
59 | 'OPTIONS': {
60 | 'context_processors': [
61 | 'django.template.context_processors.debug',
62 | 'django.template.context_processors.request',
63 | 'django.contrib.auth.context_processors.auth',
64 | 'django.contrib.messages.context_processors.messages',
65 | ],
66 | },
67 | },
68 | ]
69 |
70 | WSGI_APPLICATION = 'backend.wsgi.application'
71 |
72 | # Database
73 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases
74 |
75 | DATABASES = {
76 | 'default': {
77 | 'ENGINE': 'django.db.backends.sqlite3',
78 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
79 | }
80 | }
81 |
82 | # Password validation
83 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
84 |
85 | AUTH_PASSWORD_VALIDATORS = [
86 | {
87 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
88 | },
89 | {
90 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
91 | },
92 | {
93 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
94 | },
95 | {
96 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
97 | },
98 | ]
99 |
100 | # Internationalization
101 | # https://docs.djangoproject.com/en/1.10/topics/i18n/
102 |
103 | LANGUAGE_CODE = 'en-us'
104 | TIME_ZONE = 'UTC'
105 | USE_I18N = True
106 | USE_L10N = True
107 | USE_TZ = True
108 |
109 | # Static files (CSS, JavaScript, Images)
110 | # https://docs.djangoproject.com/en/1.10/howto/static-files/
111 |
112 | STATIC_URL = '/static/'
113 | STATICFILES_DIRS = [
114 | os.path.join(BASE_DIR, 'static'),
115 | ]
116 |
117 | WEBPACK_LOADER = {
118 | 'DEFAULT': {
119 | 'BUNDLE_DIR_NAME': 'dist/',
120 | 'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/backend/settingsdev.py:
--------------------------------------------------------------------------------
1 | from .settings import *
2 |
3 | DEBUG = True
4 | INTERNAL_IPS = ['127.0.0.1']
5 | ALLOWED_HOSTS += INTERNAL_IPS
6 | ALLOWED_HOSTS.append('localhost')
7 | INSTALLED_APPS.append('debug_toolbar')
8 | MIDDLEWARE.append('debug_toolbar.middleware.DebugToolbarMiddleware')
9 |
--------------------------------------------------------------------------------
/backend/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 | {% load render_bundle from webpack_loader %}
3 |
4 |
5 |
6 | hello-vue
7 |
8 |
9 |
10 | {% render_bundle 'main' %}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/backend/urls.py:
--------------------------------------------------------------------------------
1 | """backend URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf import settings
17 | from django.conf.urls import url, include
18 | from django.contrib import admin
19 |
20 | import backend.views
21 |
22 | urlpatterns = [
23 | url(r'^admin/', admin.site.urls),
24 | url(r'^$', backend.views.index)
25 | ]
26 |
27 | if settings.DEBUG:
28 | import debug_toolbar
29 | urlpatterns.append(url(r'^__debug__/', include(debug_toolbar.urls)))
30 |
--------------------------------------------------------------------------------
/backend/views.py:
--------------------------------------------------------------------------------
1 | from django.shortcuts import render
2 |
3 |
4 | def index(request):
5 | return render(request, 'index.html')
6 |
--------------------------------------------------------------------------------
/backend/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for backend project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "backend.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/frontend/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |

4 |
{{ msg }}
5 |
Essential Links
6 |
12 |
Ecosystem
13 |
19 |
20 |
21 |
22 |
32 |
33 |
61 |
--------------------------------------------------------------------------------
/frontend/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/hello-vue-django/65053fa67dbefaaf41246f232f67ec4c6d7ea23d/frontend/assets/logo.png
--------------------------------------------------------------------------------
/frontend/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | // eslint-disable-next-line no-new
5 | new Vue({
6 | el: '#app',
7 | render: h => h(App)
8 | });
9 |
--------------------------------------------------------------------------------
/manage:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import os
3 | import sys
4 |
5 | if __name__ == '__main__':
6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
7 | try:
8 | from django.core.management import execute_from_command_line
9 | except ImportError:
10 | # The above import may fail for some other reason. Ensure that the
11 | # issue is really that Django is missing to avoid masking other
12 | # exceptions on Python 2.
13 | try:
14 | import django
15 | except ImportError:
16 | raise ImportError(
17 | 'Couldn\'t import Django. Are you sure it\'s installed and '
18 | 'available on your PYTHONPATH environment variable? Did you '
19 | 'forget to activate a virtual environment?'
20 | )
21 | raise
22 | execute_from_command_line(sys.argv)
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hello-vue-django",
3 | "description": "A Vue.js project",
4 | "version": "1.0.0",
5 | "author": " <>",
6 | "private": true,
7 | "scripts": {
8 | "lint": "eslint --ext .js,.vue frontend",
9 | "dev": "cross-env NODE_ENV=development node server.js",
10 | "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
11 | },
12 | "dependencies": {
13 | "vue": "^2.1.0"
14 | },
15 | "devDependencies": {
16 | "babel-core": "^6.0.0",
17 | "babel-eslint": "^7.0.0",
18 | "babel-loader": "^6.0.0",
19 | "babel-preset-es2015": "^6.0.0",
20 | "babel-preset-stage-2": "^6.22.0",
21 | "cross-env": "^3.0.0",
22 | "css-loader": "^0.26.1",
23 | "eslint-friendly-formatter": "^2.0.5",
24 | "eslint-loader": "^1.5.0",
25 | "eslint": "^3.12.2",
26 | "eslint-config-standard": "^6.2.1",
27 | "eslint-plugin-html": "^1.7.0",
28 | "eslint-plugin-promise": "^3.4.0",
29 | "eslint-plugin-standard": "^2.0.1",
30 | "file-loader": "^0.9.0",
31 | "vue-loader": "^10.0.0",
32 | "vue-template-compiler": "^2.1.0",
33 | "webpack": "^2.1.0-beta.25",
34 | "webpack-bundle-tracker": "^0.2.0",
35 | "webpack-dev-server": "^2.1.0-beta.9"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | django-debug-toolbar
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | Django
2 | django-webpack-loader
3 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var WebpackDevServer = require('webpack-dev-server');
3 | var config = require('./webpack.config');
4 |
5 | // Dev server address specified in webpack.config.js
6 | var listen_addr = 'localhost';
7 | // Dev server port specified in webpack.config.js
8 | var listen_port = 8001;
9 |
10 | new WebpackDevServer(webpack(config), {
11 | publicPath: config.output.publicPath,
12 | hot: true,
13 | inline: true,
14 | headers: { "Access-Control-Allow-Origin": "*" },
15 | historyApiFallback: true
16 | }).listen(listen_port, listen_addr, function (err, result)
17 | {
18 | if (err)
19 | {
20 | console.log(err);
21 | }
22 |
23 | console.log('Listening at ' + listen_addr + ':' + listen_port);
24 | });
25 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kele59/hello-vue-django/65053fa67dbefaaf41246f232f67ec4c6d7ea23d/static/.gitkeep
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var BundleTracker = require('webpack-bundle-tracker');
4 |
5 | // Directory for deployed assets. It should be within our static files path.
6 | // Backslash at the end is not required.
7 | var dist_dir = '/static/dist';
8 | // Controls use of hot-reload devserver. When this is used you must also run `node server.js`
9 | var use_hot_reload = process.env.NODE_ENV !== 'production';
10 | // Dev server address specified in server.js
11 | var dev_server_addr = 'localhost';
12 | // Dev server port specified in server.js
13 | var dev_server_port = 8001;
14 |
15 | module.exports = {
16 | entry: ['./frontend/main.js'],
17 | output: {
18 | path: path.resolve(__dirname, '.' + dist_dir + '/'),
19 | filename: '[name]-[hash].js',
20 | publicPath: dist_dir + '/',
21 | },
22 | plugins: [
23 | new BundleTracker({filename: './webpack-stats.json'}),
24 | ],
25 | module: {
26 | rules: [
27 | {
28 | test: /\.vue$/,
29 | loader: 'vue-loader',
30 | options: {
31 | loaders: {
32 | // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
33 | // the "scss" and "sass" values for the lang attribute to the right configs here.
34 | // other preprocessors should work out of the box, no loader config like this nessessary.
35 | 'scss': 'vue-style-loader!css-loader!sass-loader',
36 | 'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
37 | }
38 | // other vue-loader options go here
39 | }
40 | },
41 | {
42 | test: /\.js$/,
43 | loader: 'babel-loader',
44 | exclude: /node_modules/
45 | },
46 | {
47 | test: /\.(png|jpg|gif|svg)$/,
48 | loader: 'file-loader',
49 | options: {
50 | name: '[name].[ext]?[hash]'
51 | }
52 | }
53 | ]
54 | },
55 | resolve: {
56 | alias: {
57 | 'vue$': 'vue/dist/vue.common.js'
58 | }
59 | },
60 | devServer: {
61 | historyApiFallback: true,
62 | noInfo: true
63 | },
64 | performance: {
65 | hints: false
66 | },
67 | devtool: '#eval-source-map'
68 | };
69 |
70 | if (process.env.NODE_ENV === 'production')
71 | {
72 | module.exports.devtool = '#source-map'
73 | // http://vue-loader.vuejs.org/en/workflow/production.html
74 | module.exports.plugins = (module.exports.plugins || []).concat([
75 | new webpack.DefinePlugin({
76 | 'process.env': {
77 | NODE_ENV: '"production"'
78 | }
79 | }),
80 | new webpack.optimize.UglifyJsPlugin({
81 | sourceMap: true,
82 | compress: {
83 | warnings: false
84 | }
85 | }),
86 | new webpack.LoaderOptionsPlugin({
87 | minimize: true
88 | })
89 | ])
90 | }
91 | else if (use_hot_reload)
92 | {
93 | module.exports.entry.push('webpack-dev-server/client?http://' + dev_server_addr + ':' + dev_server_port);
94 | module.exports.entry.push('webpack/hot/only-dev-server');
95 | module.exports.output['publicPath'] = 'http://' + dev_server_addr + ':' + dev_server_port + dist_dir + '/';
96 | module.exports.plugins.push(new webpack.HotModuleReplacementPlugin());
97 | module.exports.plugins.push(new webpack.NoEmitOnErrorsPlugin()); // don't reload if there is an error
98 | }
99 |
--------------------------------------------------------------------------------