Commit 2af091e3 authored by Kris Steinhoff's avatar Kris Steinhoff
Browse files

Merge branch 'postgresql-db' into 'master'

Django Template with Local PostgreSQL Database

See merge request !2
parents 62c83545 bc5bf9b2
Pipeline #17697 passed with stage
in 16 seconds
staticfiles/
db.sqlite3
__pycache__/
.DS_Store
.vscode
.git*
[flake8]
# https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/#coding-style
max-line-length=119
exclude=migrations
# https://github.com/github/gitignore/blob/master/Python.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# Django
**/staticfiles
# Misc
.DS_Store
.vscode
\ No newline at end of file
image: "python:3.8-slim"
variables:
PIP_DISABLE_PIP_VERSION_CHECK: 1
stages:
- lint
lint:
stage: lint
script:
- python3 -m pip install -q flake8
- flake8 ./app
# Umich Django Project Template
# {{ project_name }}
Your description for the project goes here.
## Getting Started
These might be instructions for how you run and deploy your project.
## Prerequisites
- Docker
- OpenShift
- Etc.
## Local Development
To build, serve the project at localhost:8000,
```bash
docker-compose build
docker-compose up
```
To stop without removing containers,
```bash
docker-compose stop
```
To stop and remove containers (will delete db),
```bash
docker-compose down -v
```
## Deployment
Add your own deployment instructions here...
\ No newline at end of file
POSTGRES_PASSWORD=passw0rd
version: '3'
services:
app:
build:
context: ./src
args:
ENVIRONMENT: DEVELOPMENT
env_file: ./src/.env
ports:
- 127.0.0.1:${APP_PORT:-8000}:8000
volumes:
- ./src:/usr/src/app
entrypoint: ./docker-entrypoint.sh
command: "python3 manage.py runserver 0.0.0.0:${APP_PORT:-8000} --nostatic"
depends_on:
- db
db:
image: postgres:12-alpine
env_file:
- ./db/.env
ports:
- 127.0.0.1:${DB_PORT:-5432}:5432
volumes:
- postgres-data:/var/lib/pgsql/data
volumes:
postgres-data:
ADMINS=admin=admin-group@umich.edu
ALLOWED_HOSTS=127.0.0.1,localhost
DATABASE_URL=postgresql://postgres:passw0rd@db/postgres
DEBUG=1
# Use this mail relay, if deployed in UM OpenShift cluster
# EMAIL_HOST=vdc-relay.us-east-2.a.mail.umich.edu
# Otherwise, this for UM's unauthenticated mail relay
EMAIL_HOST=mail-relay.itd.umich.edu
EMAIL_SUBJECT_PREFIX=localhost
LOGGING_LEVEL=INFO
SECRET_KEY=123
SERVER_EMAIL=django@localhost
\ No newline at end of file
FROM python:3.8-slim
ARG ENVIRONMENT="PRODUCTION"
ENV GUNICORN_WORKERS=2
ENV GUNICORN_THREADS=4
ENV PYTHONUNBUFFERED=1
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
RUN apt-get -y update && apt-get install -y libpq-dev gcc
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN set -x; \
if [ "${ENVIRONMENT}" = "DEVELOPMENT" ]; then \
pip install -r requirements.txt; \
else \
pip install -r requirements.prod.txt; \
fi;
RUN apt-get purge -y --auto-remove gcc
# Workaround for permission issue on OpenShift
RUN chmod -R g+rw /usr/src/app
EXPOSE 8000
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
CMD ["gunicorn", "--bind=0.0.0.0:8000", "--workers=${GUNICORN_WORKERS}", "--threads=${GUNICORN_THREADS}", "--access-logfile=-", "--log-file=-", "{{ project_name }}.wsgi"]
#!/usr/bin/env bash
set -e
python3 manage.py collectstatic --noinput
python3 manage.py migrate
python3 manage.py check --deploy
exec "${@}"
\ No newline at end of file
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
from django.apps import AppConfig
class OidcAuthConfig(AppConfig):
name = 'oidc_auth'
import unicodedata
from mozilla_django_oidc.auth import OIDCAuthenticationBackend
def generate_username(email):
return unicodedata.normalize('NFKC', email).split('@')[0]
class UMichOIDCBackend(OIDCAuthenticationBackend):
@staticmethod
def _set_claims(user, claims):
user.first_name = claims.get('given_name', '')
user.last_name = claims.get('family_name', '')
def create_user(self, claims):
user = super().create_user(claims)
self._set_claims(user, claims)
user.save()
return user
def update_user(self, user, claims):
self._set_claims(user, claims)
user.save()
return user
# Generated by Django 3.0.4 on 2020-03-27 15:45
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0011_update_proxy_permissions'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
]
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
from django.conf.urls import url
from django.urls import include
urlpatterns = [
url(r'^oidc/', include('mozilla_django_oidc.urls')),
]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment