Skip to content

Instantly share code, notes, and snippets.

@mireq
Last active September 17, 2020 06:17
Show Gist options
  • Save mireq/171b1f0ab9783aa72b0640b418e27c68 to your computer and use it in GitHub Desktop.
Save mireq/171b1f0ab9783aa72b0640b418e27c68 to your computer and use it in GitHub Desktop.
Utility for creating new django project
#!/bin/bash
if [ -e manage.py ]
then
echo "Installing"
else
echo "Not django directory"
exit
fi
SETTINGS_FILE=`cat manage.py|grep DJANGO_SETTINGS_MODULE|sed -e "s/.*[\'\"]\(.*\)[\'\"].*/\1/g"|sed -e 's/\./\//g'`
SETTINGS_FILE="${SETTINGS_FILE}.py"
BASE_APP_DIR=`dirname $SETTINGS_FILE`
BASE_APP_NAME=`basename $BASE_APP_DIR`
unexpand_func () {
unexpand -t 4 --first-only "$1" > "$1.tmp"
mv "$1.tmp" "$1"
}
export -f unexpand_func
find . -not -path '*/\.*' -name "*.py" -exec bash -c 'unexpand_func {}' \;
git init
echo "Creating requirements"
[[ -f requirements.in ]] || cat << 'EOF' > requirements.in
django
EOF
[[ -f requirements.dev ]] || cat << 'EOF' > requirements.dev
django-extensions
django-debugtools
ipython
ptpython
pydotplus
pylint-django
watchdog
werkzeug
EOF
[[ -f run_django.cfg ]] || cat << 'EOF' > run_django.cfg
[DEFAULT]
module = web.wsgi_werkzeug
[*.scss]
command = touch static/css/style.scss
EOF
echo "Creating scripts"
mkdir -p scripts
[[ -f scripts/setenv ]] || cat << 'EOF' > scripts/setenv
#!/bin/bash
dirname="`pwd`/`dirname ${BASH_SOURCE:-$0}`"
dirname=`cd "${dirname}/..";pwd`
export PYTHONPATH=$dirname
export DJANGO_SETTINGS_MODULE=__app_name__.settings_local
export WERKZEUG_DEBUG_PIN=off
source "${dirname}/../venv/bin/activate"
EOF
sed -i -e "s/__app_name__/${BASE_APP_NAME}/g" scripts/setenv
[[ -f scripts/setenv.all ]] || cat << 'EOF' > scripts/setenv.all
#!/bin/bash
venv_squash_mount
. ./scripts/setenv
export TIMETRACK_ENV=1
. set_timetrack_prompt
setopt IGNORE_EOF
EOF
[[ -f scripts/pip-upgrade ]] || cat << 'EOF' > scripts/pip-upgrade
#!/bin/bash
cat requirements.in requirements.dev > requirements.dev.in
pip-compile --upgrade requirements.in
pip-compile --upgrade requirements.dev.in
pip-sync requirements.dev.txt
EOF
chmod +x scripts/pip-upgrade
sed -i -z 's/\/scripts\/setenv\.all\n//g' .git/info/exclude
echo "/scripts/setenv.all" >> .git/info/exclude
sed -i -z "s/\t'${BASE_APP_NAME}',\n//g" $SETTINGS_FILE
sed -zi "s/\(INSTALLED_APPS\s*=\s*\[[^]]*\)\]/\1\t'${BASE_APP_NAME}',\n]/g" $SETTINGS_FILE
if grep --quiet MEDIA_URL $SETTINGS_FILE; then
echo "Settings file updated"
else
sed -z -i "s/TEMPLATES\s*=[^=]*\(\].*\s*=\)/TEMPLATES = [\n\t{\n\t\t'BACKEND': 'django.template.backends.django.DjangoTemplates',\n\t\t'DIRS': [BASE_DIR.joinpath('templates')],\n\t\t'APP_DIRS': True,\n\t\t'OPTIONS': {\n\t\t\t'context_processors': [\n\t\t\t\t'django.template.context_processors.debug',\n\t\t\t\t'django.template.context_processors.request',\n\t\t\t\t'django.template.context_processors.i18n',\n\t\t\t\t'django.contrib.auth.context_processors.auth',\n\t\t\t\t'django.contrib.messages.context_processors.messages',\n\t\t\t],\n\t\t\t'builtins': [\n\t\t\t\t'django.templatetags.static',\n\t\t\t\t'django.templatetags.i18n',\n\t\t\t\t'django.templatetags.l10n',\n\t\t\t],\n\t\t},\n\t},\n\1/g" $SETTINGS_FILE
sed -i -e "s/STATIC_URL.*/STATIC_URL = '\\/static\\/'\nSTATIC_ROOT = BASE_DIR.parent.joinpath('static_assets').joinpath('static')\nSTATICFILES_DIRS = (BASE_DIR.joinpath('static'),)\nSTATICFILES_FINDERS = (\n\t'django.contrib.staticfiles.finders.FileSystemFinder',\n\t'django.contrib.staticfiles.finders.AppDirectoriesFinder',\n)\n\nMEDIA_URL = '\\/media\\/'\nMEDIA_ROOT = BASE_DIR.parent.joinpath('static_assets').joinpath('media')\n/" $SETTINGS_FILE
fi
if grep --quiet Examples $BASE_APP_DIR/urls.py; then
cat << 'EOF' > $BASE_APP_DIR/urls.py
# -*- coding: utf-8 -*-
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
EOF
fi
echo "Creating editorconfig"
[[ -f .editorconfig ]] || cat << 'EOF' > .editorconfig
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = tab
trim_trailing_whitespace = true
EOF
echo "Creating python scripts"
sed -i -z "s/default_app_config.*\n//g" $BASE_APP_DIR/__init__.py
echo "default_app_config = '${BASE_APP_NAME}.apps.AppConfig'" >> $BASE_APP_DIR/__init__.py
[[ -f $BASE_APP_DIR/apps.py ]] || cat << 'EOF' > $BASE_APP_DIR/apps.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import re
from django import apps
class AppConfig(apps.AppConfig):
name = '__app_name__'
verbose_name = '__app_name__'
def ready(self):
self.patch_migrations()
def patch_migrations(self):
from django.db.migrations.writer import MigrationWriter
rx = re.compile('^( )+', flags=re.MULTILINE)
replace = lambda match: '\t'*(len(match.group())//4)
old_as_string = MigrationWriter.as_string
MigrationWriter.as_string = lambda self: rx.sub(replace, old_as_string(self))
EOF
sed -i -e "s/__app_name__/${BASE_APP_NAME}/g" $BASE_APP_DIR/apps.py
[[ -f $BASE_APP_DIR/wsgi_werkzeug.py ]] || cat << 'EOF' > $BASE_APP_DIR/wsgi_werkzeug.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import os
import warnings
warnings.resetwarnings()
warnings.filterwarnings('ignore', message='Not importing directory .*', module='django.utils.encoding')
showwarning = warnings.showwarning
BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def warn_with_filter(message, category, filename, *args):
#if not os.path.abspath(filename).startswith(BASE_DIR):
# return
showwarning(message, category, filename, *args)
warnings.showwarning = warn_with_filter
import logging
from django.contrib.staticfiles.handlers import StaticFilesHandler
from django.core.wsgi import get_wsgi_application
from django.template import TemplateSyntaxError
from django.views import debug
from django.views.debug import technical_500_response
from django_extensions.management.utils import RedirectHandler
from werkzeug.debug import DebuggedApplication
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "__app_name__.settings")
logging.getLogger(__name__)
werklogger = logging.getLogger('werkzeug')
werklogger.setLevel(logging.INFO)
werklogger.addHandler(RedirectHandler(__name__))
werklogger.propagate = False
def forward_technical_500_response(request, exc_type, exc_value, tb, **kwargs):
if request.META['REMOTE_ADDR'] == '127.0.0.1' and exc_type != TemplateSyntaxError:
raise #pylint: disable=misplaced-bare-raise
else:
return technical_500_response(request, exc_type, exc_value, tb, **kwargs)
debug.technical_500_response = forward_technical_500_response
application = DebuggedApplication(StaticFilesHandler(get_wsgi_application()), True)
EOF
sed -i -e "s/__app_name__/${BASE_APP_NAME}/g" $BASE_APP_DIR/wsgi_werkzeug.py
[[ -f $BASE_APP_DIR/settings_local.py.sample ]] || cat << 'EOF' > $BASE_APP_DIR/settings_local.py.sample
# pylint: disable=wildcard-import,unused-wildcard-import
from __future__ import unicode_literals
from .settings import *
ALLOWED_HOSTS = ['*']
DEBUG = True
INSTALLED_APPS = INSTALLED_APPS + [
'django_extensions',
]
EOF
[[ -f $BASE_APP_DIR/settings_local.py ]] || cp $BASE_APP_DIR/settings_local.py.sample $BASE_APP_DIR/settings_local.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment