├── app ├── __init__.py ├── views.py ├── wsgi.py ├── urls.py ├── templates │ └── base.html └── settings.py ├── assets ├── js │ ├── app.js │ └── vendor.js └── scss │ ├── app.scss │ └── _variables.scss ├── .babelrc ├── .eslintrc.js ├── Pipfile ├── webpack.common.js ├── manage.py ├── LICENSE ├── webpack.dev.js ├── webpack.prod.js ├── README.md ├── package.json ├── .gitignore └── Pipfile.lock /app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/js/app.js: -------------------------------------------------------------------------------- 1 | import '../scss/app.scss' -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /assets/scss/app.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "~bootstrap/scss/bootstrap"; 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "standard", 3 | "installedESLint": true, 4 | "plugins": [ 5 | "standard", 6 | "promise" 7 | ] 8 | }; -------------------------------------------------------------------------------- /assets/js/vendor.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | try { 4 | window.$ = window.jQuery = require('jquery'); 5 | 6 | require('popper.js'); 7 | require('bootstrap'); 8 | } catch (e) {} 9 | -------------------------------------------------------------------------------- /app/views.py: -------------------------------------------------------------------------------- 1 | from django.views.generic import TemplateView 2 | from django.conf import settings 3 | 4 | class Home(TemplateView): 5 | template_name = 'base.html' 6 | 7 | def get_context_data(self, **kwargs): 8 | context = super().get_context_data(**kwargs) 9 | context['settings'] = settings 10 | 11 | return context 12 | 13 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | django = "*" 10 | djangorestframework = "*" 11 | django-webpack-loader = "*" 12 | django-extensions = "*" 13 | ipython = "*" 14 | ipdb = "*" 15 | django-crispy-forms = "*" 16 | werkzeug = "*" 17 | 18 | [requires] 19 | python_version = "3.9" 20 | -------------------------------------------------------------------------------- /assets/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | // Fonts 2 | // 3 | // Font, line-height, and color for body text, headings, and more. 4 | 5 | // stylelint-disable value-keyword-case 6 | $font-family-sans-serif: "Open Sans" !default; 7 | $font-family-monospace: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !default; 8 | $font-family-base: $font-family-sans-serif !default; 9 | -------------------------------------------------------------------------------- /app/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for dist 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/2.2/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', 'app.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | var HtmlWebpackPlugin = require("html-webpack-plugin"); 4 | 5 | module.exports = { 6 | entry: { 7 | app: "./assets/js/app.js", 8 | vendor: "./assets/js/vendor.js" 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /\.html$/, 14 | use: ["html-loader"] 15 | }, 16 | { 17 | test: /\.(svg|png|jpg|gif)$/, 18 | use: { 19 | loader: "file-loader", 20 | options: { 21 | name: "[name].[hash].[ext]", 22 | outputPath: "imgs" 23 | } 24 | } 25 | } 26 | ] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /app/urls.py: -------------------------------------------------------------------------------- 1 | """dist URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.2/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: path('', 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: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path 18 | 19 | from .views import Home 20 | 21 | urlpatterns = [ 22 | path('', Home.as_view(), name='home'), 23 | path('admin/', admin.site.urls), 24 | ] 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ganesh Khade 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const common = require("./webpack.common"); 3 | const { merge } = require("webpack-merge"); 4 | const { CleanWebpackPlugin }= require("clean-webpack-plugin"); 5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | const BundleTracker = require('webpack-bundle-tracker'); 7 | 8 | module.exports = merge(common, { 9 | mode: "development", 10 | output: { 11 | filename: "[name].bundle.js", 12 | path: path.resolve(__dirname, "./assets/bundles/dev"), 13 | publicPath: "/static/dev/", 14 | }, 15 | plugins: [ 16 | new MiniCssExtractPlugin({ filename: "[name].bundle.css" }), 17 | new CleanWebpackPlugin(), 18 | new BundleTracker({path: __dirname, filename: './assets/bundles/dev/stats.json'}) 19 | ], 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.scss$/, 24 | use: [ 25 | "style-loader", //3. Inject styles into DOM 26 | "css-loader", //2. Turns css into commonjs 27 | "sass-loader" //1. Turns sass into css 28 | ] 29 | } 30 | ] 31 | }, 32 | devServer: { 33 | hot: true, 34 | compress: true, 35 | publicPath: '/static/dev/' 36 | }, 37 | }); 38 | -------------------------------------------------------------------------------- /webpack.prod.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const common = require("./webpack.common"); 3 | const { merge }= require("webpack-merge"); 4 | const { CleanWebpackPlugin }= require("clean-webpack-plugin"); 5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 6 | const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin"); 7 | const TerserPlugin = require("terser-webpack-plugin"); 8 | const BundleTracker = require('webpack-bundle-tracker'); 9 | 10 | module.exports = merge(common, { 11 | mode: "production", 12 | output: { 13 | filename: "[name].[contenthash].js", 14 | path: path.resolve(__dirname, "./assets/staticfiles/bundles/"), 15 | publicPath: "/static/bundles/", 16 | }, 17 | optimization: { 18 | minimizer: [ 19 | new OptimizeCssAssetsPlugin(), 20 | new TerserPlugin() 21 | ] 22 | }, 23 | plugins: [ 24 | new MiniCssExtractPlugin({ filename: "[name].[contenthash].css" }), 25 | new CleanWebpackPlugin(), 26 | new BundleTracker({path: __dirname, filename: './assets/staticfiles/bundles/stats.json'}) 27 | ], 28 | module: { 29 | rules: [ 30 | { 31 | test: /\.scss$/, 32 | use: [ 33 | MiniCssExtractPlugin.loader, //3. Extract css into files 34 | "css-loader", //2. Turns css into commonjs 35 | "sass-loader" //1. Turns sass into css 36 | ] 37 | } 38 | ] 39 | } 40 | }); 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Django Webpack Starter 2 | 3 | Hello fellow human. The repo uses 4 | ``` 5 | Python 3.9.* 6 | Django 3.1.* 7 | Webpack 5.4.* 8 | Bootstrap 4.5.* 9 | Pipenv 10 | ``` 11 | If you have any questions tweet me [@khadegd](https://twitter.com/khadegd). 12 | 13 | ## Installing 14 | 15 | Run the following commands. 16 | 17 | ``` 18 | git clone git@github.com:khadegd/django-webpack-starter.git demo 19 | python3 -m venv .venv 20 | source .venv/bin/activate 21 | pip install pipenv 22 | pipenv install 23 | yarn 24 | ``` 25 | 26 | 27 | ### Hot reload: 28 | ``` 29 | Update setting.py -> WEBPACK_LIVE_SERVER = True 30 | yarn start 31 | python manage.py runserver_plus 0.0.0.0:8000 32 | ``` 33 | 34 | 35 | ### One off development build: 36 | ``` 37 | yarn run build-dev 38 | python manage.py runserver_plus 0.0.0.0:8000 39 | ``` 40 | 41 | 42 | ### Production mode: 43 | 44 | ``` 45 | DEBUG = True 46 | yarn run build-prod 47 | python manage.py collectstatic 48 | python manage.py runserver_plus 0.0.0.0:8000 --insecure 49 | ``` 50 | 51 | ## Thanks 52 | 53 | * Colt Steele - [Webpack Course YouTube](https://www.youtube.com/playlist?list=PLblA84xge2_zwxh3XJqy6UVxS60YdusY8) 54 | * Chi Shang Cheng - [Integrating webpack-dev-server with Django](https://cscheng.info/2016/08/03/integrating-webpack-dev-server-with-django.html) 55 | 56 | 57 | ## Authors 58 | 59 | * **Ganesh Khade** - Twitter - [@khadegd](https://twitter.com/khadegd) 60 | 61 | 62 | ## License 63 | 64 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details 65 | 66 | 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "django-webpack-starter", 3 | "version": "1.2.0", 4 | "description": "Django webpack starter.", 5 | "main": "app.js", 6 | "dependencies": { 7 | "babel-loader": "^8.1.0", 8 | "babel-preset-env": "^1.7.0", 9 | "clean-webpack-plugin": "^3.0.0", 10 | "css-loader": "^5.0.1", 11 | "eslint": "^7.12.1", 12 | "file-loader": "^6.2.0", 13 | "html-loader": "^1.3.2", 14 | "html-webpack-plugin": "^4.5.0", 15 | "mini-css-extract-plugin": "^1.2.1", 16 | "node-sass": "^5.0.0", 17 | "optimize-css-assets-webpack-plugin": "^5.0.4", 18 | "sass-loader": "^10.0.5", 19 | "style-loader": "^2.0.0", 20 | "webpack-cli": "^4.2.0", 21 | "webpack-bundle-tracker": "^0.4.3", 22 | "webpack": "^5.4.0", 23 | "webpack-dev-server": "^3.11.0", 24 | "webpack-merge": "^5.3.0" 25 | }, 26 | "devDependencies": { 27 | "bootstrap": "^4.5.3", 28 | "jquery": "^3.5.1", 29 | "popper.js": "^1.16.1" 30 | }, 31 | "scripts": { 32 | "start": "./node_modules/.bin/webpack serve --config webpack.dev.js --progress", 33 | "build-dev": "./node_modules/.bin/webpack --config webpack.dev.js --progress", 34 | "build-prod": "./node_modules/.bin/webpack --config webpack.prod.js", 35 | "test": "echo \"Error: no test specified\" && exit 1" 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "git+https://github.com/khadegd/django-webpack-starter.git" 40 | }, 41 | "keywords": [], 42 | "author": "Ganesh Khade", 43 | "license": "MIT", 44 | "bugs": { 45 | "url": "https://github.com/khadegd/django-webpack-starter/issues" 46 | }, 47 | "homepage": "https://github.com/khadegd/django-webpack-starter#readme" 48 | } 49 | -------------------------------------------------------------------------------- /app/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load render_bundle from webpack_loader %} 2 | 3 | 4 | 5 | 6 | 7 | Example 8 | {% render_bundle 'app' 'css' %} 9 | 10 | 11 | 35 | {% if settings.DEBUG and settings.WEBPACK_LIVE_SERVER %} 36 | 37 | 38 | {% else %} 39 | {% render_bundle 'vendor' 'js' %} 40 | {% render_bundle 'app' 'js' %} 41 | {% endif %} 42 | 43 | 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | assets/bundles/dev/ 2 | 3 | *.egg-info 4 | *.pot 5 | *.py[co] 6 | .tox/ 7 | __pycache__ 8 | MANIFEST 9 | dist/ 10 | docs/_build/ 11 | docs/locale/ 12 | node_modules/ 13 | tests/coverage_html/ 14 | tests/.coverage 15 | build/ 16 | tests/report/ 17 | .vscode 18 | 19 | 20 | # Byte-compiled / optimized / DLL files 21 | __pycache__/ 22 | *.py[cod] 23 | *$py.class 24 | 25 | # C extensions 26 | *.so 27 | 28 | # Distribution / packaging 29 | .Python 30 | build/ 31 | develop-eggs/ 32 | dist/ 33 | downloads/ 34 | eggs/ 35 | .eggs/ 36 | lib/ 37 | lib64/ 38 | parts/ 39 | sdist/ 40 | var/ 41 | wheels/ 42 | pip-wheel-metadata/ 43 | share/python-wheels/ 44 | *.egg-info/ 45 | .installed.cfg 46 | *.egg 47 | MANIFEST 48 | 49 | # PyInstaller 50 | # Usually these files are written by a python script from a template 51 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 52 | *.manifest 53 | *.spec 54 | 55 | # Installer logs 56 | pip-log.txt 57 | pip-delete-this-directory.txt 58 | 59 | # Unit test / coverage reports 60 | htmlcov/ 61 | .tox/ 62 | .nox/ 63 | .coverage 64 | .coverage.* 65 | .cache 66 | nosetests.xml 67 | coverage.xml 68 | *.cover 69 | .hypothesis/ 70 | .pytest_cache/ 71 | 72 | # Translations 73 | *.mo 74 | *.pot 75 | 76 | # Django stuff: 77 | *.log 78 | local_settings.py 79 | db.sqlite3 80 | db.sqlite3-journal 81 | 82 | # Flask stuff: 83 | instance/ 84 | .webassets-cache 85 | 86 | # Scrapy stuff: 87 | .scrapy 88 | 89 | # Sphinx documentation 90 | docs/_build/ 91 | 92 | # PyBuilder 93 | target/ 94 | 95 | # Jupyter Notebook 96 | .ipynb_checkpoints 97 | 98 | # IPython 99 | profile_default/ 100 | ipython_config.py 101 | 102 | # pyenv 103 | .python-version 104 | 105 | # pipenv 106 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 107 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 108 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 109 | # install all needed dependencies. 110 | #Pipfile.lock 111 | 112 | # celery beat schedule file 113 | celerybeat-schedule 114 | 115 | # SageMath parsed files 116 | *.sage.py 117 | 118 | # Environments 119 | .env 120 | .venv 121 | env/ 122 | venv/ 123 | ENV/ 124 | env.bak/ 125 | venv.bak/ 126 | 127 | # Spyder project settings 128 | .spyderproject 129 | .spyproject 130 | 131 | # Rope project settings 132 | .ropeproject 133 | 134 | # mkdocs documentation 135 | /site 136 | 137 | # mypy 138 | .mypy_cache/ 139 | .dmypy.json 140 | dmypy.json 141 | 142 | # Pyre type checker 143 | .pyre/ 144 | 145 | # Logs 146 | logs 147 | *.log 148 | npm-debug.log* 149 | yarn-debug.log* 150 | yarn-error.log* 151 | lerna-debug.log* 152 | 153 | # Diagnostic reports (https://nodejs.org/api/report.html) 154 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 155 | 156 | # Runtime data 157 | pids 158 | *.pid 159 | *.seed 160 | *.pid.lock 161 | 162 | # Directory for instrumented libs generated by jscoverage/JSCover 163 | lib-cov 164 | 165 | # Coverage directory used by tools like istanbul 166 | coverage 167 | *.lcov 168 | 169 | # nyc test coverage 170 | .nyc_output 171 | 172 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 173 | .grunt 174 | 175 | # Bower dependency directory (https://bower.io/) 176 | bower_components 177 | 178 | # node-waf configuration 179 | .lock-wscript 180 | 181 | # Compiled binary addons (https://nodejs.org/api/addons.html) 182 | build/Release 183 | 184 | # Dependency directories 185 | node_modules/ 186 | jspm_packages/ 187 | 188 | # TypeScript v1 declaration files 189 | typings/ 190 | 191 | # TypeScript cache 192 | *.tsbuildinfo 193 | 194 | # Optional npm cache directory 195 | .npm 196 | 197 | # Optional eslint cache 198 | .eslintcache 199 | 200 | # Optional REPL history 201 | .node_repl_history 202 | 203 | # Output of 'npm pack' 204 | *.tgz 205 | 206 | # Yarn Integrity file 207 | .yarn-integrity 208 | 209 | # dotenv environment variables file 210 | .env 211 | .env.test 212 | 213 | # parcel-bundler cache (https://parceljs.org/) 214 | .cache 215 | 216 | # next.js build output 217 | .next 218 | 219 | # nuxt.js build output 220 | .nuxt 221 | 222 | # vuepress build output 223 | .vuepress/dist 224 | 225 | # Serverless directories 226 | .serverless/ 227 | 228 | # FuseBox cache 229 | .fusebox/ 230 | 231 | # DynamoDB Local files 232 | .dynamodb/ 233 | -------------------------------------------------------------------------------- /app/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for app project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.2.4. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.2/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 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = ')u)=q2gh%++e1!h(q5*+sa^nn8ygszg=dqfr7a!0ogzleh=i6k' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = False 27 | 28 | ALLOWED_HOSTS = [ 29 | 'localhost', 30 | '127.0.0.1' 31 | ] 32 | 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = [ 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 44 | # Third party apps 45 | 'webpack_loader', 46 | 'crispy_forms', 47 | 'django_extensions' 48 | ] 49 | 50 | MIDDLEWARE = [ 51 | 'django.middleware.security.SecurityMiddleware', 52 | 'django.contrib.sessions.middleware.SessionMiddleware', 53 | 'django.middleware.common.CommonMiddleware', 54 | 'django.middleware.csrf.CsrfViewMiddleware', 55 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 56 | 'django.contrib.messages.middleware.MessageMiddleware', 57 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 58 | ] 59 | 60 | ROOT_URLCONF = 'app.urls' 61 | 62 | TEMPLATES = [ 63 | { 64 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 65 | 'DIRS': [os.path.join(BASE_DIR, 'app/templates')], 66 | 'APP_DIRS': True, 67 | 'OPTIONS': { 68 | 'context_processors': [ 69 | 'django.template.context_processors.debug', 70 | 'django.template.context_processors.request', 71 | 'django.contrib.auth.context_processors.auth', 72 | 'django.contrib.messages.context_processors.messages', 73 | ], 74 | }, 75 | }, 76 | ] 77 | 78 | WSGI_APPLICATION = 'app.wsgi.application' 79 | 80 | 81 | # Database 82 | # https://docs.djangoproject.com/en/2.2/ref/settings/#databases 83 | 84 | DATABASES = { 85 | 'default': { 86 | 'ENGINE': 'django.db.backends.sqlite3', 87 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 88 | } 89 | } 90 | 91 | 92 | # Password validation 93 | # https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators 94 | 95 | AUTH_PASSWORD_VALIDATORS = [ 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 104 | }, 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 107 | }, 108 | ] 109 | 110 | 111 | # Internationalization 112 | # https://docs.djangoproject.com/en/2.2/topics/i18n/ 113 | 114 | LANGUAGE_CODE = 'en-us' 115 | 116 | TIME_ZONE = 'UTC' 117 | 118 | USE_I18N = True 119 | 120 | USE_L10N = True 121 | 122 | USE_TZ = True 123 | 124 | 125 | # Static files (CSS, JavaScript, Images) 126 | # https://docs.djangoproject.com/en/2.2/howto/static-files/ 127 | 128 | STATIC_URL = '/static/' 129 | 130 | STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') 131 | 132 | STATICFILES_DIRS = [ 133 | os.path.join(BASE_DIR, 'assets/staticfiles'), 134 | ] 135 | 136 | WEBPACK_LOADER = { 137 | 'DEFAULT': { 138 | 'BUNDLE_DIR_NAME': 'bundles/dev/', 139 | 'POLL_INTERVAL': 0.1, 140 | 'TIMEOUT': None, 141 | 'STATS_FILE': os.path.join(BASE_DIR, 'assets/bundles/dev/stats.json') 142 | } 143 | } 144 | 145 | # Live reload server setting 146 | WEBPACK_LIVE_SERVER = False 147 | 148 | if DEBUG and WEBPACK_LIVE_SERVER: 149 | WEBPACK_LIVE_SERVER_CONFIG = { 150 | 'ADDRESS': 'http://localhost:8080/static/dev' 151 | } 152 | 153 | if not DEBUG: 154 | WEBPACK_LOADER.update({ 155 | 'DEFAULT': { 156 | # 'BUNDLE_DIR_NAME': 'bundles/', 157 | 'STATS_FILE': os.path.join(BASE_DIR, 'staticfiles/bundles/stats.json') 158 | } 159 | }) 160 | 161 | CRISPY_TEMPLATE_PACK = 'bootstrap4' 162 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "e25c802ca32f76a63865a03704b4feac5ee234ebe9e294ab22eef0575779119b" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.9" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "asgiref": { 20 | "hashes": [ 21 | "sha256:a5098bc870b80e7b872bff60bb363c7f2c2c89078759f6c47b53ff8c525a152e", 22 | "sha256:cd88907ecaec59d78e4ac00ea665b03e571cb37e3a0e37b3702af1a9e86c365a" 23 | ], 24 | "markers": "python_version >= '3.5'", 25 | "version": "==3.3.0" 26 | }, 27 | "backcall": { 28 | "hashes": [ 29 | "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", 30 | "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" 31 | ], 32 | "version": "==0.2.0" 33 | }, 34 | "decorator": { 35 | "hashes": [ 36 | "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760", 37 | "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7" 38 | ], 39 | "version": "==4.4.2" 40 | }, 41 | "django": { 42 | "hashes": [ 43 | "sha256:14a4b7cd77297fba516fc0d92444cc2e2e388aa9de32d7a68d4a83d58f5a4927", 44 | "sha256:14b87775ffedab2ef6299b73343d1b4b41e5d4e2aa58c6581f114dbec01e3f8f" 45 | ], 46 | "index": "pypi", 47 | "version": "==3.1.3" 48 | }, 49 | "django-crispy-forms": { 50 | "hashes": [ 51 | "sha256:888bb316db89b60050a42ec35080facb361d823eec38010ccb0702f45642d3b8", 52 | "sha256:f2f1e0fbb458851636447cfb6be1a611b40c8ac9e41a74ba923011378670b43b" 53 | ], 54 | "index": "pypi", 55 | "version": "==1.9.2" 56 | }, 57 | "django-extensions": { 58 | "hashes": [ 59 | "sha256:6809c89ca952f0e08d4e0766bc0101dfaf508d7649aced1180c091d737046ea7", 60 | "sha256:dc663652ac9460fd06580a973576820430c6d428720e874ae46b041fa63e0efa" 61 | ], 62 | "index": "pypi", 63 | "version": "==3.0.9" 64 | }, 65 | "django-webpack-loader": { 66 | "hashes": [ 67 | "sha256:7a3c88201aa54481f9399465615cbe7b9aece8081496a6d0287b7cb8e232f447", 68 | "sha256:d28a276ed3d89e97a313b74967e373693f8b86afe629f4c91eea91c5b4f2ec20" 69 | ], 70 | "index": "pypi", 71 | "version": "==0.7.0" 72 | }, 73 | "djangorestframework": { 74 | "hashes": [ 75 | "sha256:5c5071fcbad6dce16f566d492015c829ddb0df42965d488b878594aabc3aed21", 76 | "sha256:d54452aedebb4b650254ca092f9f4f5df947cb1de6ab245d817b08b4f4156249" 77 | ], 78 | "index": "pypi", 79 | "version": "==3.12.1" 80 | }, 81 | "ipdb": { 82 | "hashes": [ 83 | "sha256:c85398b5fb82f82399fc38c44fe3532c0dde1754abee727d8f5cfcc74547b334" 84 | ], 85 | "index": "pypi", 86 | "version": "==0.13.4" 87 | }, 88 | "ipython": { 89 | "hashes": [ 90 | "sha256:c987e8178ced651532b3b1ff9965925bfd445c279239697052561a9ab806d28f", 91 | "sha256:cbb2ef3d5961d44e6a963b9817d4ea4e1fa2eb589c371a470fed14d8d40cbd6a" 92 | ], 93 | "index": "pypi", 94 | "version": "==7.19.0" 95 | }, 96 | "ipython-genutils": { 97 | "hashes": [ 98 | "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", 99 | "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" 100 | ], 101 | "version": "==0.2.0" 102 | }, 103 | "jedi": { 104 | "hashes": [ 105 | "sha256:86ed7d9b750603e4ba582ea8edc678657fb4007894a12bcf6f4bb97892f31d20", 106 | "sha256:98cc583fa0f2f8304968199b01b6b4b94f469a1f4a74c1560506ca2a211378b5" 107 | ], 108 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 109 | "version": "==0.17.2" 110 | }, 111 | "parso": { 112 | "hashes": [ 113 | "sha256:97218d9159b2520ff45eb78028ba8b50d2bc61dcc062a9682666f2dc4bd331ea", 114 | "sha256:caba44724b994a8a5e086460bb212abc5a8bc46951bf4a9a1210745953622eb9" 115 | ], 116 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 117 | "version": "==0.7.1" 118 | }, 119 | "pexpect": { 120 | "hashes": [ 121 | "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", 122 | "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" 123 | ], 124 | "markers": "sys_platform != 'win32'", 125 | "version": "==4.8.0" 126 | }, 127 | "pickleshare": { 128 | "hashes": [ 129 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", 130 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" 131 | ], 132 | "version": "==0.7.5" 133 | }, 134 | "prompt-toolkit": { 135 | "hashes": [ 136 | "sha256:25c95d2ac813909f813c93fde734b6e44406d1477a9faef7c915ff37d39c0a8c", 137 | "sha256:7debb9a521e0b1ee7d2fe96ee4bd60ef03c6492784de0547337ca4433e46aa63" 138 | ], 139 | "markers": "python_full_version >= '3.6.1'", 140 | "version": "==3.0.8" 141 | }, 142 | "ptyprocess": { 143 | "hashes": [ 144 | "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", 145 | "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" 146 | ], 147 | "version": "==0.6.0" 148 | }, 149 | "pygments": { 150 | "hashes": [ 151 | "sha256:381985fcc551eb9d37c52088a32914e00517e57f4a21609f48141ba08e193fa0", 152 | "sha256:88a0bbcd659fcb9573703957c6b9cff9fab7295e6e76db54c9d00ae42df32773" 153 | ], 154 | "markers": "python_version >= '3.5'", 155 | "version": "==2.7.2" 156 | }, 157 | "pytz": { 158 | "hashes": [ 159 | "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268", 160 | "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd" 161 | ], 162 | "version": "==2020.4" 163 | }, 164 | "sqlparse": { 165 | "hashes": [ 166 | "sha256:017cde379adbd6a1f15a61873f43e8274179378e95ef3fede90b5aa64d304ed0", 167 | "sha256:0f91fd2e829c44362cbcfab3e9ae12e22badaa8a29ad5ff599f9ec109f0454e8" 168 | ], 169 | "markers": "python_version >= '3.5'", 170 | "version": "==0.4.1" 171 | }, 172 | "traitlets": { 173 | "hashes": [ 174 | "sha256:178f4ce988f69189f7e523337a3e11d91c786ded9360174a3d9ca83e79bc5396", 175 | "sha256:69ff3f9d5351f31a7ad80443c2674b7099df13cc41fc5fa6e2f6d3b0330b0426" 176 | ], 177 | "markers": "python_version >= '3.7'", 178 | "version": "==5.0.5" 179 | }, 180 | "wcwidth": { 181 | "hashes": [ 182 | "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", 183 | "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" 184 | ], 185 | "version": "==0.2.5" 186 | }, 187 | "werkzeug": { 188 | "hashes": [ 189 | "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43", 190 | "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c" 191 | ], 192 | "index": "pypi", 193 | "version": "==1.0.1" 194 | } 195 | }, 196 | "develop": {} 197 | } 198 | --------------------------------------------------------------------------------