Merge branch 'new-template' into 'master'

update template to add test and other functions

See merge request ccsolutions.io/open-source/templates/django!1
This commit is contained in:
Andros Fenollosa 2022-08-02 07:07:34 +00:00
commit f07b4d01b9
31 changed files with 330 additions and 192 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
.env
.idea/*
static/admin/
static/django_extensions/
static/django_extensions/
static/rest_framework/

18
Caddyfile.dev Normal file
View File

@ -0,0 +1,18 @@
http://project.localhost {
root * /usr/src/app/
encode gzip zstd
@notStatic {
not path /static/* /media/*
}
reverse_proxy @notStatic django:8000
file_server /static/*
file_server /media/*
}
http://webmail.localhost {
reverse_proxy mailhog:8025
}

View File

@ -1,4 +1,4 @@
http://ccstech.localhost
https://project.com
root * /usr/src/app/

View File

@ -1,4 +1,4 @@
FROM debian:11
FROM python:3.10-slim
# Prevents Python from writing pyc files to disc (equivalent to python -B option)
ENV PYTHONDONTWRITEBYTECODE 1

View File

@ -2,16 +2,16 @@
help:
@perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-25s\033[0m %s\n", $$1, $$2}'
lint: ## Check style with black
black --check --exclude="/(postgres|venv|migrations|\.git)/" .
format: ## Format style with black
black --exclude="/(postgres|venv|migrations|\.git)/" .
black --exclude="/(postgres_data|venv|migrations|\.git)/" core/ apps/ scripts/ tests/
test: ## Tests
docker-compose -f docker-compose.dev.yaml exec -T django bash -c "pytest"
docker.recreate.django: ## Recreate Django image
docker-compose -f docker-compose.yaml build --no-cache --force-rm django
docker-compose -f docker-compose.yaml up --force-recreate --no-deps -d django
make run.loaddata
docker-compose -f docker-compose.dev.yaml build --no-cache --force-rm django
docker-compose -f docker-compose.dev.yaml up --force-recreate --no-deps -d django
## make run.loaddata
run.makemigrations: ## Makemigrations
docker-compose -f docker-compose.yaml exec -T django bash -c "python3 manage.py makemigrations"
@ -21,18 +21,19 @@ run.migrate: ## Migrate
run.loaddata: ## Load initial data
# Remove database
rm -rf database.sqlite
docker-compose exec -T django bash -c "python3 manage.py flush --noinput"
# Remove media
rm -rf media
# Migrate
docker-compose -f docker-compose.yaml exec -T django bash -c "python3 manage.py migrate"
docker-compose exec -T django bash -c "python3 manage.py migrate"
run.loaddata.test: ## Load initial data test
make run.loaddata
# Add superuser: alias "admin" - password "admin"
docker-compose -f docker-compose.yaml exec -T django bash -c "cat data/create_superuser.py | python3 manage.py shell"
# Add more users: alias random - password "password"
docker-compose -f docker-compose.yaml exec -T django bash -c "cat data/create_users.py | python3 manage.py shell"
docker-compose -f docker-compose.dev.yaml exec -T django bash -c "cat data/create_superuser.py | python3 manage.py shell"
run.server: ## Run server
docker-compose -f docker-compose.yaml up
run.server.dev: ## Run server
docker-compose -f docker-compose.dev.yaml up
run.server.pro: ## Run server
docker-compose -f docker-compose.pro.yaml up

View File

@ -8,7 +8,7 @@ make run.server
Now open:
`http://ccstech.localhost`
`http://project.localhost`
## Gulp
@ -68,15 +68,15 @@ make run.loaddata.test
## Other domains
- Caddy: `http://ccstech.localhost`.
- Gulp: `http://ccstech.localhost:3000`.
- Django: `http://ccstech.localhost:8000`.
- Mailhog: `http://ccstech.localhost:8025`.
- Caddy: `http://project.localhost`.
- Gulp: `http://project.localhost:3000`.
- Django: `http://project.localhost:8000`.
- Mailhog: `http://project.localhost:8025`.
### Bash Django
``` shell
docker exec -it ccstech_django_1 bash
docker exec -it project-django bash
```
# Run production
@ -85,4 +85,41 @@ docker exec -it ccstech_django_1 bash
docker-compose -f docker-compose.pro.yaml up
```
Open `https://ccstech.io`.
Open `https://proyect.com`.
# Enviroment (.env)
```text
PROJECT_NAME=project
# Domain
DOMAIN=project.localhost
DOMAIN_URL=http://project.localhost
# Database
DB_NAME=project_db
DB_USER=postgres
DB_PASSWORD=postgres
DB_HOST=postgresql
DB_PORT=5432
# Django options
DJANGO_SECRET_KEY=mysecret
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
# Caddy
CADDY_PORT_ONE=80
CADDY_PORT_TWO=443
# Email
DEFAULT_FROM_EMAIL=no-reply@project.localhost
EMAIL_CONTACT=info@project.localhost
EMAIL_HOST=mailhog
EMAIL_USER=
EMAIL_PASSWORD=
EMAIL_PORT=1025
EMAIL_USE_TLS=False
EMAIL_USE_SSL=False
```

View File

@ -1,6 +0,0 @@
from django.apps import AppConfig
class WebsiteConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app.website'

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

6
apps/website/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class WebsiteConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "apps.website"

7
apps/website/urls.py Normal file
View File

@ -0,0 +1,7 @@
from django.urls import path
from apps.website.views import home
urlpatterns = [
path("", home, name="home"),
]

View File

@ -2,4 +2,4 @@ from django.shortcuts import render
# Create your views here.
def home(request):
return render(request, 'home.html')
return render(request, "home.html")

View File

@ -1,16 +0,0 @@
"""
WSGI config for ccstech project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ccstech.settings')
application = get_wsgi_application()

View File

@ -1,5 +1,5 @@
"""
ASGI config for ccstech project.
ASGI config for core project.
It exposes the ASGI callable as a module-level variable named ``application``.
@ -11,6 +11,6 @@ import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ccstech.settings')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")
application = get_asgi_application()

View File

@ -10,6 +10,7 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
import dj_database_url
from pathlib import Path
from django.db.backends.signals import connection_created
@ -35,39 +36,40 @@ if not os.environ.get("ALLOWED_HOSTS") == None:
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'app.website',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_extensions",
"rest_framework",
"apps.website",
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = 'ccstech.urls'
ROOT_URLCONF = "core.urls"
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "app", "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(BASE_DIR, "app", "templates")],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
@ -78,14 +80,9 @@ TEMPLATES = [
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": os.environ.get("DB_ENGINE"),
"NAME": os.environ.get("DB_NAME"),
"USER": os.environ.get("DB_USER"),
"PASSWORD": os.environ.get("DB_PASSWORD"),
"HOST": os.environ.get("DB_HOST"),
"PORT": os.environ.get("DB_PORT"),
}
"default": dj_database_url.config(
default=f"postgres://{os.environ.get('DB_USER')}:{os.environ.get('DB_PASSWORD')}@{os.environ.get('DB_HOST')}:{os.environ.get('DB_PORT')}/{os.environ.get('DB_NAME')}"
)
}
# Password validation
@ -93,16 +90,16 @@ DATABASES = {
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
@ -110,9 +107,9 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'es-es'
LANGUAGE_CODE = "es-es"
TIME_ZONE = 'UTC'
TIME_ZONE = "UTC"
USE_I18N = True
@ -152,12 +149,10 @@ CHANNEL_LAYERS = {
}
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
if DEBUG:
CACHES = {

View File

@ -1,4 +1,4 @@
"""ccstech URL Configuration
"""template URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
@ -14,10 +14,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from app.website import views as website_views
from django.urls import path, include
urlpatterns = [
path('', website_views.home, name='home'),
path('admin/', admin.site.urls),
path("", include("apps.website.urls")),
path("admin/", admin.site.urls),
]

View File

@ -12,6 +12,6 @@ python3 manage.py migrate
# Start server
echo "Starting server"
## With WebSockets
uvicorn --host 0.0.0.0 --port 8000 --reload ccstech.asgi:application
## without WebSockets
#gunicorn --workers=4 -b 0.0.0.0:8000 --reload ccstech.wsgi:application
python3 manage.py runserver 0.0.0.0:8000
#echo "*****Start server with production mode*****"
#daphne -b 0.0.0.0 -p 8000 core.asgi:application

80
docker-compose.dev.yaml Normal file
View File

@ -0,0 +1,80 @@
version: '3.8'
services:
postgresql:
image: postgres
container_name: ${PROJECT_NAME}-postgresql
restart: "no"
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- ${DB_PORT}:5432
django:
build:
context: ./
dockerfile: ./Dockerfiles/django/Dockerfile
container_name: ${PROJECT_NAME}-django
restart: "no"
entrypoint: /django-launcher.sh
volumes:
- .:/usr/src/app/
environment:
DEBUG: "False"
ALLOWED_HOSTS: ${DOMAIN}
SECRET_KEY: ${DJANGO_SECRET_KEY}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DOMAIN: ${DOMAIN}
DOMAIN_URL: ${DOMAIN_URL}
STATIC_URL: /static/
STATIC_ROOT: static
MEDIA_URL: /media/
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
EMAIL_HOST: ${EMAIL_HOST}
EMAIL_USE_TLS: ${EMAIL_USE_TLS}
EMAIL_USE_SSL: ${EMAIL_USE_SSL}
EMAIL_PORT: ${EMAIL_PORT}
EMAIL_USER: ${EMAIL_USER}
EMAIL_PASSWORD: ${EMAIL_PASSWORD}
expose:
- 8000
depends_on:
- postgresql
links:
- redis
caddy:
image: caddy:alpine
container_name: ${PROJECT_NAME}-caddy
restart: "no"
ports:
- ${CADDY_PORT_ONE}:80
- ${CADDY_PORT_TWO}:443
volumes:
- ./Caddyfile.dev:/etc/caddy/Caddyfile
- ./caddy_data:/data
- .:/usr/src/app/
depends_on:
- django
redis:
image: redis:alpine
container_name: ${PROJECT_NAME}-redis
restart: "no"
expose:
- ${REDIS_PORT}
mailhog:
image: mailhog/mailhog:latest
container_name: ${PROJECT_NAME}-mailhog
restart: "no"
expose:
- 1025

73
docker-compose.pro.yaml Normal file
View File

@ -0,0 +1,73 @@
version: '3.8'
services:
postgresql:
image: postgres
container_name: ${PROJECT_NAME}-postgresql
restart: always
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- ${DB_PORT}:5432
django:
build:
context: ./
dockerfile: ./Dockerfiles/django/Dockerfile
container_name: ${PROJECT_NAME}-django
restart: always
entrypoint: /django-launcher.sh
volumes:
- .:/usr/src/app/
environment:
DEBUG: "False"
ALLOWED_HOSTS: ${DOMAIN}
SECRET_KEY: ${DJANGO_SECRET_KEY}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DOMAIN: ${DOMAIN}
DOMAIN_URL: ${DOMAIN_URL}
STATIC_URL: /static/
STATIC_ROOT: static
MEDIA_URL: /media/
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
EMAIL_HOST: ${EMAIL_HOST}
EMAIL_USE_TLS: ${EMAIL_USE_TLS}
EMAIL_USE_SSL: ${EMAIL_USE_SSL}
EMAIL_PORT: ${EMAIL_PORT}
EMAIL_USER: ${EMAIL_USER}
EMAIL_PASSWORD: ${EMAIL_PASSWORD}
expose:
- 8000
depends_on:
- postgresql
links:
- redis
caddy:
image: caddy:alpine
container_name: ${PROJECT_NAME}-caddy
restart: always
ports:
- ${CADDY_PORT_ONE}:80
- ${CADDY_PORT_TWO}:443
volumes:
- ./Caddyfile.pro:/etc/caddy/Caddyfile
- ./caddy_data:/data
- .:/usr/src/app/
depends_on:
- django
redis:
image: redis:alpine
container_name: ${PROJECT_NAME}-redis
restart: always
expose:
- ${REDIS_PORT}

View File

@ -1,75 +0,0 @@
version: '3.8'
services:
postgresql:
image: postgres
restart: "no"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
POSTGRES_DB: "ccstech"
ports:
- 5432:5432
django:
build:
context: ./
dockerfile: ./Dockerfiles/django/Dockerfile
restart: "no"
entrypoint: /django-launcher.sh
volumes:
- .:/usr/src/app/
environment:
DEBUG: "True"
ALLOWED_HOSTS: "ccstech.localhost"
SECRET_KEY: "misecreto"
DB_ENGINE: "django.db.backends.postgresql"
DB_NAME: "ccstech"
DB_USER: "postgres"
DB_PASSWORD: "postgres"
DB_HOST: "postgresql"
DB_PORT: "5432"
DOMAIN: "ccstech.localhost"
DOMAIN_URL: "http://ccstech.localhost"
STATIC_URL: "/static/"
STATIC_ROOT: "static"
MEDIA_URL: "/media/"
REDIS_HOST: "redis"
REDIS_PORT: "6379"
EMAIL_HOST: "mailhog"
EMAIL_USE_TLS: "False"
EMAIL_PORT: "1025"
EMAIL_USER: ""
EMAIL_PASSWORD: ""
expose:
- 8000
depends_on:
- postgresql
caddy:
image: caddy:alpine
restart: "no"
ports:
- 80:80
- 443:443
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- ./caddy_data:/data
- .:/usr/src/app/
depends_on:
- django
redis:
image: redis:alpine
restart: "no"
expose:
- 6379
mailhog:
image: mailhog/mailhog:latest
restart: "no"
expose:
- 1025
ports:
- 8025:8025

View File

@ -6,7 +6,7 @@ import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ccstech.settings')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:

5
pytest.ini Normal file
View File

@ -0,0 +1,5 @@
[pytest]
DJANGO_SETTINGS_MODULE = core.settings
# -- recommended but optional:
python_files = test_*.py

View File

@ -1,18 +1,31 @@
# Django
django===4.0.5
django-extensions===3.1.5
django===4.0.6
django-extensions===3.2.0
dj-database-url==0.5.0
# Django REST
djangorestframework==3.13.1
django-cors-headers==3.10.0
# PostgreSQL driver
psycopg2-binary===2.9.3
# Servidor para Django sin Websockets
gunicorn===20.1.0
# Servidor para Django con Websockets
uvicorn===0.18.1
websockets===10.3
# Channels
channels==3.0.5
# Check connection
redis==4.3.4
# Django Server
daphne===3.0.2
asgiref===3.5.2
# Conector de Redis para Channels
channels_redis===3.4.0
# Template
# Pillow
Pillow===9.1.1
# Templates
## Image processing
Pillow===9.2.0
# Testing
pytest==7.1.2
pytest-django==4.5.2
# Quality code
black==22.6.0
flake8==4.0.1
isort==5.10.1

0
scripts/__ini__.py Normal file
View File

0
tests/__ini__.py Normal file
View File

3
tests/test_start.py Normal file
View File

@ -0,0 +1,3 @@
def test_hello_world():
assert "hello_world" == "hello_world"
assert "foo" != "bar"