diff --git a/.github/contributors.json b/.github/contributors.json
index 190b81d38..49ebfe4d8 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1302,5 +1302,25 @@
"name": "Abe Hanoka",
"github_login": "abe-101",
"twitter_username": "abe__101"
+ },
+ {
+ "name": "Adin Hodovic",
+ "github_login": "adinhodovic",
+ "twitter_username": ""
+ },
+ {
+ "name": "Leifur Halldor Asgeirsson",
+ "github_login": "leifurhauks",
+ "twitter_username": ""
+ },
+ {
+ "name": "David",
+ "github_login": "buckldav",
+ "twitter_username": ""
+ },
+ {
+ "name": "rguptar",
+ "github_login": "rguptar",
+ "twitter_username": ""
}
]
\ No newline at end of file
diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml
index ee0c547e1..571bdcd02 100644
--- a/.github/workflows/update-contributors.yml
+++ b/.github/workflows/update-contributors.yml
@@ -31,7 +31,7 @@ jobs:
run: python scripts/update_contributors.py
- name: Commit changes
- uses: stefanzweifel/git-auto-commit-action@v4.15.3
+ uses: stefanzweifel/git-auto-commit-action@v4.15.4
with:
commit_message: Update Contributors
file_pattern: CONTRIBUTORS.md .github/contributors.json
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e31055bb1..75d2409cd 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,13 +3,13 @@ default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- repo: https://github.com/asottile/pyupgrade
- rev: v3.2.2
+ rev: v3.2.3
hooks:
- id: pyupgrade
args: [--py310-plus]
@@ -26,7 +26,7 @@ repos:
- id: isort
- repo: https://github.com/PyCQA/flake8
- rev: 5.0.4
+ rev: 6.0.0
hooks:
- id: flake8
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 88f2ab45b..45e784f8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,46 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
+## 2022.11.30
+
+### Changed
+- Add Azure Storage as an option to serve static and media files ([#3967](https://github.com/cookiecutter/cookiecutter-django/pull/3967))
+### Updated
+- Auto-update pre-commit hooks ([#3970](https://github.com/cookiecutter/cookiecutter-django/pull/3970))
+
+## 2022.11.26
+
+### Changed
+- Fix typo in flower start for watching celery ([#3966](https://github.com/cookiecutter/cookiecutter-django/pull/3966))
+
+## 2022.11.24
+
+### Updated
+- Auto-update pre-commit hooks ([#3963](https://github.com/cookiecutter/cookiecutter-django/pull/3963))
+
+## 2022.11.23
+
+### Changed
+- Fix graceful shutdown of local dev containers and use watchfiles for beat + flower ([#3925](https://github.com/cookiecutter/cookiecutter-django/pull/3925))
+- feat(celery): Enable sending the sent task event by default ([#3961](https://github.com/cookiecutter/cookiecutter-django/pull/3961))
+### Updated
+- Bump stefanzweifel/git-auto-commit-action from 4.15.3 to 4.15.4 ([#3940](https://github.com/cookiecutter/cookiecutter-django/pull/3940))
+- Update django-model-utils to 4.3.1 ([#3948](https://github.com/cookiecutter/cookiecutter-django/pull/3948))
+- Update flake8-isort to 5.0.3 ([#3952](https://github.com/cookiecutter/cookiecutter-django/pull/3952))
+
+## 2022.11.22
+
+### Changed
+- Remove USE_L10N due to deprecation ([#3960](https://github.com/cookiecutter/cookiecutter-django/pull/3960))
+- Remove platform from compose file ([#3957](https://github.com/cookiecutter/cookiecutter-django/pull/3957))
+- feat(celery): Send task events for Celery by default ([#3959](https://github.com/cookiecutter/cookiecutter-django/pull/3959))
+### Updated
+- Update python-slugify to 7.0.0 ([#3950](https://github.com/cookiecutter/cookiecutter-django/pull/3950))
+- Update redis to 4.3.5 ([#3954](https://github.com/cookiecutter/cookiecutter-django/pull/3954))
+- Update sentry-sdk to 1.11.1 ([#3955](https://github.com/cookiecutter/cookiecutter-django/pull/3955))
+- Update uvicorn to 0.20.0 ([#3953](https://github.com/cookiecutter/cookiecutter-django/pull/3953))
+- Update tox to 3.27.1 ([#3945](https://github.com/cookiecutter/cookiecutter-django/pull/3945))
+
## 2022.11.11
### Updated
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 86ee9251c..d97324708 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -166,6 +166,13 @@ Listed in alphabetical order.
Richard Hajdu |
diff --git a/README.md b/README.md
index 9f2af6d37..27fc6e0e1 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ production-ready Django projects quickly.
- Optional basic ASGI setup for Websockets
- Optional custom static build using Gulp and livereload
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
-- Media storage using Amazon S3 or Google Cloud Storage
+- Media storage using Amazon S3, Google Cloud Storage or Azure Storage
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku
- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/)
@@ -41,7 +41,7 @@ production-ready Django projects quickly.
*These features can be enabled during initial project setup.*
-- Serve static files from Amazon S3, Google Cloud Storage or [Whitenoise](https://whitenoise.readthedocs.io/)
+- Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/)
- Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only)
- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing
- Integration with [Sentry](https://sentry.io/welcome/) for error logging
diff --git a/cookiecutter.json b/cookiecutter.json
index ec30781cc..984001bb7 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -27,6 +27,7 @@
"cloud_provider": [
"AWS",
"GCP",
+ "Azure",
"None"
],
"mail_service": [
diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst
index 2d8103cf2..0560badd3 100644
--- a/docs/project-generation-options.rst
+++ b/docs/project-generation-options.rst
@@ -66,7 +66,8 @@ cloud_provider:
1. AWS_
2. GCP_
- 3. None
+ 3. Azure_
+ 4. None
Note that if you choose no cloud provider, media files won't work.
@@ -147,6 +148,7 @@ debug:
.. _AWS: https://aws.amazon.com/s3/
.. _GCP: https://cloud.google.com/storage/
+.. _Azure: https://azure.microsoft.com/en-us/products/storage/blobs/
.. _Amazon SES: https://aws.amazon.com/ses/
.. _Mailgun: https://www.mailgun.com
diff --git a/docs/settings.rst b/docs/settings.rst
index b8c6d448e..4691adbbd 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -49,6 +49,9 @@ DJANGO_AWS_S3_CUSTOM_DOMAIN AWS_S3_CUSTOM_DOMAIN n/a
DJANGO_AWS_S3_MAX_MEMORY_SIZE AWS_S3_MAX_MEMORY_SIZE n/a 100_000_000
DJANGO_GCP_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error
GOOGLE_APPLICATION_CREDENTIALS n/a n/a raises error
+DJANGO_AZURE_ACCOUNT_KEY AZURE_ACCOUNT_KEY n/a raises error
+DJANGO_AZURE_ACCOUNT_NAME AZURE_ACCOUNT_NAME n/a raises error
+DJANGO_AZURE_CONTAINER_NAME AZURE_CONTAINER n/a raises error
SENTRY_DSN SENTRY_DSN n/a raises error
SENTRY_ENVIRONMENT n/a n/a production
SENTRY_TRACES_SAMPLE_RATE n/a n/a 0.0
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
index 2845f012c..c3eef1e43 100644
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -72,11 +72,8 @@ if (
sys.exit(1)
if (
- "{{ cookiecutter.cloud_provider }}" == "GCP"
- and "{{ cookiecutter.mail_service }}" == "Amazon SES"
-) or (
- "{{ cookiecutter.cloud_provider }}" == "None"
- and "{{ cookiecutter.mail_service }}" == "Amazon SES"
+ "{{ cookiecutter.mail_service }}" == "Amazon SES"
+ and "{{ cookiecutter.cloud_provider }}" != "AWS"
):
print(
"You should either use AWS or select a different "
diff --git a/requirements.txt b/requirements.txt
index ea9671876..88c8176f1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,12 +7,12 @@ binaryornot==0.4.4
black==22.10.0
isort==5.10.1
flake8==5.0.4
-flake8-isort==5.0.0
+flake8-isort==5.0.3
pre-commit==2.20.0
# Testing
# ------------------------------------------------------------------------------
-tox==3.27.0
+tox==3.27.1
pytest==7.2.0
pytest-cookies==0.6.1
pytest-instafail==0.4.2
diff --git a/setup.py b/setup.py
index ea0d169e3..a388c0b61 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ except ImportError:
from distutils.core import setup
# We use calendar versioning
-version = "2022.11.11"
+version = "2022.11.30"
with open("README.rst") as readme_file:
long_description = readme_file.read()
diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py
index 3a757fcb7..6219f75ef 100755
--- a/tests/test_cookiecutter_generation.py
+++ b/tests/test_cookiecutter_generation.py
@@ -56,6 +56,8 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "AWS", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "use_whitenoise": "y"},
{"cloud_provider": "GCP", "use_whitenoise": "n"},
+ {"cloud_provider": "Azure", "use_whitenoise": "y"},
+ {"cloud_provider": "Azure", "use_whitenoise": "n"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailgun"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailjet"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"},
@@ -82,7 +84,16 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "GCP", "mail_service": "SendinBlue"},
{"cloud_provider": "GCP", "mail_service": "SparkPost"},
{"cloud_provider": "GCP", "mail_service": "Other SMTP"},
- # Note: cloud_providers GCP and None with mail_service Amazon SES is not supported
+ {"cloud_provider": "Azure", "mail_service": "Mailgun"},
+ {"cloud_provider": "Azure", "mail_service": "Mailjet"},
+ {"cloud_provider": "Azure", "mail_service": "Mandrill"},
+ {"cloud_provider": "Azure", "mail_service": "Postmark"},
+ {"cloud_provider": "Azure", "mail_service": "Sendgrid"},
+ {"cloud_provider": "Azure", "mail_service": "SendinBlue"},
+ {"cloud_provider": "Azure", "mail_service": "SparkPost"},
+ {"cloud_provider": "Azure", "mail_service": "Other SMTP"},
+ # Note: cloud_providers GCP, Azure, and None
+ # with mail_service Amazon SES is not supported
{"use_async": "y"},
{"use_async": "n"},
{"use_drf": "y"},
@@ -113,6 +124,7 @@ SUPPORTED_COMBINATIONS = [
UNSUPPORTED_COMBINATIONS = [
{"cloud_provider": "None", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "mail_service": "Amazon SES"},
+ {"cloud_provider": "Azure", "mail_service": "Amazon SES"},
{"cloud_provider": "None", "mail_service": "Amazon SES"},
]
diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django
index bd70b9c47..b6482dbd9 100644
--- a/{{cookiecutter.project_slug}}/.envs/.production/.django
+++ b/{{cookiecutter.project_slug}}/.envs/.production/.django
@@ -44,6 +44,12 @@ DJANGO_AWS_STORAGE_BUCKET_NAME=
# ------------------------------------------------------------------------------
GOOGLE_APPLICATION_CREDENTIALS=
DJANGO_GCP_STORAGE_BUCKET_NAME=
+{% elif cookiecutter.cloud_provider == 'Azure' %}
+# Azure
+# ------------------------------------------------------------------------------
+DJANGO_AZURE_ACCOUNT_KEY=
+DJANGO_AZURE_ACCOUNT_NAME=
+DJANGO_AZURE_CONTAINER_NAME=
{% endif %}
# django-allauth
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
index 433d97de9..e8e69627d 100644
--- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
+++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
@@ -3,14 +3,14 @@ default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- repo: https://github.com/asottile/pyupgrade
- rev: v3.2.2
+ rev: v3.2.3
hooks:
- id: pyupgrade
args: [--py310-plus]
@@ -26,7 +26,7 @@ repos:
- id: isort
- repo: https://github.com/PyCQA/flake8
- rev: 5.0.4
+ rev: 6.0.0
hooks:
- id: flake8
args: ["--config=setup.cfg"]
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start
index c04a7365e..61f83968b 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start
@@ -5,4 +5,4 @@ set -o nounset
rm -f './celerybeat.pid'
-celery -A config.celery_app beat -l INFO
+exec watchfiles celery.__main__.main --args '-A config.celery_app beat -l INFO'
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start
index bd3c9f2fd..ac3cc6b36 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start
@@ -3,9 +3,6 @@
set -o errexit
set -o nounset
-
-celery \
- -A config.celery_app \
- -b "${CELERY_BROKER_URL}" \
- flower \
- --basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}"
+exec watchfiles celery.__main__.main \
+ --args \
+ "-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\""
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start
index 4ddcfa137..16341fdd1 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start
@@ -4,4 +4,4 @@ set -o errexit
set -o nounset
-watchfiles celery.__main__.main --args '-A config.celery_app worker -l INFO'
+exec watchfiles celery.__main__.main --args '-A config.celery_app worker -l INFO'
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/start b/{{cookiecutter.project_slug}}/compose/local/django/start
index 3fe547357..ec57dc8e4 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/start
@@ -7,7 +7,7 @@ set -o nounset
python manage.py migrate
{%- if cookiecutter.use_async == 'y' %}
-uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
+exec uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
{%- else %}
-python manage.py runserver_plus 0.0.0.0:8000
+exec python manage.py runserver_plus 0.0.0.0:8000
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/start b/{{cookiecutter.project_slug}}/compose/local/docs/start
index fd2e0de6a..96a94f566 100644
--- a/{{cookiecutter.project_slug}}/compose/local/docs/start
+++ b/{{cookiecutter.project_slug}}/compose/local/docs/start
@@ -4,4 +4,4 @@ set -o errexit
set -o pipefail
set -o nounset
-make livehtml
+exec make livehtml
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/start b/{{cookiecutter.project_slug}}/compose/production/django/start
index 2ba79501c..73f686bd7 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/start
+++ b/{{cookiecutter.project_slug}}/compose/production/django/start
@@ -28,7 +28,7 @@ if compress_enabled; then
fi
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
-/usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker
+exec /usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker
{%- else %}
-/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
+exec /usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py
index 5b15032c8..8891652d7 100644
--- a/{{cookiecutter.project_slug}}/config/settings/base.py
+++ b/{{cookiecutter.project_slug}}/config/settings/base.py
@@ -30,8 +30,6 @@ LANGUAGE_CODE = "es-MX"
SITE_ID = 1
# https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
USE_I18N = True
-# https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
-USE_L10N = True
# https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True
# https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths
@@ -301,6 +299,10 @@ CELERY_TASK_TIME_LIMIT = 5 * 60
CELERY_TASK_SOFT_TIME_LIMIT = 60
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-scheduler
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#worker-send-task-events
+CELERY_WORKER_SEND_TASK_EVENTS = True
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std-setting-task_send_sent_event
+CELERY_TASK_SEND_SENT_EVENT = True
{%- endif %}
# django-allauth
diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py
index 8eed5a805..40d3f19cc 100644
--- a/{{cookiecutter.project_slug}}/config/settings/production.py
+++ b/{{cookiecutter.project_slug}}/config/settings/production.py
@@ -100,6 +100,10 @@ aws_s3_domain = AWS_S3_CUSTOM_DOMAIN or f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws
{% elif cookiecutter.cloud_provider == 'GCP' %}
GS_BUCKET_NAME = env("DJANGO_GCP_STORAGE_BUCKET_NAME")
GS_DEFAULT_ACL = "publicRead"
+{% elif cookiecutter.cloud_provider == 'Azure' %}
+AZURE_ACCOUNT_KEY = env("DJANGO_AZURE_ACCOUNT_KEY")
+AZURE_ACCOUNT_NAME = env("DJANGO_AZURE_ACCOUNT_NAME")
+AZURE_CONTAINER = env("DJANGO_AZURE_CONTAINER_NAME")
{% endif -%}
{% if cookiecutter.cloud_provider != 'None' or cookiecutter.use_whitenoise == 'y' -%}
@@ -116,6 +120,9 @@ STATIC_URL = f"https://{aws_s3_domain}/static/"
STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootGoogleCloudStorage"
COLLECTFAST_STRATEGY = "collectfast.strategies.gcloud.GoogleCloudStrategy"
STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/"
+{% elif cookiecutter.cloud_provider == 'Azure' -%}
+STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootAzureStorage"
+STATIC_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/"
{% endif -%}
# MEDIA
@@ -126,6 +133,9 @@ MEDIA_URL = f"https://{aws_s3_domain}/media/"
{%- elif cookiecutter.cloud_provider == 'GCP' %}
DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootGoogleCloudStorage"
MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
+{%- elif cookiecutter.cloud_provider == 'Azure' %}
+DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootAzureStorage"
+MEDIA_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/media/"
{%- endif %}
# EMAIL
@@ -228,7 +238,7 @@ COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True)
{%- if cookiecutter.cloud_provider == 'None' %}
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE
COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage"
-{%- elif cookiecutter.cloud_provider in ('AWS', 'GCP') and cookiecutter.use_whitenoise == 'n' %}
+{%- elif cookiecutter.cloud_provider in ('AWS', 'GCP', 'Azure') and cookiecutter.use_whitenoise == 'n' %}
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE
COMPRESS_STORAGE = STATICFILES_STORAGE
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml
index 83433c992..c442809df 100644
--- a/{{cookiecutter.project_slug}}/local.yml
+++ b/{{cookiecutter.project_slug}}/local.yml
@@ -11,7 +11,6 @@ services:
dockerfile: ./compose/local/django/Dockerfile
image: {{ cookiecutter.project_slug }}_local_django
container_name: {{ cookiecutter.project_slug }}_local_django
- platform: linux/x86_64
depends_on:
- postgres
{%- if cookiecutter.use_celery == 'y' %}
@@ -46,7 +45,6 @@ services:
docs:
image: {{ cookiecutter.project_slug }}_local_docs
container_name: {{ cookiecutter.project_slug }}_local_docs
- platform: linux/x86_64
build:
context: .
dockerfile: ./compose/local/docs/Dockerfile
diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml
index 4c1d64c20..ea4292a0d 100644
--- a/{{cookiecutter.project_slug}}/production.yml
+++ b/{{cookiecutter.project_slug}}/production.yml
@@ -11,7 +11,6 @@ services:
context: .
dockerfile: ./compose/production/django/Dockerfile
image: {{ cookiecutter.project_slug }}_production_django
- platform: linux/x86_64
depends_on:
- postgres
- redis
diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt
index 56b3b14f3..bfcd3166b 100644
--- a/{{cookiecutter.project_slug}}/requirements/base.txt
+++ b/{{cookiecutter.project_slug}}/requirements/base.txt
@@ -1,5 +1,5 @@
pytz==2022.6 # https://github.com/stub42/pytz
-python-slugify==6.1.2 # https://github.com/un33k/python-slugify
+python-slugify==7.0.0 # https://github.com/un33k/python-slugify
Pillow==9.3.0 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
@@ -12,7 +12,7 @@ argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %}
whitenoise==6.2.0 # https://github.com/evansd/whitenoise
{%- endif %}
-redis==4.3.4 # https://github.com/redis/redis-py
+redis==4.3.5 # https://github.com/redis/redis-py
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
hiredis==2.0.0 # https://github.com/redis/hiredis-py
{%- endif %}
@@ -24,14 +24,14 @@ flower==1.2.0 # https://github.com/mher/flower
{%- endif %}
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
-uvicorn[standard]==0.19.0 # https://github.com/encode/uvicorn
+uvicorn[standard]==0.20.0 # https://github.com/encode/uvicorn
{%- endif %}
# Django
# ------------------------------------------------------------------------------
django==4.0.8 # pyup: < 4.1 # https://www.djangoproject.com/
django-environ==0.9.0 # https://github.com/joke2k/django-environ
-django-model-utils==4.2.0 # https://github.com/jazzband/django-model-utils
+django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils
django-allauth==0.51.0 # https://github.com/pennersr/django-allauth
django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-crispy-forms
crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index 23d14f1fd..8789b70c3 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -30,7 +30,7 @@ sphinx-rtd-theme==1.0.0 # https://pypi.org/project/sphinx-rtd-theme/
# Code quality
# ------------------------------------------------------------------------------
flake8==5.0.4 # https://github.com/PyCQA/flake8
-flake8-isort==5.0.0 # https://github.com/gforcada/flake8-isort
+flake8-isort==5.0.3 # https://github.com/gforcada/flake8-isort
coverage==6.5.0 # https://github.com/nedbat/coveragepy
black==22.10.0 # https://github.com/psf/black
pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django
diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt
index e2c2046d2..c9b5b88a7 100644
--- a/{{cookiecutter.project_slug}}/requirements/production.txt
+++ b/{{cookiecutter.project_slug}}/requirements/production.txt
@@ -8,7 +8,7 @@ psycopg2==2.9.5 # https://github.com/psycopg/psycopg2
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
-sentry-sdk==1.10.1 # https://github.com/getsentry/sentry-python
+sentry-sdk==1.11.1 # https://github.com/getsentry/sentry-python
{%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
hiredis==2.0.0 # https://github.com/redis/hiredis-py
@@ -20,6 +20,8 @@ hiredis==2.0.0 # https://github.com/redis/hiredis-py
django-storages[boto3]==1.13.1 # https://github.com/jschneier/django-storages
{%- elif cookiecutter.cloud_provider == 'GCP' %}
django-storages[google]==1.13.1 # https://github.com/jschneier/django-storages
+{%- elif cookiecutter.cloud_provider == 'Azure' %}
+django-storages[azure]==1.13.1 # https://github.com/jschneier/django-storages
{%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %}
django-anymail[mailgun]==8.6 # https://github.com/anymail/django-anymail
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py
index b712d3239..27595ad1a 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py
@@ -22,4 +22,15 @@ class StaticRootGoogleCloudStorage(GoogleCloudStorage):
class MediaRootGoogleCloudStorage(GoogleCloudStorage):
location = "media"
file_overwrite = False
+{%- elif cookiecutter.cloud_provider == 'Azure' -%}
+from storages.backends.azure_storage import AzureStorage
+
+
+class StaticRootAzureStorage(AzureStorage):
+ location = "static"
+
+
+class MediaRootAzureStorage(AzureStorage):
+ location = "media"
+ file_overwrite = False
{%- endif %}
|