├── .env ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── bin ├── cli.py ├── commands.py └── shared.py ├── core ├── __init__.py ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── admin.cpython-36.pyc │ └── models.cpython-36.pyc ├── admin.py ├── apps.py ├── management │ └── commands │ │ ├── __pycache__ │ │ └── rename.cpython-36.pyc │ │ ├── makesuper.py │ │ └── rename.py ├── migrations │ ├── __init__.py │ └── __pycache__ │ │ └── __init__.cpython-36.pyc ├── models.py ├── tests.py └── views.py ├── db.sqlite3 ├── demo ├── __init__.py ├── azure.py ├── settings.py ├── urls.py └── wsgi.py ├── manage.py ├── requirements.txt ├── templates └── base.html └── thumbnail.png /.env: -------------------------------------------------------------------------------- 1 | # - Load the values into your environment before interacting with Azure: 2 | # 3 | # $ # Export values from file into environment: 4 | # $ export $(grep -v '^#' .env | xargs) 5 | # $ # Now interact with (e.g.) the production PosgreSQL instance: 6 | # $ python manage.py showmigrations 7 | 8 | SECRET_KEY='-05sgp9!deq=q1nltm@^^2cc+v29i(tyybv3v2t77qi66czazj' 9 | 10 | # The Azure Resource Group and Location to use for you applicaiton. 11 | # - If using the VS Code App Service extension to create your app, 12 | # use the values it provides 13 | AZ_GROUP='' 14 | AZ_LOCATION='' 15 | 16 | # The name you choose for your App Service application. 17 | APP_SERVICE_APP_NAME='' 18 | 19 | # Server Name, Admin User and Admin Password for creating the Azure 20 | # PostgreSQL server. 21 | 22 | POSTGRES_SERVER_NAME='' 23 | POSTGRES_ADMIN_USER='' 24 | POSTGRES_ADMIN_PASSWORD='' 25 | 26 | # The Azure PostgreSQL server host. 27 | # This will not be available until after creating the database server. 28 | # (Will be output at end if running `./bin/createdb.py`) 29 | POSTGRES_HOST='' 30 | 31 | # The application DB name you want to use. 32 | # `./bin/createdb.py` will offer to create this db after creating the server. 33 | APP_DB_NAME='' 34 | 35 | # The production settings module. 36 | DJANGO_SETTINGS_MODULE='' 37 | 38 | # Once these are set you can run collectstatic to push the staticfiles. 39 | AZ_STORAGE_ACCOUNT_NAME='' 40 | AZ_STORAGE_KEY='' 41 | AZ_STORAGE_CONTAINER='' 42 | 43 | # App Service Deployment Settings for Azure Pipeline 44 | # 45 | # Combine these to give the push URL: 46 | # 47 | # "https://$DEPLOYMENT_USERNAME:$DEPLOYMENT_PASSWORD@$DEPLOYMENT_URL" 48 | # 49 | # git push -f HEAD:master 50 | # 51 | # $ git push -f "https://$DEPLOYMENT_USERNAME:$DEPLOYMENT_PASSWORD@$DEPLOYMENT_URL" HEAD:master 52 | # 53 | # Credentials can be added as secret variable to Azure DevOps Pipelines in order to use `.azure-deploy.yml`. 54 | # 55 | # 56 | # Username and Password for the deployment. 57 | # 58 | # YOU MUST CREATE THESE DEPLOY THE DEPLOYMENT URL WILL BE AVAILABLE. 59 | # 60 | # Create by using the `az` CLI: 61 | # 62 | # $ az webapp deployment user set --user-name --password 63 | # 64 | # Or add in the portal. 65 | # 66 | # App > Deployment Center > Deployment Credentials > User Credentials 67 | DEPLOYMENT_USERNAME='' 68 | DEPLOYMENT_PASSWORD='' 69 | 70 | # The `LocalGit` deployment URL of the App. 71 | # 72 | # You get this when the deployment source is configured. 73 | # You can retrieve it from the portal or via the `az` CLI: 74 | # 75 | # $ az webapp deployment source config-local-git --name= --resource-group= 76 | DEPLOYMENT_URL='' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | env 2 | **/*.pyc 3 | **/__pycache__ 4 | media 5 | .DS_Store 6 | *.sqlite3 7 | *.env 8 | 9 | # Accept these files in the repository 10 | !.gitignore 11 | !.travis.yml 12 | /.env 13 | /.vscode -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.pythonPath": "${workspaceFolder}/env/bin/python3", 3 | "editor.formatOnSave": true, 4 | "python.linting.pycodestyleEnabled": true, 5 | "python.linting.pylintEnabled": true, 6 | "python.linting.pylintPath": "pylint", 7 | "python.linting.pylintArgs": ["W0614", "--load-plugins", "pylint_django"], 8 | "python.venvPath": "${workspaceFolder}/env/bin/python3", 9 | "python.linting.pycodestyleArgs": ["--ignore=E501"], 10 | "files.exclude": { 11 | "**/*.pyc": true 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

3 | 4 | JustDjango 5 | 6 |

7 |

8 | The Definitive Django Learning Platform. 9 |

10 |

11 | 12 | # Django Project Boilerplate 13 | 14 | This repository is a boilerplate Django project for quickly getting started. 15 | 16 |

17 | 18 |

19 | 20 | ## Getting started 21 | 22 | Steps: 23 | 24 | 1. Clone/pull/download this repository 25 | 2. Create a virtualenv with `virtualenv env` and install dependencies with `pip install -r requirements.txt` 26 | 3. Configure your .env variables 27 | 4. Rename your project with `python manage.py rename ` 28 | 29 | This project includes: 30 | 31 | 1. Settings modules for deploying with Azure 32 | 2. Django commands for renaming your project and creating a superuser 33 | 3. A cli tool for setting environment variables for deployment 34 | 35 | --- 36 | 37 |
38 | 39 | Other places you can find us:
40 | 41 | YouTube 42 | Twitter 43 | 44 |
45 | -------------------------------------------------------------------------------- /bin/cli.py: -------------------------------------------------------------------------------- 1 | import click 2 | import os 3 | import subprocess 4 | import sys 5 | 6 | from shared import verify_environment 7 | from commands import ( 8 | settings_command, 9 | create_server_command, 10 | azure_firewall_command, 11 | get_local_ip_firewall_command, 12 | create_db_command, 13 | connect_details_command 14 | ) 15 | 16 | 17 | def get_settings_command(): 18 | verify_environment() 19 | SETTINGS_KEYS = ( 20 | 'SECRET_KEY', 21 | 'POSTGRES_SERVER_NAME', 22 | 'POSTGRES_ADMIN_USER', 23 | 'POSTGRES_ADMIN_PASSWORD', 24 | 'POSTGRES_HOST', 25 | 'APP_DB_NAME', 26 | 'DJANGO_SETTINGS_MODULE', 27 | 'AZ_STORAGE_ACCOUNT_NAME', 28 | 'AZ_STORAGE_CONTAINER', 29 | 'AZ_STORAGE_KEY', 30 | ) 31 | settings_pairs = ['{}={}'.format(k, os.getenv(k)) for k in SETTINGS_KEYS] 32 | return settings_command + settings_pairs 33 | 34 | 35 | @click.command() 36 | @click.option("--check-env", default=False, help="List environment variables.") 37 | @click.option("--deploying", default=False, help="Deploying to Azure.") 38 | def main(check_env, deploying): 39 | """CLI for working with data and deployment""" 40 | if os.getenv("DJANGO_SETTINGS_MODULE") == 'market.azure': 41 | security_check = input( 42 | 'You are currently accessing the Azure environment. Is this what you want to do? [y/n]: ') 43 | if security_check == 'n': 44 | print("Exiting") 45 | exit() 46 | 47 | # if check_env: 48 | # subprocess.call("grep -v '^#' .env | xargs") 49 | 50 | migrate = input("Migrate the database? [y/n]: ") 51 | if migrate == 'y': 52 | process_migrate = subprocess.check_call( 53 | ['python', 'manage.py', 'migrate']) 54 | 55 | prepopulate = input("Prepopulate the database? [y/n]: ") 56 | # TODO: this should be done by default in the migration step 57 | if prepopulate == 'y': 58 | process_makesuper = subprocess.check_call( 59 | ['python', 'manage.py', 'prepopulate']) 60 | 61 | makesuper = input("Create the admin user? [y/n]: ") 62 | if makesuper == 'y': 63 | process_makesuper = subprocess.check_call( 64 | ['python', 'manage.py', 'makesuper']) 65 | 66 | if deploying: 67 | REQUIRED_ENV_VARS = ( 68 | 'AZ_GROUP', 69 | 'AZ_LOCATION', 70 | 'POSTGRES_SERVER_NAME', 71 | 'POSTGRES_ADMIN_USER', 72 | 'POSTGRES_ADMIN_PASSWORD', 73 | 'APP_DB_NAME', 74 | ) 75 | 76 | missing = [] 77 | for v in REQUIRED_ENV_VARS: 78 | if v not in os.environ: 79 | missing.append(v) 80 | if missing: 81 | print("Required Environment Variables Unset:") 82 | print("\t" + "\n\t".join(missing)) 83 | print("Exiting.") 84 | exit() 85 | 86 | create_server = input('Create PostgreSQL server? [y/n]: ') 87 | if create_server == 'y': 88 | print("Creating PostgreSQL server...") 89 | subprocess.check_call(create_server_command) 90 | 91 | create_rule = input('Create firewall rules? [y/n]: ') 92 | local_ip_firewall_command = get_local_ip_firewall_command() 93 | if create_rule == 'y': 94 | print("Allowing access from Azure...") 95 | subprocess.check_call(azure_firewall_command) 96 | print("Allowing access from local IP...") 97 | subprocess.check_call(local_ip_firewall_command) 98 | 99 | create_app_db = input('Create App DB? [y/n]: ') 100 | if create_app_db == 'y': 101 | print("Creating App DB...") 102 | subprocess.check_call(create_db_command) 103 | 104 | print("Getting access details...") 105 | subprocess.check_call(connect_details_command) 106 | 107 | # Connect to Azure using connection string format (to force SSL) 108 | # psql "host=$POSTGRES_HOST sslmode=require port=5432 user=$POSTGRES_ADMIN_USER@$POSTGRES_SERVER_NAME dbname=postgres" -W 109 | 110 | update_azure_env = input("Update the azure environment? [y/n]: ") 111 | if update_azure_env == 'y': 112 | print("Updating App Settings... ") 113 | sys.stdout.flush() 114 | command = get_settings_command() 115 | process_update_env = subprocess.check_call(command) 116 | print("Finished updating app settings") 117 | 118 | print("Exiting...") 119 | sys.exit() 120 | 121 | 122 | if __name__ == '__main__': 123 | main() 124 | -------------------------------------------------------------------------------- /bin/commands.py: -------------------------------------------------------------------------------- 1 | import os 2 | import urllib.request 3 | 4 | 5 | # App service settings 6 | 7 | # https://docs.microsoft.com/en-us/cli/azure/webapp/config/appsettings?view=azure-cli-latest#az-webapp-config-appsettings-set 8 | settings_command = [ 9 | 'az', 'webapp', 'config', 'appsettings', 'set', 10 | '--name', os.getenv('APP_SERVICE_APP_NAME'), 11 | '--resource-group', os.getenv('AZ_GROUP'), 12 | '--settings', 13 | ] 14 | 15 | # Database server 16 | 17 | # Ref: https://docs.microsoft.com/en-gb/cli/azure/postgres/server?view=azure-cli-latest#az-postgres-server-create 18 | # SKUs: https://docs.microsoft.com/en-us/azure/postgresql/concepts-pricing-tiers 19 | # {pricing tier}_{compute generation}_{vCores} 20 | create_server_command = [ 21 | 'az', 'postgres', 'server', 'create', 22 | '--resource-group', os.getenv('AZ_GROUP'), 23 | '--location', os.getenv('AZ_LOCATION'), 24 | '--name', os.getenv('POSTGRES_SERVER_NAME'), 25 | '--admin-user', os.getenv('POSTGRES_ADMIN_USER'), 26 | '--admin-password', os.getenv('POSTGRES_ADMIN_PASSWORD'), 27 | '--sku-name', 'B_Gen5_1', 28 | ] 29 | 30 | # Firewall 31 | 32 | # Ref: https://docs.microsoft.com/en-gb/cli/azure/postgres/server/firewall-rule?view=azure-cli-latest#az-postgres-server-firewall-rule-create 33 | azure_firewall_command = [ 34 | 'az', 'postgres', 'server', 'firewall-rule', 'create', 35 | '--resource-group', os.getenv('AZ_GROUP'), 36 | '--server-name', os.getenv('POSTGRES_SERVER_NAME'), 37 | '--start-ip-address', '0.0.0.0', 38 | '--end-ip-address', '0.0.0.0', 39 | '--name', 'AllowAllAzureIPs', 40 | ] 41 | 42 | 43 | def get_local_ip_firewall_command(): 44 | with urllib.request.urlopen('http://ip.42.pl/raw') as f: 45 | my_ip = f.read() 46 | local_ip_firewall_command = [ 47 | 'az', 'postgres', 'server', 'firewall-rule', 'create', 48 | '--resource-group', os.getenv('AZ_GROUP'), 49 | '--server-name', os.getenv('POSTGRES_SERVER_NAME'), 50 | '--start-ip-address', my_ip, 51 | '--end-ip-address', my_ip, 52 | '--name', 'AllowMyIP', 53 | ] 54 | return local_ip_firewall_command 55 | 56 | 57 | # Database 58 | 59 | create_db_command = [ 60 | 'az', 'postgres', 'db', 'create', 61 | '--resource-group', os.getenv('AZ_GROUP'), 62 | '--server-name', os.getenv('POSTGRES_SERVER_NAME'), 63 | '--name', os.getenv('APP_DB_NAME'), 64 | ] 65 | 66 | connect_details_command = [ 67 | 'az', 'postgres', 'server', 'show', 68 | '--resource-group', os.getenv('AZ_GROUP'), 69 | '--name', os.getenv('POSTGRES_SERVER_NAME'), 70 | ] 71 | 72 | 73 | # TODO: add a Storage CLI command 74 | -------------------------------------------------------------------------------- /bin/shared.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import subprocess 4 | import sys 5 | 6 | # # pass in shell=True if on windows (Note security hazard) 7 | # with open('cli-log.txt', 'w') as f: 8 | # process = subprocess.run(['ls', '-la'], stdout=f, text=True) 9 | 10 | # process2 = subprocess.run( 11 | # ['ls', '-la'], capture_output=True, text=True, check=True) 12 | 13 | # process3 = subprocess.run(['ls', 'la', 'dne'], stderr=subprocess.DEVNULL) 14 | 15 | # process4 = subprocess.run(['grep', '-n', 'cli-log'], 16 | # capture_output=True, text=True, input=process3.stdout) 17 | 18 | # print(process.args) # arguments 19 | # print(process.returncode) # 0 means successful 20 | # print(process.stdout) 21 | # print(process.stdout.decode()) # if we don't pass text as an argument 22 | 23 | 24 | REQUIRED_ENV_VARS = ( 25 | 'AZ_GROUP', 26 | 'AZ_LOCATION', 27 | 'APP_SERVICE_APP_NAME', 28 | 'POSTGRES_SERVER_NAME', 29 | 'POSTGRES_ADMIN_USER', 30 | 'POSTGRES_ADMIN_PASSWORD', 31 | 'APP_DB_NAME', 32 | ) 33 | 34 | 35 | def verify_environment(): 36 | missing = [] 37 | for v in REQUIRED_ENV_VARS: 38 | if v not in os.environ: 39 | missing.append(v) 40 | if missing: 41 | print("Required Environment Variables Unset:") 42 | print("\t" + "\n\t".join(missing)) 43 | print("Exiting.") 44 | exit() 45 | 46 | 47 | if __name__ == '__main__': 48 | verify_environment() 49 | -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/__init__.py -------------------------------------------------------------------------------- /core/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /core/__pycache__/admin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/__pycache__/admin.cpython-36.pyc -------------------------------------------------------------------------------- /core/__pycache__/models.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/__pycache__/models.cpython-36.pyc -------------------------------------------------------------------------------- /core/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /core/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoreConfig(AppConfig): 5 | name = 'core' 6 | -------------------------------------------------------------------------------- /core/management/commands/__pycache__/rename.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/management/commands/__pycache__/rename.cpython-36.pyc -------------------------------------------------------------------------------- /core/management/commands/makesuper.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth import get_user_model 2 | from django.core.management.base import BaseCommand 3 | 4 | 5 | class Command(BaseCommand): 6 | def handle(self, *args, **options): 7 | User = get_user_model() 8 | if not User.objects.filter(username="admin").exists(): 9 | User.objects.create_superuser( 10 | "admin", "admin@domain.com", "admin") 11 | self.stdout.write(self.style.SUCCESS('Admin user has created')) 12 | else: 13 | self.stdout.write(self.style.SUCCESS('Admin user already exists')) 14 | -------------------------------------------------------------------------------- /core/management/commands/rename.py: -------------------------------------------------------------------------------- 1 | import os 2 | from django.core.management.base import BaseCommand 3 | 4 | 5 | class Command(BaseCommand): 6 | help = 'Renames a Django project' 7 | 8 | def add_arguments(self, parser): 9 | parser.add_argument('current', type=str, nargs='+', 10 | help='The current Django project folder name') 11 | parser.add_argument('new', type=str, nargs='+', 12 | help='The new Django project name') 13 | 14 | def handle(self, *args, **kwargs): 15 | current_project_name = kwargs['current'][0] 16 | new_project_name = kwargs['new'][0] 17 | 18 | # logic for renaming the files 19 | 20 | files_to_rename = [f'{current_project_name}/settings.py', 21 | f'{current_project_name}/wsgi.py', 'manage.py'] 22 | 23 | for f in files_to_rename: 24 | with open(f, 'r') as file: 25 | filedata = file.read() 26 | 27 | filedata = filedata.replace(current_project_name, new_project_name) 28 | 29 | with open(f, 'w') as file: 30 | file.write(filedata) 31 | 32 | os.rename(current_project_name, new_project_name) 33 | 34 | self.stdout.write(self.style.SUCCESS( 35 | 'Project has been renamed to %s' % new_project_name)) 36 | -------------------------------------------------------------------------------- /core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/migrations/__init__.py -------------------------------------------------------------------------------- /core/migrations/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/core/migrations/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /core/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /core/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /core/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/db.sqlite3 -------------------------------------------------------------------------------- /demo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/demo/__init__.py -------------------------------------------------------------------------------- /demo/azure.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | from .settings import * 3 | 4 | DEBUG = True 5 | ALLOWED_HOSTS += ['*'] 6 | WSGI_APPLICATION = 'market.wsgi.application' 7 | 8 | AUTH_PASSWORD_VALIDATORS = [ 9 | {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, 10 | {'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator'}, 11 | {'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator'}, 12 | {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, 13 | ] 14 | 15 | DATABASES = { 16 | 'default': { 17 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 18 | 'NAME': os.getenv('APP_DB_NAME'), 19 | 'USER': '{}@{}'.format(os.getenv('POSTGRES_ADMIN_USER'), os.getenv('POSTGRES_SERVER_NAME')), 20 | 'PASSWORD': os.getenv('POSTGRES_ADMIN_PASSWORD'), 21 | 'HOST': os.getenv('POSTGRES_HOST'), 22 | 'PORT': '5432', 23 | 'OPTIONS': {'sslmode': 'require'}, 24 | } 25 | } 26 | 27 | STATICFILES_STORAGE = 'storages.backends.azure_storage.AzureStorage' 28 | AZURE_ACCOUNT_NAME = os.getenv('AZ_STORAGE_ACCOUNT_NAME') 29 | AZURE_CONTAINER = os.getenv('AZ_STORAGE_CONTAINER') 30 | AZURE_ACCOUNT_KEY = os.getenv('AZ_STORAGE_KEY') 31 | -------------------------------------------------------------------------------- /demo/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | ENVIRONMENT = os.getenv('ENVIRONMENT', 'development') 4 | 5 | DEBUG = True 6 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 7 | SECRET_KEY = '-05sgp9!deq=q1nltm@^^2cc+v29i(tyybv3v2t77qi66czazj' 8 | ALLOWED_HOSTS = [] 9 | 10 | INSTALLED_APPS = [ 11 | 'django.contrib.admin', 12 | 'django.contrib.auth', 13 | 'django.contrib.contenttypes', 14 | 'django.contrib.sessions', 15 | 'django.contrib.messages', 16 | 'django.contrib.staticfiles', 17 | 'core' 18 | ] 19 | 20 | MIDDLEWARE = [ 21 | 'django.middleware.security.SecurityMiddleware', 22 | 'django.contrib.sessions.middleware.SessionMiddleware', 23 | 'django.middleware.common.CommonMiddleware', 24 | 'django.middleware.csrf.CsrfViewMiddleware', 25 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 26 | 'django.contrib.messages.middleware.MessageMiddleware', 27 | 'django.middleware.clickjacking.XFrameOptionsMiddleware' 28 | ] 29 | 30 | ROOT_URLCONF = 'demo.urls' 31 | 32 | TEMPLATES = [ 33 | { 34 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 35 | 'DIRS': [os.path.join(BASE_DIR, 'templates')], 36 | 'APP_DIRS': True, 37 | 'OPTIONS': { 38 | 'context_processors': [ 39 | 'django.template.context_processors.debug', 40 | 'django.template.context_processors.request', 41 | 'django.contrib.auth.context_processors.auth', 42 | 'django.contrib.messages.context_processors.messages', 43 | ], 44 | }, 45 | }, 46 | ] 47 | 48 | LANGUAGE_CODE = 'en-us' 49 | TIME_ZONE = 'UTC' 50 | USE_I18N = True 51 | USE_L10N = True 52 | USE_TZ = True 53 | 54 | STATIC_URL = '/static/' 55 | STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static_files')] 56 | STATIC_ROOT = os.path.join(BASE_DIR, 'static') 57 | MEDIA_URL = '/media/' 58 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 59 | 60 | DATABASES = { 61 | "default": { 62 | "ENGINE": "django.db.backends.sqlite3", 63 | "NAME": os.path.join(BASE_DIR, 'db.sqlite3') 64 | } 65 | } 66 | 67 | if ENVIRONMENT == 'production': 68 | DEBUG = False 69 | SECRET_KEY = os.getenv('SECRET_KEY') 70 | SESSION_COOKIE_SECURE = True 71 | SECURE_BROWSER_XSS_FILTER = True 72 | SECURE_CONTENT_TYPE_NOSNIFF = True 73 | SECURE_HSTS_INCLUDE_SUBDOMAINS = True 74 | SECURE_HSTS_SECONDS = 31536000 75 | SECURE_REDIRECT_EXEMPT = [] 76 | SECURE_SSL_REDIRECT = True 77 | SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 78 | -------------------------------------------------------------------------------- /demo/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf import settings 2 | from django.conf.urls.static import static 3 | from django.contrib import admin 4 | from django.urls import path, include 5 | 6 | urlpatterns = [ 7 | path('admin/', admin.site.urls), 8 | ] 9 | 10 | if settings.DEBUG: 11 | urlpatterns += static(settings.STATIC_URL, 12 | document_root=settings.STATIC_ROOT) 13 | urlpatterns += static(settings.MEDIA_URL, 14 | document_root=settings.MEDIA_ROOT) 15 | -------------------------------------------------------------------------------- /demo/wsgi.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from django.core.wsgi import get_wsgi_application 4 | 5 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo.settings') 6 | 7 | application = get_wsgi_application() 8 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | ) from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | autopep8==1.4.4 2 | Django==2.2.13 3 | pep8==1.7.1 4 | pycodestyle==2.5.0 5 | pytz==2018.5 6 | sqlparse==0.2.4 7 | -------------------------------------------------------------------------------- /templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | {% block content %} 11 | {% endblock content %} 12 | 13 | -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/justdjango/django_project_boilerplate/3f4e1a07c1c4c5cc65c3a77c153d4f2165a13511/thumbnail.png --------------------------------------------------------------------------------