diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
index e39803fa9..61f839cf6 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -7,5 +7,5 @@ labels: question
First, make sure to examine [the docs](https://cookiecutter-django.readthedocs.io/en/latest/). If that doesn't help, we recommend one of these 3 main channels:
- If your issue is related to Django + something else but was generated with cookiecutter-django, the best is to post a question on [StackOverflow](https://stackoverflow.com/questions/tagged/cookiecutter-django) tagged with `cookiecutter-django`, you would get more visibility from other communities as well.
-- Join us on [Discord](https://discord.gg/bTfDa6Zz) and ask around.
+- Join us on [Discord](https://discord.gg/uFXweDQc5a) and ask around.
- Start [a discussion](https://github.com/cookiecutter/cookiecutter-django/discussions) on our project's GitHub.
diff --git a/.github/contributors.json b/.github/contributors.json
index 8fd9c258b..3d59b17bb 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1227,5 +1227,75 @@
"name": "Abdullah Adeel",
"github_login": "mabdullahadeel",
"twitter_username": "abdadeel_"
+ },
+ {
+ "name": "Jorge Valdez",
+ "github_login": "jorgeavaldez",
+ "twitter_username": ""
+ },
+ {
+ "name": "Ryan Fitch",
+ "github_login": "ryfi",
+ "twitter_username": ""
+ },
+ {
+ "name": "ghazi-git",
+ "github_login": "ghazi-git",
+ "twitter_username": ""
+ },
+ {
+ "name": "Cebrail Yılmaz",
+ "github_login": "b1sar",
+ "twitter_username": ""
+ },
+ {
+ "name": "Artur Barseghyan",
+ "github_login": "barseghyanartur",
+ "twitter_username": ""
+ },
+ {
+ "name": "innicoder",
+ "github_login": "innicoder",
+ "twitter_username": ""
+ },
+ {
+ "name": "Naveen",
+ "github_login": "naveensrinivasan",
+ "twitter_username": "snaveen"
+ },
+ {
+ "name": "Nikita Sobolev",
+ "github_login": "sobolevn",
+ "twitter_username": ""
+ },
+ {
+ "name": "Sebastian Reyes Espinosa",
+ "github_login": "sebastian-code",
+ "twitter_username": "sebastianreyese"
+ },
+ {
+ "name": "jugglinmike",
+ "github_login": "jugglinmike",
+ "twitter_username": ""
+ },
+ {
+ "name": "monosans",
+ "github_login": "monosans",
+ "twitter_username": ""
+ },
+ {
+ "name": "Marcio Mazza",
+ "github_login": "marciomazza",
+ "twitter_username": "marciomazza"
+ },
+ {
+ "name": "Brandon Rumiser",
+ "github_login": "brumiser1550",
+ "twitter_username": ""
+ },
+ {
+ "name": "krati yadav",
+ "github_login": "krati5",
+ "twitter_username": ""
}
]
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0180184fa..d466f4032 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,17 +4,21 @@ on:
push:
pull_request:
+concurrency:
+ group: ${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
jobs:
lint:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
- name: Run pre-commit
- uses: pre-commit/action@v2.0.3
+ uses: pre-commit/action@v3.0.0
tests:
strategy:
@@ -28,10 +32,10 @@ jobs:
name: "Run tests"
runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
- name: Install dependencies
run: pip install -r requirements.txt
@@ -46,7 +50,7 @@ jobs:
- name: Basic
args: ""
- name: Extended
- args: "use_celery=y use_drf=y js_task_runner=Gulp"
+ args: "use_celery=y use_drf=y frontend_pipeline=Gulp"
name: "${{ matrix.script.name }} Docker"
runs-on: ubuntu-latest
@@ -55,10 +59,10 @@ jobs:
COMPOSE_DOCKER_CLI_BUILD: 1
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
- name: Install dependencies
run: pip install -r requirements.txt
@@ -71,12 +75,12 @@ jobs:
matrix:
script:
- name: With Celery
- args: "use_celery=y use_compressor=y"
+ args: "use_celery=y frontend_pipeline='Django Compressor'"
- name: With Gulp
- args: "js_task_runner=Gulp custom_bootstrap_compilation=y"
+ args: "frontend_pipeline='Gulp'"
- runs-on: ubuntu-latest
name: "${{ matrix.script.name }} Bare metal"
+ runs-on: ubuntu-latest
services:
redis:
image: redis:5.0
@@ -95,10 +99,10 @@ jobs:
DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres"
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
cache-dependency-path: |
requirements.txt
@@ -106,7 +110,7 @@ jobs:
{{cookiecutter.project_slug}}/requirements/local.txt
- name: Install dependencies
run: pip install -r requirements.txt
- - uses: actions/setup-node@v2
+ - uses: actions/setup-node@v3
with:
node-version: "16"
- name: Bare Metal ${{ matrix.script.name }}
diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml
index 1118e1b23..fd250604f 100644
--- a/.github/workflows/django-issue-checker.yml
+++ b/.github/workflows/django-issue-checker.yml
@@ -16,10 +16,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml
index e92816101..1708e8b82 100644
--- a/.github/workflows/pre-commit-autoupdate.yml
+++ b/.github/workflows/pre-commit-autoupdate.yml
@@ -8,17 +8,23 @@ on:
- cron: "15 2 * * *"
workflow_dispatch: # to trigger manually
+permissions:
+ contents: read
+
jobs:
auto-update:
# Disables this workflow from running in a repository that is not part of the indicated organization/user
if: github.repository_owner == 'cookiecutter'
+ permissions:
+ contents: write # for peter-evans/create-pull-request to create branch
+ pull-requests: write # for peter-evans/create-pull-request to create a PR
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
+ - uses: actions/checkout@v3
+ - uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: Install pre-commit
run: pip install pre-commit
@@ -31,7 +37,7 @@ jobs:
run: pre-commit autoupdate
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v3.12.0
+ uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update/pre-commit-autoupdate
diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml
index 00065c05b..27113a89f 100644
--- a/.github/workflows/update-changelog.yml
+++ b/.github/workflows/update-changelog.yml
@@ -14,12 +14,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml
index 335159444..75dc2c3e0 100644
--- a/.github/workflows/update-contributors.yml
+++ b/.github/workflows/update-contributors.yml
@@ -5,19 +5,24 @@ on:
branches:
- master
+permissions:
+ contents: read
+
jobs:
build:
# Disables this workflow from running in a repository that is not part of the indicated organization/user
if: github.repository_owner == 'cookiecutter'
+ permissions:
+ contents: write # for stefanzweifel/git-auto-commit-action to push code in repo
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
- python-version: "3.9"
+ python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
@@ -26,7 +31,7 @@ jobs:
run: python scripts/update_contributors.py
- name: Commit changes
- uses: stefanzweifel/git-auto-commit-action@v4.13.1
+ uses: stefanzweifel/git-auto-commit-action@v4.15.2
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 63add8bf5..6d22c2e84 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,13 +3,20 @@ default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.1.0
+ rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: check-yaml
+ - repo: https://github.com/asottile/pyupgrade
+ rev: v3.1.0
+ hooks:
+ - id: pyupgrade
+ args: [--py310-plus]
+ exclude: hooks/
+
- repo: https://github.com/psf/black
- rev: 21.12b0
+ rev: 22.10.0
hooks:
- id: black
@@ -19,7 +26,7 @@ repos:
- id: isort
- repo: https://github.com/PyCQA/flake8
- rev: 4.0.1
+ rev: 5.0.4
hooks:
- id: flake8
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b2fb058b4..da352847b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,597 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
+## 2022.10.24
+
+### Changed
+- Upgrade Python version from 3.9 to 3.10 ([#3913](https://github.com/cookiecutter/cookiecutter-django/pull/3913))
+### Updated
+- Update sentry-sdk to 1.10.1 ([#3911](https://github.com/cookiecutter/cookiecutter-django/pull/3911))
+- Bump stefanzweifel/git-auto-commit-action from 4.15.1 to 4.15.2 ([#3914](https://github.com/cookiecutter/cookiecutter-django/pull/3914))
+
+## 2022.10.19
+
+### Changed
+- Set AWS_S3_MAX_MEMORY_SIZE ([#3810](https://github.com/cookiecutter/cookiecutter-django/pull/3810))
+- Upgrade to Django 4.0 ([#3848](https://github.com/cookiecutter/cookiecutter-django/pull/3848))
+### Updated
+- Update pytz to 2022.5 ([#3906](https://github.com/cookiecutter/cookiecutter-django/pull/3906))
+- Update sphinx to 5.3.0 ([#3905](https://github.com/cookiecutter/cookiecutter-django/pull/3905))
+- Update django-celery-beat to 2.4.0 ([#3908](https://github.com/cookiecutter/cookiecutter-django/pull/3908))
+- Update watchfiles to 0.18.0 ([#3907](https://github.com/cookiecutter/cookiecutter-django/pull/3907))
+
+## 2022.10.13
+
+### Updated
+- Update pygithub to 1.56 ([#3904](https://github.com/cookiecutter/cookiecutter-django/pull/3904))
+
+## 2022.10.11
+
+### Updated
+- Auto-update pre-commit hooks ([#3899](https://github.com/cookiecutter/cookiecutter-django/pull/3899))
+- Update flake8-isort to 5.0.0 ([#3901](https://github.com/cookiecutter/cookiecutter-django/pull/3901))
+- Update gitpython to 3.1.29 ([#3902](https://github.com/cookiecutter/cookiecutter-django/pull/3902))
+- Update psycopg2 to 2.9.4 ([#3896](https://github.com/cookiecutter/cookiecutter-django/pull/3896))
+- Bump stefanzweifel/git-auto-commit-action from 4.15.0 to 4.15.1 ([#3903](https://github.com/cookiecutter/cookiecutter-django/pull/3903))
+- Update black to 22.10.0 ([#3898](https://github.com/cookiecutter/cookiecutter-django/pull/3898))
+
+## 2022.10.04
+
+### Updated
+- Update django to 3.2.16 ([#3895](https://github.com/cookiecutter/cookiecutter-django/pull/3895))
+- Update mypy to 0.982 ([#3893](https://github.com/cookiecutter/cookiecutter-django/pull/3893))
+- Auto-update pre-commit hooks ([#3894](https://github.com/cookiecutter/cookiecutter-django/pull/3894))
+
+## 2022.10.03
+
+### Updated
+- Update sentry-sdk to 1.9.10 ([#3892](https://github.com/cookiecutter/cookiecutter-django/pull/3892))
+
+## 2022.10.02
+
+### Updated
+- Update pytz to 2022.4 ([#3891](https://github.com/cookiecutter/cookiecutter-django/pull/3891))
+
+## 2022.09.30
+
+### Updated
+- Update coverage to 6.5.0 ([#3890](https://github.com/cookiecutter/cookiecutter-django/pull/3890))
+- Update mypy to 0.981 ([#3889](https://github.com/cookiecutter/cookiecutter-django/pull/3889))
+- Update sentry-sdk to 1.9.9 ([#3888](https://github.com/cookiecutter/cookiecutter-django/pull/3888))
+- Update sphinx to 5.2.3 ([#3887](https://github.com/cookiecutter/cookiecutter-django/pull/3887))
+
+## 2022.09.29
+
+### Changed
+- Remove outdated & optional Sendgrid settings from production config ([#3885](https://github.com/cookiecutter/cookiecutter-django/pull/3885))
+
+## 2022.09.27
+
+### Updated
+- Update sphinx to 5.2.2 ([#3884](https://github.com/cookiecutter/cookiecutter-django/pull/3884))
+
+## 2022.09.26
+
+### Updated
+- Update drf-spectacular to 0.24.2 ([#3882](https://github.com/cookiecutter/cookiecutter-django/pull/3882))
+- Update djangorestframework to 3.14.0 ([#3881](https://github.com/cookiecutter/cookiecutter-django/pull/3881))
+- Update django-debug-toolbar to 3.7.0 ([#3878](https://github.com/cookiecutter/cookiecutter-django/pull/3878))
+- Auto-update pre-commit hooks ([#3877](https://github.com/cookiecutter/cookiecutter-django/pull/3877))
+- Bump stefanzweifel/git-auto-commit-action from 4.14.1 to 4.15.0 ([#3880](https://github.com/cookiecutter/cookiecutter-django/pull/3880))
+- Update sphinx to 5.2.1 ([#3879](https://github.com/cookiecutter/cookiecutter-django/pull/3879))
+
+## 2022.09.24
+
+### Fixed
+- Remove `--no-deps` in pip wheels command of docs Dockerfile ([#3875](https://github.com/cookiecutter/cookiecutter-django/pull/3875))
+
+## 2022.09.23
+
+### Changed
+- Reload uvicorn on html file change ([#3866](https://github.com/cookiecutter/cookiecutter-django/pull/3866))
+- Mailjet default api url does not work out of the box ([#3871](https://github.com/cookiecutter/cookiecutter-django/pull/3871))
+### Updated
+- Auto-update pre-commit hooks ([#3872](https://github.com/cookiecutter/cookiecutter-django/pull/3872))
+- Update django-extensions to 3.2.1 ([#3867](https://github.com/cookiecutter/cookiecutter-django/pull/3867))
+- Update tox to 3.26.0 ([#3864](https://github.com/cookiecutter/cookiecutter-django/pull/3864))
+- Update drf-spectacular to 0.24.1 ([#3874](https://github.com/cookiecutter/cookiecutter-django/pull/3874))
+
+## 2022.09.15
+
+### Updated
+- Update watchfiles to 0.17.0 ([#3869](https://github.com/cookiecutter/cookiecutter-django/pull/3869))
+- Update drf-spectacular to 0.24.0 ([#3870](https://github.com/cookiecutter/cookiecutter-django/pull/3870))
+
+## 2022.09.05
+
+### Updated
+- Update sentry-sdk to 1.9.8 ([#3861](https://github.com/cookiecutter/cookiecutter-django/pull/3861))
+
+## 2022.09.02
+
+### Updated
+- Update pytest to 7.1.3 ([#3860](https://github.com/cookiecutter/cookiecutter-django/pull/3860))
+- Update sentry-sdk to 1.9.7 ([#3859](https://github.com/cookiecutter/cookiecutter-django/pull/3859))
+
+## 2022.09.01
+
+### Changed
+- Add article to README about how to use a hosted DB ([#3844](https://github.com/cookiecutter/cookiecutter-django/pull/3844))
+### Updated
+- Update sentry-sdk to 1.9.6 ([#3856](https://github.com/cookiecutter/cookiecutter-django/pull/3856))
+- Auto-update pre-commit hooks ([#3858](https://github.com/cookiecutter/cookiecutter-django/pull/3858))
+- Update black to 22.8.0 ([#3857](https://github.com/cookiecutter/cookiecutter-django/pull/3857))
+
+## 2022.08.26
+
+### Changed
+- Fix formatting in docs ([#3850](https://github.com/cookiecutter/cookiecutter-django/pull/3850))
+
+## 2022.08.24
+
+### Updated
+- Update django-debug-toolbar to 3.6.0 ([#3847](https://github.com/cookiecutter/cookiecutter-django/pull/3847))
+- Update werkzeug to 2.2.2 ([#3846](https://github.com/cookiecutter/cookiecutter-django/pull/3846))
+- Update coverage to 6.4.4 ([#3842](https://github.com/cookiecutter/cookiecutter-django/pull/3842))
+- Update uvicorn to 0.18.3 ([#3845](https://github.com/cookiecutter/cookiecutter-django/pull/3845))
+- Update sentry-sdk to 1.9.5 ([#3841](https://github.com/cookiecutter/cookiecutter-django/pull/3841))
+- Update flower to 1.2.0 ([#3836](https://github.com/cookiecutter/cookiecutter-django/pull/3836))
+- Update django-storages to 1.13.1 ([#3833](https://github.com/cookiecutter/cookiecutter-django/pull/3833))
+
+## 2022.08.15
+
+### Updated
+- Update coverage to 6.4.3 ([#3835](https://github.com/cookiecutter/cookiecutter-django/pull/3835))
+- Update pytz to 2022.2.1 ([#3840](https://github.com/cookiecutter/cookiecutter-django/pull/3840))
+- Update sentry-sdk to 1.9.4 ([#3838](https://github.com/cookiecutter/cookiecutter-django/pull/3838))
+
+## 2022.08.09
+
+### Updated
+- Update sentry-sdk to 1.9.3 ([#3837](https://github.com/cookiecutter/cookiecutter-django/pull/3837))
+
+## 2022.08.05
+
+### Updated
+- Update sentry-sdk to 1.9.2 ([#3832](https://github.com/cookiecutter/cookiecutter-django/pull/3832))
+
+## 2022.08.04
+
+### Updated
+- Auto-update pre-commit hooks ([#3816](https://github.com/cookiecutter/cookiecutter-django/pull/3816))
+- Update flake8 to 5.0.4 ([#3829](https://github.com/cookiecutter/cookiecutter-django/pull/3829))
+- Update django-compressor to 4.1 ([#3823](https://github.com/cookiecutter/cookiecutter-django/pull/3823))
+- Update flake8-isort to 4.2.0 ([#3828](https://github.com/cookiecutter/cookiecutter-django/pull/3828))
+
+## 2022.08.03
+
+### Updated
+- Update django to 3.2.15 ([#3822](https://github.com/cookiecutter/cookiecutter-django/pull/3822))
+
+## 2022.07.29
+
+### Updated
+- Update sentry-sdk to 1.9.0 ([#3815](https://github.com/cookiecutter/cookiecutter-django/pull/3815))
+
+## 2022.07.28
+
+### Updated
+- Update werkzeug to 2.2.1 ([#3814](https://github.com/cookiecutter/cookiecutter-django/pull/3814))
+
+## 2022.07.27
+
+### Updated
+- Update werkzeug to 2.2.0 ([#3813](https://github.com/cookiecutter/cookiecutter-django/pull/3813))
+- Update sphinx to 5.1.1 ([#3811](https://github.com/cookiecutter/cookiecutter-django/pull/3811))
+- Update drf-spectacular to 0.23.1 ([#3812](https://github.com/cookiecutter/cookiecutter-django/pull/3812))
+
+## 2022.07.26
+
+### Changed
+- Switch from `watchgod` to `watchfiles` ([#3791](https://github.com/cookiecutter/cookiecutter-django/pull/3791))
+- Change Django settings file used by pylint ([#3806](https://github.com/cookiecutter/cookiecutter-django/pull/3806))
+- Simplify database access in tests ([#3807](https://github.com/cookiecutter/cookiecutter-django/pull/3807))
+- Provide more context when wating for PostgreSQL takes too long ([#3782](https://github.com/cookiecutter/cookiecutter-django/pull/3782))
+### Updated
+- Update django-compressor to 4.0 ([#3802](https://github.com/cookiecutter/cookiecutter-django/pull/3802))
+- Update flake8-isort to 4.1.2.post0 ([#3809](https://github.com/cookiecutter/cookiecutter-django/pull/3809))
+- Update sphinx to 5.1.0 ([#3808](https://github.com/cookiecutter/cookiecutter-django/pull/3808))
+- Update sh to 1.14.3 ([#3798](https://github.com/cookiecutter/cookiecutter-django/pull/3798))
+- Auto-update pre-commit hooks ([#3780](https://github.com/cookiecutter/cookiecutter-django/pull/3780))
+
+## 2022.07.22
+
+### Updated
+- Update pytest-sugar to 0.9.5 ([#3800](https://github.com/cookiecutter/cookiecutter-django/pull/3800))
+- Update sphinx to 5.0.2 ([#3801](https://github.com/cookiecutter/cookiecutter-django/pull/3801))
+- Update pillow to 9.2.0 ([#3799](https://github.com/cookiecutter/cookiecutter-django/pull/3799))
+- Update werkzeug to 2.1.2 ([#3797](https://github.com/cookiecutter/cookiecutter-django/pull/3797))
+
+## 2022.07.21
+
+### Changed
+- Set user to form instance in update user view test ([#3776](https://github.com/cookiecutter/cookiecutter-django/pull/3776))
+- Fix warning from django-coverage-plugin in tests ([#3790](https://github.com/cookiecutter/cookiecutter-django/pull/3790))
+- Always use `const` instead of `var` in `gulpfile.js` ([#3786](https://github.com/cookiecutter/cookiecutter-django/pull/3786))
+### Updated
+- Update flower to 1.1.0 ([#3796](https://github.com/cookiecutter/cookiecutter-django/pull/3796))
+- Update coverage to 6.4.2 ([#3783](https://github.com/cookiecutter/cookiecutter-django/pull/3783))
+- Update mypy to 0.971 ([#3788](https://github.com/cookiecutter/cookiecutter-django/pull/3788))
+- Update sentry-sdk to 1.8.0 ([#3792](https://github.com/cookiecutter/cookiecutter-django/pull/3792))
+- Update pre-commit to 2.20.0 ([#3779](https://github.com/cookiecutter/cookiecutter-django/pull/3779))
+- Update django-extensions to 3.2.0 ([#3774](https://github.com/cookiecutter/cookiecutter-django/pull/3774))
+- Update tox to 3.25.1 ([#3767](https://github.com/cookiecutter/cookiecutter-django/pull/3767))
+- Update uvicorn to 0.18.2 ([#3762](https://github.com/cookiecutter/cookiecutter-django/pull/3762))
+- Update redis to 4.3.4 ([#3763](https://github.com/cookiecutter/cookiecutter-django/pull/3763))
+- Update requests to 2.28.1 ([#3766](https://github.com/cookiecutter/cookiecutter-django/pull/3766))
+
+## 2022.07.10
+
+### Changed
+- Revert auto-update pre-commit hooks ([#3778](https://github.com/cookiecutter/cookiecutter-django/pull/3778))
+### Updated
+- Auto-update pre-commit hooks ([#3775](https://github.com/cookiecutter/cookiecutter-django/pull/3775))
+
+## 2022.07.06
+
+### Updated
+- Update django to 3.2.14 ([#3768](https://github.com/cookiecutter/cookiecutter-django/pull/3768))
+
+## 2022.06.28
+
+### Updated
+- Auto-update pre-commit hooks ([#3765](https://github.com/cookiecutter/cookiecutter-django/pull/3765))
+- Update black to 22.6.0 ([#3764](https://github.com/cookiecutter/cookiecutter-django/pull/3764))
+
+## 2022.06.23
+
+### Updated
+- Update django-debug-toolbar to 3.5.0 ([#3760](https://github.com/cookiecutter/cookiecutter-django/pull/3760))
+
+## 2022.06.22
+
+### Updated
+- Update django-stubs to 1.12.0 ([#3757](https://github.com/cookiecutter/cookiecutter-django/pull/3757))
+- Update sentry-sdk to 1.6.0 ([#3756](https://github.com/cookiecutter/cookiecutter-django/pull/3756))
+- Update djangorestframework-stubs to 1.7.0 ([#3754](https://github.com/cookiecutter/cookiecutter-django/pull/3754))
+
+## 2022.06.15
+
+### Updated
+- Update django-environ to 0.9.0 ([#3751](https://github.com/cookiecutter/cookiecutter-django/pull/3751))
+
+## 2022.06.13
+
+### Updated
+- Update cookiecutter to 2.1.1 ([#3727](https://github.com/cookiecutter/cookiecutter-django/pull/3727))
+
+## 2022.06.11
+
+### Updated
+- Update requests to 2.28.0 ([#3748](https://github.com/cookiecutter/cookiecutter-django/pull/3748))
+
+## 2022.06.09
+
+### Updated
+- Bump actions/setup-python from 3 to 4 ([#3746](https://github.com/cookiecutter/cookiecutter-django/pull/3746))
+
+## 2022.06.08
+
+### Updated
+- Auto-update pre-commit hooks ([#3744](https://github.com/cookiecutter/cookiecutter-django/pull/3744))
+
+## 2022.06.07
+
+### Updated
+- Update django-allauth to 0.51.0 ([#3743](https://github.com/cookiecutter/cookiecutter-django/pull/3743))
+- Auto-update pre-commit hooks ([#3742](https://github.com/cookiecutter/cookiecutter-django/pull/3742))
+
+## 2022.06.06
+
+### Updated
+- Bump pre-commit/action from 2.0.3 to 3.0.0 ([#3739](https://github.com/cookiecutter/cookiecutter-django/pull/3739))
+
+## 2022.06.05
+
+### Updated
+- Update whitenoise to 6.2.0 ([#3737](https://github.com/cookiecutter/cookiecutter-django/pull/3737))
+- Update django-cors-headers to 3.13.0 ([#3738](https://github.com/cookiecutter/cookiecutter-django/pull/3738))
+
+## 2022.06.04
+
+### Updated
+- Update django-cors-headers to 3.12.0 ([#3736](https://github.com/cookiecutter/cookiecutter-django/pull/3736))
+- Update djangorestframework-stubs to 1.6.0 ([#3718](https://github.com/cookiecutter/cookiecutter-django/pull/3718))
+- Update django-stubs to 1.11.0 ([#3734](https://github.com/cookiecutter/cookiecutter-django/pull/3734))
+- Update sphinx to 5.0.1 ([#3733](https://github.com/cookiecutter/cookiecutter-django/pull/3733))
+- Update sphinx to 5.0.0 ([#3724](https://github.com/cookiecutter/cookiecutter-django/pull/3724))
+- Update celery to 5.2.7 ([#3732](https://github.com/cookiecutter/cookiecutter-django/pull/3732))
+- Update django-celery-beat to 2.3.0 ([#3731](https://github.com/cookiecutter/cookiecutter-django/pull/3731))
+
+## 2022.06.02
+
+### Updated
+- Update coverage to 6.4.1 ([#3729](https://github.com/cookiecutter/cookiecutter-django/pull/3729))
+- Update redis to 4.3.3 ([#3728](https://github.com/cookiecutter/cookiecutter-django/pull/3728))
+
+## 2022.06.01
+
+### Updated
+- Update redis to 4.3.2 ([#3726](https://github.com/cookiecutter/cookiecutter-django/pull/3726))
+
+## 2022.05.24
+
+### Updated
+- Update coverage to 6.4 ([#3716](https://github.com/cookiecutter/cookiecutter-django/pull/3716))
+
+## 2022.05.18
+
+### Updated
+- Update pillow to 9.1.1 ([#3714](https://github.com/cookiecutter/cookiecutter-django/pull/3714))
+
+## 2022.05.16
+
+### Changed
+- Update postgres versions ([#3712](https://github.com/cookiecutter/cookiecutter-django/pull/3712))
+### Updated
+- Update django-anymail to 8.6 ([#3713](https://github.com/cookiecutter/cookiecutter-django/pull/3713))
+
+## 2022.05.14
+
+### Updated
+- Update coverage to 6.3.3 ([#3709](https://github.com/cookiecutter/cookiecutter-django/pull/3709))
+- Update whitenoise to 6.1.0 ([#3707](https://github.com/cookiecutter/cookiecutter-django/pull/3707))
+- Update sentry-sdk to 1.5.12 ([#3706](https://github.com/cookiecutter/cookiecutter-django/pull/3706))
+- Update redis to 4.3.1 ([#3704](https://github.com/cookiecutter/cookiecutter-django/pull/3704))
+
+## 2022.05.07
+
+### Changed
+- Add pyupgrade to pre-commit config ([#3702](https://github.com/cookiecutter/cookiecutter-django/pull/3702))
+- Set permissions for GitHub actions ([#3698](https://github.com/cookiecutter/cookiecutter-django/pull/3698))
+### Updated
+- Update jinja2 to 3.1.2 ([#3700](https://github.com/cookiecutter/cookiecutter-django/pull/3700))
+
+## 2022.05.06
+
+### Updated
+- Update pre-commit to 2.19.0 ([#3697](https://github.com/cookiecutter/cookiecutter-django/pull/3697))
+
+## 2022.05.04
+
+### Updated
+- Update django-coverage-plugin to 2.0.3 ([#3695](https://github.com/cookiecutter/cookiecutter-django/pull/3695))
+
+## 2022.05.03
+
+### Updated
+- Update django-debug-toolbar to 3.4.0 ([#3692](https://github.com/cookiecutter/cookiecutter-django/pull/3692))
+- Update sentry-sdk to 1.5.11 ([#3693](https://github.com/cookiecutter/cookiecutter-django/pull/3693))
+
+## 2022.05.01
+
+### Updated
+- Update django-debug-toolbar to 3.3.0 ([#3690](https://github.com/cookiecutter/cookiecutter-django/pull/3690))
+
+## 2022.04.28
+
+### Changed
+- Add the possibility to set a max django version on create_django_issue script ([#3680](https://github.com/cookiecutter/cookiecutter-django/pull/3680))
+
+## 2022.04.27
+
+### Updated
+- Update mypy to 0.950 ([#3687](https://github.com/cookiecutter/cookiecutter-django/pull/3687))
+- Update python-slugify to 6.1.2 ([#3686](https://github.com/cookiecutter/cookiecutter-django/pull/3686))
+- Update drf-spectacular to 0.22.1 ([#3684](https://github.com/cookiecutter/cookiecutter-django/pull/3684))
+
+## 2022.04.25
+
+### Updated
+- Update pytest to 7.1.2 ([#3683](https://github.com/cookiecutter/cookiecutter-django/pull/3683))
+
+## 2022.04.19
+
+### Updated
+- Update tox to 3.25.0 ([#3675](https://github.com/cookiecutter/cookiecutter-django/pull/3675))
+- Update sentry-sdk to 1.5.10 ([#3679](https://github.com/cookiecutter/cookiecutter-django/pull/3679))
+
+## 2022.04.13
+
+### Updated
+- Bump stefanzweifel/git-auto-commit-action from 4.14.0 to 4.14.1 ([#3677](https://github.com/cookiecutter/cookiecutter-django/pull/3677))
+
+## 2022.04.11
+
+### Updated
+- Update django to 3.2.13 ([#3676](https://github.com/cookiecutter/cookiecutter-django/pull/3676))
+
+## 2022.04.08
+
+### Updated
+- Auto-update pre-commit hooks ([#3673](https://github.com/cookiecutter/cookiecutter-django/pull/3673))
+
+## 2022.04.05
+
+### Updated
+- Update celery to 5.2.6 ([#3671](https://github.com/cookiecutter/cookiecutter-django/pull/3671))
+
+## 2022.04.04
+
+### Updated
+- Update redis to 4.2.2 ([#3670](https://github.com/cookiecutter/cookiecutter-django/pull/3670))
+- Update celery to 5.2.5 ([#3669](https://github.com/cookiecutter/cookiecutter-django/pull/3669))
+- Update pre-commit to 2.18.1 ([#3668](https://github.com/cookiecutter/cookiecutter-django/pull/3668))
+- Update pillow to 9.1.0 ([#3665](https://github.com/cookiecutter/cookiecutter-django/pull/3665))
+
+## 2022.04.01
+
+### Changed
+- Update domain for Celery docs ([#3663](https://github.com/cookiecutter/cookiecutter-django/pull/3663))
+### Updated
+- Update watchgod to 0.8.2 ([#3664](https://github.com/cookiecutter/cookiecutter-django/pull/3664))
+- Update redis to 4.2.1 ([#3660](https://github.com/cookiecutter/cookiecutter-django/pull/3660))
+
+## 2022.03.28
+
+### Changed
+- Update `black` version to `22.3.0` ([#3657](https://github.com/cookiecutter/cookiecutter-django/pull/3657))
+
+## 2022.03.27
+
+### Updated
+- Update sphinx to 4.5.0 ([#3654](https://github.com/cookiecutter/cookiecutter-django/pull/3654))
+- Update jinja2 to 3.1.1 ([#3652](https://github.com/cookiecutter/cookiecutter-django/pull/3652))
+- Update pylint-django to 2.5.3 ([#3650](https://github.com/cookiecutter/cookiecutter-django/pull/3650))
+- Update django-allauth to 0.50.0 ([#3649](https://github.com/cookiecutter/cookiecutter-django/pull/3649))
+- Update mypy to 0.942 ([#3648](https://github.com/cookiecutter/cookiecutter-django/pull/3648))
+- Update jinja2 to 3.1.0 ([#3647](https://github.com/cookiecutter/cookiecutter-django/pull/3647))
+- Update redis to 4.2.0 ([#3646](https://github.com/cookiecutter/cookiecutter-django/pull/3646))
+- Update watchgod to 0.8.1 ([#3643](https://github.com/cookiecutter/cookiecutter-django/pull/3643))
+- Bump stefanzweifel/git-auto-commit-action from 4.13.1 to 4.14.0 ([#3641](https://github.com/cookiecutter/cookiecutter-django/pull/3641))
+- Update drf-spectacular to 0.22.0 ([#3642](https://github.com/cookiecutter/cookiecutter-django/pull/3642))
+- Update pytz to 2022.1 ([#3639](https://github.com/cookiecutter/cookiecutter-django/pull/3639))
+- Update sentry-sdk to 1.5.8 ([#3638](https://github.com/cookiecutter/cookiecutter-django/pull/3638))
+- Update pytest to 7.1.1 ([#3637](https://github.com/cookiecutter/cookiecutter-django/pull/3637))
+- Update uvicorn to 0.17.6 ([#3627](https://github.com/cookiecutter/cookiecutter-django/pull/3627))
+
+## 2022.03.23
+
+### Updated
+- Bump peter-evans/create-pull-request from 3.14.0 to 4 ([#3645](https://github.com/cookiecutter/cookiecutter-django/pull/3645))
+
+## 2022.03.20
+
+### Changed
+- Unify compressor, gulp and custom bootstrap options ([#3535](https://github.com/cookiecutter/cookiecutter-django/pull/3535))
+
+## 2022.03.14
+
+### Fixed
+- Fix broken link in README of generated projects ([#3634](https://github.com/cookiecutter/cookiecutter-django/pull/3634))
+
+## 2022.03.13
+
+### Changed
+- Add DRF spectacular link in requirements ([#3630](https://github.com/cookiecutter/cookiecutter-django/pull/3630))
+
+## 2022.03.09
+
+### Changed
+- Fix a few typos in the documentation ([#3625](https://github.com/cookiecutter/cookiecutter-django/pull/3625))
+
+## 2022.03.08
+
+### Updated
+- Update sentry-sdk to 1.5.7 ([#3624](https://github.com/cookiecutter/cookiecutter-django/pull/3624))
+
+## 2022.03.03
+
+### Updated
+- Upgrade actions/setup-python to v3 ([#3621](https://github.com/cookiecutter/cookiecutter-django/pull/3621))
+
+## 2022.03.02
+
+### Updated
+- Bump actions/checkout from 2 to 3 ([#3619](https://github.com/cookiecutter/cookiecutter-django/pull/3619))
+
+## 2022.03.01
+
+### Updated
+- Bump actions/setup-python from 2 to 3 ([#3617](https://github.com/cookiecutter/cookiecutter-django/pull/3617))
+- Bump peter-evans/create-pull-request from 3.13.0 to 3.14.0 ([#3618](https://github.com/cookiecutter/cookiecutter-django/pull/3618))
+
+## 2022.02.28
+
+### Updated
+- Update python-slugify to 6.1.1 ([#3615](https://github.com/cookiecutter/cookiecutter-django/pull/3615))
+- Bump peter-evans/create-pull-request from 3.12.1 to 3.13.0 ([#3616](https://github.com/cookiecutter/cookiecutter-django/pull/3616))
+
+## 2022.02.25
+
+### Updated
+- Bump actions/setup-node from 2 to 3 ([#3614](https://github.com/cookiecutter/cookiecutter-django/pull/3614))
+
+## 2022.02.24
+
+### Updated
+- Update django-allauth to 0.49.0 ([#3613](https://github.com/cookiecutter/cookiecutter-django/pull/3613))
+- Update sentry-sdk to 1.5.6 ([#3611](https://github.com/cookiecutter/cookiecutter-django/pull/3611))
+- Update python-slugify to 6.1.0 ([#3612](https://github.com/cookiecutter/cookiecutter-django/pull/3612))
+
+## 2022.02.21
+
+### Changed
+- Cancel previous CI runs on successive PR pushes with GitHub actions ([#3575](https://github.com/cookiecutter/cookiecutter-django/pull/3575))
+### Updated
+- Update coverage to 6.3.2 ([#3610](https://github.com/cookiecutter/cookiecutter-django/pull/3610))
+- Update gitpython to 3.1.27 ([#3607](https://github.com/cookiecutter/cookiecutter-django/pull/3607))
+- Update pylint-django to 2.5.2 ([#3602](https://github.com/cookiecutter/cookiecutter-django/pull/3602))
+- Update python-slugify to 6.0.1 ([#3599](https://github.com/cookiecutter/cookiecutter-django/pull/3599))
+- Update uvicorn to 0.17.5 ([#3596](https://github.com/cookiecutter/cookiecutter-django/pull/3596))
+- Update redis to 4.1.4 ([#3595](https://github.com/cookiecutter/cookiecutter-django/pull/3595))
+
+## 2022.02.20
+
+### Changed
+- Fix incorrect createdb instruction in documentation ([#3606](https://github.com/cookiecutter/cookiecutter-django/pull/3606))
+
+## 2022.02.16
+
+### Fixed
+- Fix Swagger schema API endpoint & add a test for it ([#3592](https://github.com/cookiecutter/cookiecutter-django/pull/3592))
+
+## 2022.02.15
+
+### Changed
+- Update the drf-spectacular local dev server url to use http instead of https ([#3591](https://github.com/cookiecutter/cookiecutter-django/pull/3591))
+
+## 2022.02.13
+
+### Changed
+- Change docs port from 7000 to 9000 ([#3590](https://github.com/cookiecutter/cookiecutter-django/pull/3590))
+
+## 2022.02.12
+
+### Updated
+- Update pytest to 7.0.1 ([#3588](https://github.com/cookiecutter/cookiecutter-django/pull/3588))
+
+## 2022.02.11
+
+### Updated
+- Update sentry-sdk to 1.5.5 ([#3586](https://github.com/cookiecutter/cookiecutter-django/pull/3586))
+
+## 2022.02.10
+
+### Fixed
+- Fix GitLab CI error caused by Docker Compose's `platform` option ([#3585](https://github.com/cookiecutter/cookiecutter-django/pull/3585))
+### Updated
+- Update whitenoise to 6.0.0 ([#3583](https://github.com/cookiecutter/cookiecutter-django/pull/3583))
+
+## 2022.02.08
+
+### Fixed
+- Fixed some typos in drf-spectacular description and comments ([#3579](https://github.com/cookiecutter/cookiecutter-django/pull/3579))
+### Updated
+- Update redis to 4.1.3 ([#3577](https://github.com/cookiecutter/cookiecutter-django/pull/3577))
+- Update werkzeug to 2.0.3 ([#3576](https://github.com/cookiecutter/cookiecutter-django/pull/3576))
+
+## 2022.02.07
+
+### Changed
+- Update black to 22.1.0 ([#3572](https://github.com/cookiecutter/cookiecutter-django/pull/3572))
+### Fixed
+- Fix docker-compose config on Apple silicon ([#3562](https://github.com/cookiecutter/cookiecutter-django/pull/3562))
+### Updated
+- Update uvicorn to 0.17.4 ([#3574](https://github.com/cookiecutter/cookiecutter-django/pull/3574))
+- Update django-allauth to 0.48.0 ([#3573](https://github.com/cookiecutter/cookiecutter-django/pull/3573))
+- Update pytest to 7.0.0 ([#3567](https://github.com/cookiecutter/cookiecutter-django/pull/3567))
+- Update coverage to 6.3.1 ([#3561](https://github.com/cookiecutter/cookiecutter-django/pull/3561))
+- Update pillow to 9.0.1 ([#3571](https://github.com/cookiecutter/cookiecutter-django/pull/3571))
+- Bump peter-evans/create-pull-request from 3.12.0 to 3.12.1 ([#3558](https://github.com/cookiecutter/cookiecutter-django/pull/3558))
+- Update drf-spectacular to 0.21.2 ([#3560](https://github.com/cookiecutter/cookiecutter-django/pull/3560))
+- Update django to 3.2.12 ([#3559](https://github.com/cookiecutter/cookiecutter-django/pull/3559))
+
## 2022.01.27
### Updated
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..8a5fc4158
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+## Code of Conduct
+
+Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PyPA Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/).
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a9d5b088f..28bb81e38 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -33,7 +33,7 @@ To run all tests using various versions of python in virtualenvs defined in tox.
It is possible to test with a specific version of python. To do this, the command
is:
- $ tox -e py39
+ $ tox -e py310
This will run pytest with the python3.9 interpreter, for example.
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index d31b480a6..3f7d4564f 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -285,6 +285,13 @@ Listed in alphabetical order.
Simon Rey |
diff --git a/README.md b/README.md
index 3f5df1f01..9f2af6d37 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://github.com/cookiecutter/cookiecutter-django/actions?query=workflow%3ACI)
[](https://cookiecutter-django.readthedocs.io/en/latest/?badge=latest)
[](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/)
-[](https://discord.gg/9BrxzPKuEW)
+[](https://discord.gg/uFXweDQc5a)
[](https://www.codetriage.com/cookiecutter/cookiecutter-django)
[](https://github.com/ambv/black)
@@ -17,8 +17,8 @@ production-ready Django projects quickly.
## Features
-- For Django 3.2
-- Works with Python 3.9
+- For Django 4.0
+- Works with Python 3.10
- Renders Django projects with 100% starting test coverage
- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5
- [12-Factor](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ)
@@ -42,7 +42,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/)
-- Configuration for [Celery](http://www.celeryproject.org/) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only)
+- 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
@@ -121,16 +121,12 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
use_pycharm [n]: y
use_docker [n]: n
Select postgresql_version:
- 1 - 14.1
- 2 - 13.5
- 3 - 12.9
- 4 - 11.14
- 5 - 10.19
+ 1 - 14
+ 2 - 13
+ 3 - 12
+ 4 - 11
+ 5 - 10
Choose from 1, 2, 3, 4, 5 [1]: 1
- Select js_task_runner:
- 1 - None
- 2 - Gulp
- Choose from 1, 2 [1]: 1
Select cloud_provider:
1 - AWS
2 - GCP
@@ -149,8 +145,11 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 1
use_async [n]: n
use_drf [n]: y
- custom_bootstrap_compilation [n]: n
- use_compressor [n]: n
+ Select frontend_pipeline:
+ 1 - None
+ 2 - Django Compressor
+ 3 - Gulp
+ Choose from 1, 2, 3, 4 [1]: 1
use_celery [n]: y
use_mailhog [n]: n
use_sentry [n]: y
@@ -189,7 +188,7 @@ For local development, see the following:
- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the *cookiecutter-django* tag. We check there periodically for questions.
- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues).
-- For anything else, you can chat with us on [Discord](https://discord.gg/9BrxzPKuEW).
+- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a).
## For Readers of Two Scoops of Django
@@ -233,6 +232,7 @@ experience better.
## Articles
+- [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021
- [Using cookiecutter-django with Google Cloud Storage](https://ahhda.github.io/cloud/gce/django/2019/03/12/using-django-cookiecutter-cloud-storage.html) - Mar. 12, 2019
- [cookiecutter-django with Nginx, Route 53 and ELB](https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/) - Feb. 12, 2018
- [cookiecutter-django and Amazon RDS](https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/) - Feb. 7, 2018
@@ -245,8 +245,3 @@ experience better.
- [How to create a Django Application using Cookiecutter and Django 1.8](https://www.swapps.io/blog/how-to-create-a-django-application-using-cookiecutter-and-django-1-8/) - Sept. 12, 2015
Have a blog or online publication? Write about your cookiecutter-django tips and tricks, then send us a pull request with the link.
-
-## Code of Conduct
-
-Everyone interacting in the Cookiecutter project's codebases, issue trackers, chat
-rooms, and mailing lists is expected to follow the [PyPA Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/).
diff --git a/cookiecutter.json b/cookiecutter.json
index 6d2e14daa..3fa5b6f66 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -18,15 +18,11 @@
"use_pycharm": "n",
"use_docker": "n",
"postgresql_version": [
- "14.1",
- "13.5",
- "12.9",
- "11.14",
- "10.19"
- ],
- "js_task_runner": [
- "None",
- "Gulp"
+ "14",
+ "13",
+ "12",
+ "11",
+ "10"
],
"cloud_provider": [
"AWS",
@@ -47,8 +43,11 @@
],
"use_async": "n",
"use_drf": "n",
- "custom_bootstrap_compilation": "n",
- "use_compressor": "n",
+ "frontend_pipeline": [
+ "None",
+ "Django Compressor",
+ "Gulp"
+ ],
"use_celery": "n",
"use_mailhog": "n",
"use_sentry": "n",
diff --git a/docs/conf.py b/docs/conf.py
index f55bcb819..b53e6a7e7 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -39,7 +39,7 @@ master_doc = "index"
# General information about the project.
project = "Cookiecutter Django"
-copyright = "2013-{}, Daniel Roy Greenfeld".format(now.year)
+copyright = f"2013-{now.year}, Daniel Roy Greenfeld"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst
index bab5881cd..e239b6593 100644
--- a/docs/deployment-on-heroku.rst
+++ b/docs/deployment-on-heroku.rst
@@ -112,7 +112,7 @@ Or add the DSN for your account, if you already have one:
Gulp & Bootstrap compilation
++++++++++++++++++++++++++++
-If you've opted for a custom bootstrap build, you'll most likely need to setup
+If you've opted for Gulp, you'll most likely need to setup
your app to use `multiple buildpacks`_: one for Python & one for Node.js:
.. code-block:: bash
diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst
index f7bff12a4..7984d7b5e 100644
--- a/docs/deployment-on-pythonanywhere.rst
+++ b/docs/deployment-on-pythonanywhere.rst
@@ -34,7 +34,7 @@ Make sure your project is fully committed and pushed up to Bitbucket or Github o
git clone # you can also use hg
cd my-project-name
- mkvirtualenv --python=/usr/bin/python3.9 my-project-name
+ mkvirtualenv --python=/usr/bin/python3.10 my-project-name
pip install -r requirements/production.txt # may take a few minutes
diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst
index e0b522c8c..4bb5d9032 100644
--- a/docs/developing-locally-docker.rst
+++ b/docs/developing-locally-docker.rst
@@ -18,7 +18,7 @@ Prerequisites
* Docker; if you don't have it yet, follow the `installation instructions`_;
* Docker Compose; refer to the official documentation for the `installation guide`_.
-* Pre-commit; refer to the official documentation for the [pre-commit](https://pre-commit.com/#install).
+* Pre-commit; refer to the official documentation for the `pre-commit`_.
.. _`installation instructions`: https://docs.docker.com/install/#supported-platforms
.. _`installation guide`: https://docs.docker.com/compose/install/
@@ -190,7 +190,7 @@ Celery tasks in local development
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When not using docker Celery tasks are set to run in Eager mode, so that a full stack is not needed. When using docker the task scheduler will be used by default.
-If you need tasks to be executed on the main thread during development set CELERY_TASK_ALWAYS_EAGER = True in config/settings/local.py.
+If you need tasks to be executed on the main thread during development set ``CELERY_TASK_ALWAYS_EAGER = True`` in ``config/settings/local.py``.
Possible uses could be for testing, or ease of profiling with DJDT.
@@ -215,7 +215,7 @@ Developing locally with HTTPS
Increasingly it is becoming necessary to develop software in a secure environment in order that there are very few changes when deploying to production. Recently Facebook changed their policies for apps/sites that use Facebook login which requires the use of an HTTPS URL for the OAuth redirect URL. So if you want to use the ``users`` application with a OAuth provider such as Facebook, securing your communication to the local development environment will be necessary.
-In order to create a secure environment, we need to have a trusted SSL certficate installed in our Docker application.
+In order to create a secure environment, we need to have a trusted SSL certificate installed in our Docker application.
#. **Let's Encrypt**
diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst
index a9a54a03b..c9d28ff73 100644
--- a/docs/developing-locally.rst
+++ b/docs/developing-locally.rst
@@ -9,7 +9,7 @@ Setting Up Development Environment
Make sure to have the following on your host:
-* Python 3.9
+* Python 3.10
* PostgreSQL_.
* Redis_, if using Celery
* Cookiecutter_
@@ -18,7 +18,7 @@ First things first.
#. Create a virtualenv: ::
- $ python3.9 -m venv
+ $ python3.10 -m venv
#. Activate the virtualenv you have just created: ::
@@ -42,7 +42,8 @@ First things first.
#. Create a new PostgreSQL database using createdb_: ::
- $ createdb -U postgres --password
+ $ createdb --username=postgres
+ ``project_slug`` is what you have entered as the project_slug at the setup stage.
.. note::
@@ -81,7 +82,7 @@ First things first.
or if you're running asynchronously: ::
- $ uvicorn config.asgi:application --host 0.0.0.0 --reload
+ $ uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
.. _PostgreSQL: https://www.postgresql.org/download/
.. _Redis: https://redis.io/download
@@ -154,7 +155,7 @@ To run Celery locally, make sure redis-server is installed (instructions are ava
Sass Compilation & Live Reloading
---------------------------------
-If you've opted for Gulp as JS task runner, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
+If you've opted for Gulp as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
#. Make sure that `Node.js`_ v16 is installed on your machine.
#. In the project root, install the JS dependencies with::
@@ -167,7 +168,7 @@ If you've opted for Gulp as JS task runner, the project comes configured with `S
The app will now run with live reloading enabled, applying front-end changes dynamically.
-.. note:: The task will start 2 processes in parallel: the static assets build loop on one side, and the Django server on the other. You don NOT need to run Django as your would normally with ``manage.py runserver``.
+.. note:: The task will start 2 processes in parallel: the static assets build loop on one side, and the Django server on the other. You do NOT need to run Django as your would normally with ``manage.py runserver``.
.. _Node.js: http://nodejs.org/download/
.. _Sass: https://sass-lang.com/
diff --git a/docs/document.rst b/docs/document.rst
index a30979094..974c66c69 100644
--- a/docs/document.rst
+++ b/docs/document.rst
@@ -13,7 +13,7 @@ If you set up your project to `develop locally with docker`_, run the following
$ docker-compose -f local.yml up docs
-Navigate to port 7000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development.
+Navigate to port 9000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development.
Note: using Docker for documentation sets up a temporary SQLite file by setting the environment variable ``DATABASE_URL=sqlite:///readthedocs.db`` in ``docs/conf.py`` to avoid a dependency on PostgreSQL.
@@ -36,7 +36,7 @@ To setup your documentation on `ReadTheDocs`_, you must
Additionally, you can auto-build Pull Request previews, but `you must enable it`_.
-.. _localhost: http://localhost:7000/
+.. _localhost: http://localhost:9000/
.. _Sphinx: https://www.sphinx-doc.org/en/master/index.html
.. _develop locally: ./developing-locally.html
.. _develop locally with docker: ./developing-locally-docker.html
diff --git a/docs/faq.rst b/docs/faq.rst
index 820fb60fa..52a99467c 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -6,7 +6,7 @@ FAQ
Why is there a django.contrib.sites directory in Cookiecutter Django?
---------------------------------------------------------------------
-It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and {{cookiecutter.project_name}} value is placed by **Cookiecutter** in the domain and name fields respectively.
+It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and ``{{cookiecutter.project_name}}`` value is placed by **Cookiecutter** in the domain and name fields respectively.
See `0003_set_site_domain_and_name.py`_.
diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst
index 26fb79d2f..2d8103cf2 100644
--- a/docs/project-generation-options.rst
+++ b/docs/project-generation-options.rst
@@ -55,17 +55,11 @@ use_docker:
postgresql_version:
Select a PostgreSQL_ version to use. The choices are:
- 1. 14.1
- 2. 13.5
- 3. 12.9
- 4. 11.14
- 5. 10.19
-
-js_task_runner:
- Select a JavaScript task runner. The choices are:
-
- 1. None
- 2. Gulp_
+ 1. 14
+ 2. 13
+ 3. 12
+ 4. 11
+ 5. 10
cloud_provider:
Select a cloud provider for static & media files. The choices are:
@@ -95,13 +89,12 @@ use_async:
use_drf:
Indicates whether the project should be configured to use `Django Rest Framework`_.
-custom_bootstrap_compilation:
- Indicates whether the project should support Bootstrap recompilation
- via the selected JavaScript task runner's task. This can be useful
- for real-time Bootstrap variable alteration.
+frontend_pipeline:
+ Select a pipeline to compile and optimise frontend assets (JS, CSS, ...):
-use_compressor:
- Indicates whether the project should be configured to use `Django Compressor`_.
+ 1. None
+ 2. `Django Compressor`_
+ 3. `Gulp`_: support Bootstrap recompilation with real-time variables alteration.
use_celery:
Indicates whether the project should be configured to use Celery_.
diff --git a/docs/requirements.txt b/docs/requirements.txt
index d9286ce24..c3b371b13 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,2 +1,2 @@
-sphinx==4.4.0
+sphinx==5.3.0
sphinx-rtd-theme==1.0.0
diff --git a/docs/settings.rst b/docs/settings.rst
index 7563f50d2..b8c6d448e 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -46,6 +46,7 @@ DJANGO_AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY n/a
DJANGO_AWS_STORAGE_BUCKET_NAME AWS_STORAGE_BUCKET_NAME n/a raises error
DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None
DJANGO_AWS_S3_CUSTOM_DOMAIN AWS_S3_CUSTOM_DOMAIN n/a None
+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
SENTRY_DSN SENTRY_DSN n/a raises error
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
index 83ef3ebe6..1b3433823 100644
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -10,7 +10,6 @@ TODO: restrict Cookiecutter Django project initialization to
"""
from __future__ import print_function
-import json
import os
import random
import shutil
@@ -92,6 +91,11 @@ def remove_gulp_files():
file_names = ["gulpfile.js"]
for file_name in file_names:
os.remove(file_name)
+ remove_sass_files()
+
+
+def remove_sass_files():
+ shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass"))
def remove_packagejson_file():
@@ -100,16 +104,6 @@ def remove_packagejson_file():
os.remove(file_name)
-def remove_bootstrap_packages():
- with open("package.json", mode="r") as fd:
- content = json.load(fd)
- for package_name in ["bootstrap", "gulp-concat", "@popperjs/core"]:
- content["devDependencies"].pop(package_name)
- with open("package.json", mode="w") as fd:
- json.dump(content, fd, ensure_ascii=False, indent=2)
- fd.write("\n")
-
-
def remove_celery_files():
file_names = [
os.path.join("config", "celery_app.py"),
@@ -329,7 +323,7 @@ def remove_drf_starter_files():
)
os.remove(
os.path.join(
- "{{cookiecutter.project_slug}}", "users", "tests", "test_swagger_ui.py"
+ "{{cookiecutter.project_slug}}", "users", "tests", "test_swagger.py"
)
)
@@ -368,13 +362,13 @@ def main():
if (
"{{ cookiecutter.use_docker }}".lower() == "y"
- and "{{ cookiecutter.cloud_provider}}".lower() != "aws"
+ and "{{ cookiecutter.cloud_provider}}" != "AWS"
):
remove_aws_dockerfile()
if "{{ cookiecutter.use_heroku }}".lower() == "n":
remove_heroku_files()
- elif "{{ cookiecutter.use_compressor }}".lower() == "n":
+ elif "{{ cookiecutter.frontend_pipeline }}" != "Django Compressor":
remove_heroku_build_hooks()
if (
@@ -394,13 +388,11 @@ def main():
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
append_to_gitignore_file("!.envs/.local/")
- if "{{ cookiecutter.js_task_runner}}".lower() == "none":
+ if "{{ cookiecutter.frontend_pipeline }}" != "Gulp":
remove_gulp_files()
remove_packagejson_file()
if "{{ cookiecutter.use_docker }}".lower() == "y":
remove_node_dockerfile()
- elif "{{ cookiecutter.custom_bootstrap_compilation }}" == "n":
- remove_bootstrap_packages()
if ("{{ cookiecutter.cloud_provider}}".lower() == "none") and (
"{{ cookiecutter.use_nginx_for_serve_media_files}}".lower() == "n"
@@ -419,13 +411,13 @@ def main():
if "{{ cookiecutter.use_docker }}".lower() == "y":
remove_celery_compose_dirs()
- if "{{ cookiecutter.ci_tool }}".lower() != "travis":
+ if "{{ cookiecutter.ci_tool }}" != "Travis":
remove_dottravisyml_file()
- if "{{ cookiecutter.ci_tool }}".lower() != "gitlab":
+ if "{{ cookiecutter.ci_tool }}" != "Gitlab":
remove_dotgitlabciyml_file()
- if "{{ cookiecutter.ci_tool }}".lower() != "github":
+ if "{{ cookiecutter.ci_tool }}" != "Github":
remove_dotgithub_folder()
if "{{ cookiecutter.use_drf }}".lower() == "n":
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
index 08983b918..aa3dcbc53 100644
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -42,7 +42,7 @@ if "{{ cookiecutter.use_docker }}".lower() == "n":
if python_major_version == 2:
print(
WARNING + "You're running cookiecutter under Python 2, but the generated "
- "project requires Python 3.9+. Do you want to proceed (y/n)? " + TERMINATOR
+ "project requires Python 3.10+. Do you want to proceed (y/n)? " + TERMINATOR
)
yes_options, no_options = frozenset(["y"]), frozenset(["n"])
while True:
diff --git a/pytest.ini b/pytest.ini
index 03ca13891..52506f47d 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,4 +1,3 @@
[pytest]
addopts = -v --tb=short
-python_paths = .
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/*
diff --git a/requirements.txt b/requirements.txt
index 763fe10e3..b72480ba4 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,26 +1,26 @@
-cookiecutter==1.7.3
-sh==1.14.2
+cookiecutter==2.1.1
+sh==1.14.3; sys_platform != "win32"
binaryornot==0.4.4
# Code quality
# ------------------------------------------------------------------------------
-black==21.12b0
+black==22.10.0
isort==5.10.1
-flake8==4.0.1
-flake8-isort==4.1.1
-pre-commit==2.17.0
+flake8==5.0.4
+flake8-isort==5.0.0
+pre-commit==2.20.0
# Testing
# ------------------------------------------------------------------------------
-tox==3.24.5
-pytest==6.2.5
+tox==3.26.0
+pytest==7.1.3
pytest-cookies==0.6.1
pytest-instafail==0.4.2
pyyaml==6.0
# Scripting
# ------------------------------------------------------------------------------
-PyGithub==1.55
-gitpython==3.1.26
-jinja2==3.0.3
-requests==2.27.1
+PyGithub==1.56
+gitpython==3.1.29
+jinja2==3.1.2
+requests==2.28.1
diff --git a/scripts/create_django_issue.py b/scripts/create_django_issue.py
index daee8fe16..5809f393d 100644
--- a/scripts/create_django_issue.py
+++ b/scripts/create_django_issue.py
@@ -11,8 +11,9 @@ from __future__ import annotations
import os
import re
import sys
+from collections.abc import Iterable
from pathlib import Path
-from typing import TYPE_CHECKING, Any, Iterable, NamedTuple
+from typing import TYPE_CHECKING, Any, NamedTuple
import requests
from github import Github
@@ -47,6 +48,11 @@ class DjVersion(NamedTuple):
major, minor, *_ = version_str.split(".")
return cls(major=int(major), minor=int(minor))
+ @classmethod
+ def parse_to_tuple(cls, version_str: str):
+ version = cls.parse(version_str=version_str)
+ return version.major, version.minor
+
def get_package_info(package: str) -> dict:
"""Get package metadata using PyPI API."""
@@ -75,17 +81,22 @@ def get_name_and_version(requirements_line: str) -> tuple[str, ...]:
return name_without_extras, version
-def get_all_latest_django_versions() -> tuple[DjVersion, list[DjVersion]]:
+def get_all_latest_django_versions(
+ django_max_version: tuple[DjVersion] = None,
+) -> tuple[DjVersion, list[DjVersion]]:
"""
Grabs all Django versions that are worthy of a GitHub issue.
-
Depends on Django versions having higher major version or minor version.
"""
+ _django_max_version = (99, 99)
+ if django_max_version:
+ _django_max_version = django_max_version
+
print("Fetching all Django versions from PyPI")
base_txt = REQUIREMENTS_DIR / "base.txt"
with base_txt.open() as f:
for line in f.readlines():
- if "django==" in line:
+ if "django==" in line.lower():
break
else:
print(f"django not found in {base_txt}") # Huh...?
@@ -97,7 +108,7 @@ def get_all_latest_django_versions() -> tuple[DjVersion, list[DjVersion]]:
current_minor_version = DjVersion.parse(current_version_str)
newer_versions: set[DjVersion] = set()
for django_version in get_django_versions():
- if django_version > current_minor_version:
+ if current_minor_version < django_version <= _django_max_version:
newer_versions.add(django_version)
return current_minor_version, sorted(newer_versions, reverse=True)
@@ -143,7 +154,13 @@ class GitHubManager:
for requirements_file in self.requirements_files:
with (REQUIREMENTS_DIR / f"{requirements_file}.txt").open() as f:
for line in f.readlines():
- if "==" in line and not line.startswith("{%"):
+ if (
+ "==" in line
+ and not line.startswith("{%")
+ and not line.startswith(" #")
+ and not line.startswith("#")
+ and not line.startswith(" ")
+ ):
name, version = get_name_and_version(line)
self.requirements[requirements_file][name] = (
version,
@@ -192,9 +209,9 @@ class GitHubManager:
# updated packages, or known releases that will happen but haven't yet
if issue := self.existing_issues.get(needed_dj_version):
if index := issue.body.find(package_name):
- name, _current, prev_compat, ok = [
+ name, _current, prev_compat, ok = (
s.strip() for s in issue.body[index:].split("|", 4)[:4]
- ]
+ )
if ok in ("✅", "❓", "🕒"):
return prev_compat, ok
@@ -251,11 +268,12 @@ class GitHubManager:
)
requirements += (
f"| {self._get_md_home_page_url(info).format(package_name)} "
- f"| {version} "
- f"| {compat_version} "
+ f"| {version.strip()} "
+ f"| {compat_version.strip()} "
f"| {icon} "
f"|\n"
)
+
return requirements
def create_or_edit_issue(self, needed_dj_version: DjVersion, description: str):
@@ -277,9 +295,11 @@ class GitHubManager:
self.create_or_edit_issue(version, md_content)
-def main() -> None:
+def main(django_max_version=None) -> None:
# Check if there are any djs
- current_dj, latest_djs = get_all_latest_django_versions()
+ current_dj, latest_djs = get_all_latest_django_versions(
+ django_max_version=django_max_version
+ )
if not latest_djs:
sys.exit(0)
manager = GitHubManager(current_dj, latest_djs)
@@ -292,4 +312,9 @@ if __name__ == "__main__":
raise RuntimeError(
"No github repo, please set the environment variable GITHUB_REPOSITORY"
)
- main()
+ max_version = None
+ last_arg = sys.argv[-1]
+ if CURRENT_FILE.name not in last_arg:
+ max_version = DjVersion.parse_to_tuple(version_str=last_arg)
+
+ main(django_max_version=max_version)
diff --git a/scripts/update_changelog.py b/scripts/update_changelog.py
index c3c834eef..b50d25066 100644
--- a/scripts/update_changelog.py
+++ b/scripts/update_changelog.py
@@ -1,8 +1,8 @@
import datetime as dt
import os
import re
+from collections.abc import Iterable
from pathlib import Path
-from typing import Iterable
import git
import github.PullRequest
diff --git a/setup.py b/setup.py
index cd7e7e9d4..722dc8a78 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ except ImportError:
from distutils.core import setup
# We use calendar versioning
-version = "2022.01.27"
+version = "2022.10.24"
with open("README.rst") as readme_file:
long_description = readme_file.read()
@@ -27,13 +27,13 @@ setup(
classifiers=[
"Development Status :: 4 - Beta",
"Environment :: Console",
- "Framework :: Django :: 3.2",
+ "Framework :: Django :: 4.0",
"Intended Audience :: Developers",
"Natural Language :: English",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development",
],
diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py
index 49a0d2cc8..3a757fcb7 100755
--- a/tests/test_cookiecutter_generation.py
+++ b/tests/test_cookiecutter_generation.py
@@ -47,11 +47,11 @@ SUPPORTED_COMBINATIONS = [
{"use_pycharm": "n"},
{"use_docker": "y"},
{"use_docker": "n"},
- {"postgresql_version": "14.1"},
- {"postgresql_version": "13.5"},
- {"postgresql_version": "12.9"},
- {"postgresql_version": "11.14"},
- {"postgresql_version": "10.19"},
+ {"postgresql_version": "14"},
+ {"postgresql_version": "13"},
+ {"postgresql_version": "12"},
+ {"postgresql_version": "11"},
+ {"postgresql_version": "10"},
{"cloud_provider": "AWS", "use_whitenoise": "y"},
{"cloud_provider": "AWS", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "use_whitenoise": "y"},
@@ -87,12 +87,9 @@ SUPPORTED_COMBINATIONS = [
{"use_async": "n"},
{"use_drf": "y"},
{"use_drf": "n"},
- {"js_task_runner": "None"},
- {"js_task_runner": "Gulp"},
- {"custom_bootstrap_compilation": "y"},
- {"custom_bootstrap_compilation": "n"},
- {"use_compressor": "y"},
- {"use_compressor": "n"},
+ {"frontend_pipeline": "None"},
+ {"frontend_pipeline": "Django Compressor"},
+ {"frontend_pipeline": "Gulp"},
{"use_celery": "y"},
{"use_celery": "n"},
{"use_mailhog": "y"},
@@ -141,7 +138,7 @@ def check_paths(paths):
if is_binary(path):
continue
- for line in open(path, "r"):
+ for line in open(path):
match = RE_OBJ.search(line)
assert match is None, f"cookiecutter variable not replaced in {path}"
@@ -153,10 +150,10 @@ def test_project_generation(cookies, context, context_override):
result = cookies.bake(extra_context={**context, **context_override})
assert result.exit_code == 0
assert result.exception is None
- assert result.project.basename == context["project_slug"]
- assert result.project.isdir()
+ assert result.project_path.name == context["project_slug"]
+ assert result.project_path.is_dir()
- paths = build_files_list(str(result.project))
+ paths = build_files_list(str(result.project_path))
assert paths
check_paths(paths)
@@ -167,7 +164,7 @@ def test_flake8_passes(cookies, context_override):
result = cookies.bake(extra_context=context_override)
try:
- sh.flake8(_cwd=str(result.project))
+ sh.flake8(_cwd=str(result.project_path))
except sh.ErrorReturnCode as e:
pytest.fail(e.stdout.decode())
@@ -179,7 +176,12 @@ def test_black_passes(cookies, context_override):
try:
sh.black(
- "--check", "--diff", "--exclude", "migrations", _cwd=str(result.project)
+ "--check",
+ "--diff",
+ "--exclude",
+ "migrations",
+ ".",
+ _cwd=str(result.project_path),
)
except sh.ErrorReturnCode as e:
pytest.fail(e.stdout.decode())
@@ -198,10 +200,10 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip
assert result.exit_code == 0
assert result.exception is None
- assert result.project.basename == context["project_slug"]
- assert result.project.isdir()
+ assert result.project_path.name == context["project_slug"]
+ assert result.project_path.is_dir()
- with open(f"{result.project}/.travis.yml", "r") as travis_yml:
+ with open(f"{result.project_path}/.travis.yml") as travis_yml:
try:
yml = yaml.safe_load(travis_yml)["jobs"]["include"]
assert yml[0]["script"] == ["flake8"]
@@ -225,10 +227,10 @@ def test_gitlab_invokes_flake8_and_pytest(
assert result.exit_code == 0
assert result.exception is None
- assert result.project.basename == context["project_slug"]
- assert result.project.isdir()
+ assert result.project_path.name == context["project_slug"]
+ assert result.project_path.is_dir()
- with open(f"{result.project}/.gitlab-ci.yml", "r") as gitlab_yml:
+ with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml:
try:
gitlab_config = yaml.safe_load(gitlab_yml)
assert gitlab_config["flake8"]["script"] == ["flake8"]
@@ -252,10 +254,10 @@ def test_github_invokes_linter_and_pytest(
assert result.exit_code == 0
assert result.exception is None
- assert result.project.basename == context["project_slug"]
- assert result.project.isdir()
+ assert result.project_path.name == context["project_slug"]
+ assert result.project_path.is_dir()
- with open(f"{result.project}/.github/workflows/ci.yml", "r") as github_yml:
+ with open(f"{result.project_path}/.github/workflows/ci.yml") as github_yml:
try:
github_config = yaml.safe_load(github_yml)
linter_present = False
@@ -306,6 +308,6 @@ def test_pycharm_docs_removed(cookies, context, use_pycharm, pycharm_docs_exist)
context.update({"use_pycharm": use_pycharm})
result = cookies.bake(extra_context=context)
- with open(f"{result.project}/docs/index.rst", "r") as f:
+ with open(f"{result.project_path}/docs/index.rst") as f:
has_pycharm_docs = "pycharm/configuration" in f.read()
assert has_pycharm_docs is pycharm_docs_exist
diff --git a/tox.ini b/tox.ini
index 0afe3931d..0400e4f91 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
[tox]
skipsdist = true
-envlist = py39,black-template
+envlist = py310,black-template
[testenv]
deps = -rrequirements.txt
diff --git a/{{cookiecutter.project_slug}}/.github/dependabot.yml b/{{cookiecutter.project_slug}}/.github/dependabot.yml
index cf88cf33b..420a63cdc 100644
--- a/{{cookiecutter.project_slug}}/.github/dependabot.yml
+++ b/{{cookiecutter.project_slug}}/.github/dependabot.yml
@@ -82,7 +82,7 @@ updates:
schedule:
interval: "daily"
-{%- if cookiecutter.js_task_runner != "None" %}
+{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
# Enable version updates for javascript/npm
- package-ecosystem: "npm"
diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
index c24f4cb94..0790187bd 100644
--- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
+++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml
@@ -14,6 +14,9 @@ on:
branches: [ "master", "main" ]
paths-ignore: [ "docs/**" ]
+concurrency:
+ group: {% raw %}${{ github.head_ref || github.run_id }}{% endraw %}
+ cancel-in-progress: true
jobs:
linter:
@@ -21,12 +24,12 @@ jobs:
steps:
- name: Checkout Code Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v3
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
cache-dependency-path: |
requirements/base.txt
@@ -65,7 +68,7 @@ jobs:
steps:
- name: Checkout Code Repository
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
{%- if cookiecutter.use_docker == 'y' %}
- name: Build the Stack
@@ -82,9 +85,9 @@ jobs:
{%- else %}
- name: Set up Python
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v3
with:
- python-version: "3.9"
+ python-version: "3.10"
cache: pip
cache-dependency-path: |
requirements/base.txt
diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore
index d48356fa1..ede26ef72 100644
--- a/{{cookiecutter.project_slug}}/.gitignore
+++ b/{{cookiecutter.project_slug}}/.gitignore
@@ -338,7 +338,7 @@ MailHog
.ipython/
{%- endif %}
-{%- if cookiecutter.js_task_runner == 'Gulp' %}
+{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
project.css
project.min.css
vendors.js
diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml
index 711bfc392..dbb65fb73 100644
--- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml
+++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml
@@ -13,7 +13,7 @@ variables:
flake8:
stage: lint
- image: python:3.9-alpine
+ image: python:3.10-alpine
before_script:
- pip install -q flake8
script:
@@ -22,7 +22,7 @@ flake8:
pytest:
stage: test
{% if cookiecutter.use_docker == 'y' -%}
- image: docker/compose:latest
+ image: docker/compose:1.29.2
tags:
- docker
services:
@@ -35,7 +35,7 @@ pytest:
script:
- docker-compose -f local.yml run django pytest
{%- else -%}
- image: python:3.9
+ image: python:3.10
tags:
- python
services:
diff --git a/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml
index 67f369a3c..ad3b6a35a 100644
--- a/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml
+++ b/{{cookiecutter.project_slug}}/.idea/runConfigurations/docker_compose_up_django.xml
@@ -10,7 +10,7 @@
{%- endif %}
- {%- if cookiecutter.js_task_runner == 'Gulp' %}
+ {%- if cookiecutter.frontend_pipeline == 'Gulp' %}
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml b/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml
index 289d9716a..98759fa1b 100644
--- a/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml
+++ b/{{cookiecutter.project_slug}}/.idea/{{cookiecutter.project_slug}}.iml
@@ -13,7 +13,7 @@
- {% if cookiecutter.js_task_runner != 'None' %}
+ {% if cookiecutter.frontend_pipeline == 'Gulp' %}
diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
index 301f8b74f..ebcc5989c 100644
--- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
+++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
@@ -3,14 +3,20 @@ default_stages: [commit]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.1.0
+ rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
+ - repo: https://github.com/asottile/pyupgrade
+ rev: v3.1.0
+ hooks:
+ - id: pyupgrade
+ args: [--py310-plus]
+
- repo: https://github.com/psf/black
- rev: 21.12b0
+ rev: 22.10.0
hooks:
- id: black
@@ -20,7 +26,7 @@ repos:
- id: isort
- repo: https://github.com/PyCQA/flake8
- rev: 4.0.1
+ rev: 5.0.4
hooks:
- id: flake8
args: ["--config=setup.cfg"]
diff --git a/{{cookiecutter.project_slug}}/.pylintrc b/{{cookiecutter.project_slug}}/.pylintrc
index 6f195c6ef..9d604334b 100644
--- a/{{cookiecutter.project_slug}}/.pylintrc
+++ b/{{cookiecutter.project_slug}}/.pylintrc
@@ -1,6 +1,6 @@
[MASTER]
load-plugins=pylint_django{% if cookiecutter.use_celery == "y" %}, pylint_celery{% endif %}
-django-settings-module=config.settings.base
+django-settings-module=config.settings.local
[FORMAT]
max-line-length=120
diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml
index b4cf0c080..e943a5fa9 100644
--- a/{{cookiecutter.project_slug}}/.readthedocs.yml
+++ b/{{cookiecutter.project_slug}}/.readthedocs.yml
@@ -7,6 +7,6 @@ build:
image: testing
python:
- version: 3.9
+ version: 3.10
install:
- requirements: requirements/local.txt
diff --git a/{{cookiecutter.project_slug}}/.travis.yml b/{{cookiecutter.project_slug}}/.travis.yml
index a684da225..326d78392 100644
--- a/{{cookiecutter.project_slug}}/.travis.yml
+++ b/{{cookiecutter.project_slug}}/.travis.yml
@@ -2,7 +2,7 @@ dist: focal
language: python
python:
- - "3.9"
+ - "3.10"
services:
- {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %}
@@ -37,7 +37,7 @@ jobs:
- sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm
language: python
python:
- - "3.9"
+ - "3.10"
install:
- pip install -r requirements/local.txt
script:
diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md
index 227e24c00..f7c29fb22 100644
--- a/{{cookiecutter.project_slug}}/README.md
+++ b/{{cookiecutter.project_slug}}/README.md
@@ -20,7 +20,7 @@ Moved to [settings](http://cookiecutter-django.readthedocs.io/en/latest/settings
- To create a **normal user account**, just go to Sign Up and fill out the form. Once you submit it, you'll see a "Verify Your E-mail Address" page. Go to your console to see a simulated email verification message. Copy the link into your browser. Now the user's email should be verified and ready to go.
-- To create an **superuser account**, use this command:
+- To create a **superuser account**, use this command:
$ python manage.py createsuperuser
@@ -46,7 +46,7 @@ To run the tests, check your test coverage, and generate an HTML coverage report
### Live reloading and Sass CSS compilation
-Moved to [Live reloading and SASS compilation](http://cookiecutter-django.readthedocs.io/en/latest/live-reloading-and-sass-compilation.html).
+Moved to [Live reloading and SASS compilation](https://cookiecutter-django.readthedocs.io/en/latest/developing-locally.html#sass-compilation-live-reloading).
{%- if cookiecutter.use_celery == "y" %}
@@ -128,7 +128,7 @@ See detailed [cookiecutter-django Heroku documentation](http://cookiecutter-djan
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
{%- endif %}
-{%- if cookiecutter.custom_bootstrap_compilation == "y" %}
+{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
### Custom Bootstrap Compilation
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
@@ -136,8 +136,5 @@ Bootstrap v5 is installed using npm and customised by tweaking your variables in
You can find a list of available variables [in the bootstrap source](https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/docs/5.1/customize/sass/).
-{%- if cookiecutter.js_task_runner == "Gulp" %}
Bootstrap's javascript as well as its dependencies is concatenated into a single file: `static/js/vendors.js`.
{%- endif %}
-
-{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
index 044ef4a74..3ea6b2d4c 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
@@ -1,4 +1,4 @@
-ARG PYTHON_VERSION=3.9-slim-bullseye
+ARG PYTHON_VERSION=3.10-slim-bullseye
# define an alias for the specfic python version used in this file.
FROM python:${PYTHON_VERSION} as python
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start
index d7b63cd41..4ddcfa137 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
-watchgod celery.__main__.main --args -A config.celery_app worker -l INFO
+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 9cbb6c897..3fe547357 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
+uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
{%- else %}
python manage.py runserver_plus 0.0.0.0:8000
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
index 6f1bb8b5e..c45d18c95 100644
--- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile
@@ -1,4 +1,4 @@
-ARG PYTHON_VERSION=3.9-slim-bullseye
+ARG PYTHON_VERSION=3.10-slim-bullseye
# define an alias for the specfic python version used in this file.
FROM python:${PYTHON_VERSION} as python
@@ -22,7 +22,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
COPY ./requirements /requirements
# create python dependency wheels
-RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels \
+RUN pip wheel --no-cache-dir --wheel-dir /usr/src/app/wheels \
-r /requirements/local.txt -r /requirements/production.txt \
&& rm -rf /requirements
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
index 1dd47a2f7..4652f0898 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
@@ -1,6 +1,6 @@
-ARG PYTHON_VERSION=3.9-slim-bullseye
+ARG PYTHON_VERSION=3.10-slim-bullseye
-{% if cookiecutter.js_task_runner == 'Gulp' -%}
+{% if cookiecutter.frontend_pipeline == 'Gulp' -%}
FROM node:16-bullseye-slim as client-builder
ARG APP_HOME=/app
@@ -99,7 +99,7 @@ RUN chmod +x /start-flower
# copy application code to WORKDIR
-{%- if cookiecutter.js_task_runner == 'Gulp' %}
+{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME}
{% else %}
COPY --chown=django:django . ${APP_HOME}
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint
index 95ab8297a..2fbcad955 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint
+++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint
@@ -16,30 +16,34 @@ if [ -z "${POSTGRES_USER}" ]; then
fi
export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}"
-postgres_ready() {
python << END
import sys
+import time
import psycopg2
-try:
- psycopg2.connect(
- dbname="${POSTGRES_DB}",
- user="${POSTGRES_USER}",
- password="${POSTGRES_PASSWORD}",
- host="${POSTGRES_HOST}",
- port="${POSTGRES_PORT}",
- )
-except psycopg2.OperationalError:
- sys.exit(-1)
-sys.exit(0)
+suggest_unrecoverable_after = 30
+start = time.time()
+while True:
+ try:
+ psycopg2.connect(
+ dbname="${POSTGRES_DB}",
+ user="${POSTGRES_USER}",
+ password="${POSTGRES_PASSWORD}",
+ host="${POSTGRES_HOST}",
+ port="${POSTGRES_PORT}",
+ )
+ break
+ except psycopg2.OperationalError as error:
+ sys.stderr.write("Waiting for PostgreSQL to become available...\n")
+
+ if time.time() - start > suggest_unrecoverable_after:
+ sys.stderr.write(" This is taking longer than expected. The following exception may be indicative of an unrecoverable error: '{}'\n".format(error))
+
+ time.sleep(1)
END
-}
-until postgres_ready; do
- >&2 echo 'Waiting for PostgreSQL to become available...'
- sleep 1
-done
+
>&2 echo 'PostgreSQL is available'
exec "$@"
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/start b/{{cookiecutter.project_slug}}/compose/production/django/start
index 8e324afe0..2ba79501c 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/start
+++ b/{{cookiecutter.project_slug}}/compose/production/django/start
@@ -6,7 +6,7 @@ set -o nounset
python /app/manage.py collectstatic --noinput
-{% if cookiecutter.use_whitenoise == 'y' and cookiecutter.use_compressor == 'y' %}
+{% if cookiecutter.use_whitenoise == 'y' and cookiecutter.frontend_pipeline == 'Django Compressor' %}
compress_enabled() {
python << END
import sys
diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py
index 1598373d3..ad879fa72 100644
--- a/{{cookiecutter.project_slug}}/config/settings/base.py
+++ b/{{cookiecutter.project_slug}}/config/settings/base.py
@@ -44,7 +44,10 @@ LOCALE_PATHS = [str(ROOT_DIR / "locale")]
DATABASES = {"default": env.db("DATABASE_URL")}
{%- else %}
DATABASES = {
- "default": env.db("DATABASE_URL", default="postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}"),
+ "default": env.db(
+ "DATABASE_URL",
+ default="postgres://{% if cookiecutter.windows == 'y' %}localhost{% endif %}/{{cookiecutter.project_slug}}",
+ ),
}
{%- endif %}
DATABASES["default"]["ATOMIC_REQUESTS"] = True
@@ -274,25 +277,25 @@ LOGGING = {
# Celery
# ------------------------------------------------------------------------------
if USE_TZ:
- # http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-timezone
+ # https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-timezone
CELERY_TIMEZONE = TIME_ZONE
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-broker_url
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-broker_url
CELERY_BROKER_URL = env("CELERY_BROKER_URL")
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_backend
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-result_backend
CELERY_RESULT_BACKEND = CELERY_BROKER_URL
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-accept_content
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-accept_content
CELERY_ACCEPT_CONTENT = ["json"]
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-task_serializer
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-task_serializer
CELERY_TASK_SERIALIZER = "json"
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#std:setting-result_serializer
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-result_serializer
CELERY_RESULT_SERIALIZER = "json"
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-time-limit
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-time-limit
# TODO: set to whatever value is adequate in your circumstances
CELERY_TASK_TIME_LIMIT = 5 * 60
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-soft-time-limit
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-soft-time-limit
# TODO: set to whatever value is adequate in your circumstances
CELERY_TASK_SOFT_TIME_LIMIT = 60
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#beat-scheduler
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-scheduler
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
{%- endif %}
@@ -313,7 +316,7 @@ ACCOUNT_FORMS = {"signup": "{{cookiecutter.project_slug}}.users.forms.UserSignup
SOCIALACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter"
# https://django-allauth.readthedocs.io/en/latest/forms.html
SOCIALACCOUNT_FORMS = {"signup": "{{cookiecutter.project_slug}}.users.forms.UserSocialSignupForm"}
-{% if cookiecutter.use_compressor == 'y' -%}
+{% if cookiecutter.frontend_pipeline == 'Django Compressor' -%}
# django-compressor
# ------------------------------------------------------------------------------
# https://django-compressor.readthedocs.io/en/latest/quickstart/#installation
@@ -330,20 +333,21 @@ REST_FRAMEWORK = {
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
+ "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}
# django-cors-headers - https://github.com/adamchainz/django-cors-headers#setup
CORS_URLS_REGEX = r"^/api/.*$"
-# By Default swagger ui is available only to admin user. You can change permission classs to change that
+# By Default swagger ui is available only to admin user(s). You can change permission classes to change that
# See more configuration options at https://drf-spectacular.readthedocs.io/en/latest/settings.html#settings
SPECTACULAR_SETTINGS = {
"TITLE": "{{ cookiecutter.project_name }} API",
- "DESCRIPTION": "Documentation of API endpoiints of {{ cookiecutter.project_name }}",
+ "DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}",
"VERSION": "1.0.0",
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
"SERVERS": [
- {"url": "https://127.0.0.1:8000", "description": "Local Development server"},
+ {"url": "http://127.0.0.1:8000", "description": "Local Development server"},
{"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"},
],
}
diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py
index 3ce150e1c..a5fe0f71c 100644
--- a/{{cookiecutter.project_slug}}/config/settings/local.py
+++ b/{{cookiecutter.project_slug}}/config/settings/local.py
@@ -69,7 +69,7 @@ if env("USE_DOCKER") == "yes":
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
- {%- if cookiecutter.js_task_runner == 'Gulp' %}
+ {%- if cookiecutter.frontend_pipeline == 'Gulp' %}
try:
_, _, ips = socket.gethostbyname_ex("node")
INTERNAL_IPS.extend(ips)
@@ -88,10 +88,10 @@ INSTALLED_APPS += ["django_extensions"] # noqa F405
# Celery
# ------------------------------------------------------------------------------
{% if cookiecutter.use_docker == 'n' -%}
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-always-eager
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-always-eager
CELERY_TASK_ALWAYS_EAGER = True
{%- endif %}
-# http://docs.celeryproject.org/en/latest/userguide/configuration.html#task-eager-propagates
+# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-eager-propagates
CELERY_TASK_EAGER_PROPAGATES = True
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py
index 06eb8d492..8eed5a805 100644
--- a/{{cookiecutter.project_slug}}/config/settings/production.py
+++ b/{{cookiecutter.project_slug}}/config/settings/production.py
@@ -88,6 +88,11 @@ AWS_S3_OBJECT_PARAMETERS = {
"CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate"
}
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
+AWS_S3_MAX_MEMORY_SIZE = env.int(
+ "DJANGO_AWS_S3_MAX_MEMORY_SIZE",
+ default=100_000_000, # 100MB
+)
+# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None)
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#cloudfront
AWS_S3_CUSTOM_DOMAIN = env("DJANGO_AWS_S3_CUSTOM_DOMAIN", default=None)
@@ -167,7 +172,6 @@ EMAIL_BACKEND = "anymail.backends.mailjet.EmailBackend"
ANYMAIL = {
"MAILJET_API_KEY": env("MAILJET_API_KEY"),
"MAILJET_SECRET_KEY": env("MAILJET_SECRET_KEY"),
- "MAILJET_API_URL": env("MAILJET_API_URL", default="https://api.mailjet.com/v3"),
}
{%- elif cookiecutter.mail_service == 'Mandrill' %}
# https://anymail.readthedocs.io/en/stable/esps/mandrill/
@@ -190,8 +194,6 @@ ANYMAIL = {
EMAIL_BACKEND = "anymail.backends.sendgrid.EmailBackend"
ANYMAIL = {
"SENDGRID_API_KEY": env("SENDGRID_API_KEY"),
- "SENDGRID_GENERATE_MESSAGE_ID": env("SENDGRID_GENERATE_MESSAGE_ID"),
- "SENDGRID_MERGE_FIELD_FORMAT": env("SENDGRID_MERGE_FIELD_FORMAT"),
"SENDGRID_API_URL": env("SENDGRID_API_URL", default="https://api.sendgrid.com/v3/"),
}
{%- elif cookiecutter.mail_service == 'SendinBlue' %}
@@ -218,7 +220,7 @@ EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
ANYMAIL = {}
{%- endif %}
-{% if cookiecutter.use_compressor == 'y' -%}
+{% if cookiecutter.frontend_pipeline == 'Django Compressor' -%}
# django-compressor
# ------------------------------------------------------------------------------
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_ENABLED
diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py
index 78fb6cc66..f103eb10b 100644
--- a/{{cookiecutter.project_slug}}/config/settings/test.py
+++ b/{{cookiecutter.project_slug}}/config/settings/test.py
@@ -25,5 +25,9 @@ PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
+# DEBUGING FOR TEMPLATES
+# ------------------------------------------------------------------------------
+TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa F405
+
# Your stuff...
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/docs/Makefile b/{{cookiecutter.project_slug}}/docs/Makefile
index 0c4f9f574..cf080e476 100644
--- a/{{cookiecutter.project_slug}}/docs/Makefile
+++ b/{{cookiecutter.project_slug}}/docs/Makefile
@@ -3,7 +3,7 @@
# You can set these variables from the command line, and also
# from the environment for the first two.
-SPHINXOPTS ?=
+SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = ./_build
@@ -21,10 +21,10 @@ help:
# Build, watch and serve docs with live reload
livehtml:
- sphinx-autobuild -b html
+ sphinx-autobuild -b html
{%- if cookiecutter.use_docker == 'y' %} --host 0.0.0.0
- {%- else %} --open-browser
- {%- endif %} --port 7000 --watch $(APP) -c . $(SOURCEDIR) $(BUILDDIR)/html
+ {%- else %} --open-browser
+ {%- endif %} --port 9000 --watch $(APP) -c . $(SOURCEDIR) $(BUILDDIR)/html
# Outputs rst files from django application code
apidocs:
diff --git a/{{cookiecutter.project_slug}}/docs/howto.rst b/{{cookiecutter.project_slug}}/docs/howto.rst
index 0ef90d023..7f2d26a1e 100644
--- a/{{cookiecutter.project_slug}}/docs/howto.rst
+++ b/{{cookiecutter.project_slug}}/docs/howto.rst
@@ -28,7 +28,7 @@ Docstrings to Documentation
The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings.
-Numpy or Google style docstrings will be picked up from project files and availble for documentation. See the `Napoleon `_ extension for details.
+Numpy or Google style docstrings will be picked up from project files and available for documentation. See the `Napoleon `_ extension for details.
For an in-use example, see the `page source <_sources/users.rst.txt>`_ for :ref:`users`.
diff --git a/{{cookiecutter.project_slug}}/docs/make.bat b/{{cookiecutter.project_slug}}/docs/make.bat
index b19f42c6a..6cd1129f0 100644
--- a/{{cookiecutter.project_slug}}/docs/make.bat
+++ b/{{cookiecutter.project_slug}}/docs/make.bat
@@ -32,7 +32,7 @@ if errorlevel 9009 (
goto end
:livehtml
-sphinx-autobuild -b html --open-browser -p 7000 --watch %APP% -c . %SOURCEDIR% %BUILDDIR%/html
+sphinx-autobuild -b html --open-browser -p 9000 --watch %APP% -c . %SOURCEDIR% %BUILDDIR%/html
GOTO :EOF
:apidocs
diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js
index 0f90be220..680e3672e 100644
--- a/{{cookiecutter.project_slug}}/gulpfile.js
+++ b/{{cookiecutter.project_slug}}/gulpfile.js
@@ -9,9 +9,7 @@ const pjson = require('./package.json')
// Plugins
const autoprefixer = require('autoprefixer')
const browserSync = require('browser-sync').create()
-{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
const concat = require('gulp-concat')
-{% endif %}
const cssnano = require ('cssnano')
const imagemin = require('gulp-imagemin')
const pixrem = require('pixrem')
@@ -29,13 +27,11 @@ function pathsConfig(appName) {
const vendorsRoot = 'node_modules'
return {
- {%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
bootstrapSass: `${vendorsRoot}/bootstrap/scss`,
vendorsJs: [
`${vendorsRoot}/@popperjs/core/dist/umd/popper.js`,
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
],
- {%- endif %}
app: this.app,
templates: `${this.app}/templates`,
css: `${this.app}/static/css`,
@@ -46,7 +42,7 @@ function pathsConfig(appName) {
}
}
-var paths = pathsConfig()
+const paths = pathsConfig()
////////////////////////////////
// Tasks
@@ -54,21 +50,19 @@ var paths = pathsConfig()
// Styles autoprefixing and minification
function styles() {
- var processCss = [
+ const processCss = [
autoprefixer(), // adds vendor prefixes
pixrem(), // add fallbacks for rem units
]
- var minifyCss = [
+ const minifyCss = [
cssnano({ preset: 'default' }) // minify result
]
return src(`${paths.sass}/project.scss`)
.pipe(sass({
includePaths: [
- {%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
paths.bootstrapSass,
- {%- endif %}
paths.sass
]
}).on('error', sass.logError))
@@ -89,7 +83,6 @@ function scripts() {
.pipe(dest(paths.js))
}
-{%- if cookiecutter.custom_bootstrap_compilation == 'y' %}
// Vendor Javascript minification
function vendorScripts() {
return src(paths.vendorsJs)
@@ -100,7 +93,6 @@ function vendorScripts() {
.pipe(rename({ suffix: '.min' }))
.pipe(dest(paths.js))
}
-{%- endif %}
// Image compression
function imgCompression() {
@@ -112,7 +104,7 @@ function imgCompression() {
{%- if cookiecutter.use_async == 'y' -%}
// Run django server
function asyncRunServer() {
- var cmd = spawn('gunicorn', [
+ const cmd = spawn('gunicorn', [
'config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload'
], {stdio: 'inherit'}
)
@@ -123,7 +115,7 @@ function asyncRunServer() {
{%- else %}
// Run django server
function runServer(cb) {
- var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'})
+ const cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'})
cmd.on('close', function(code) {
console.log('runServer exited with code ' + code)
cb(code)
@@ -173,7 +165,7 @@ function watchPaths() {
const generateAssets = parallel(
styles,
scripts,
- {%- if cookiecutter.custom_bootstrap_compilation == 'y' %}vendorScripts,{% endif %}
+ vendorScripts,
imgCompression
)
diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml
index 5090c5cef..fb203acd6 100644
--- a/{{cookiecutter.project_slug}}/local.yml
+++ b/{{cookiecutter.project_slug}}/local.yml
@@ -11,6 +11,7 @@ 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' %}
@@ -43,6 +44,7 @@ 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
@@ -53,7 +55,7 @@ services:
- ./config:/app/config:z
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
ports:
- - "7000:7000"
+ - "9000:9000"
command: /start-docs
{%- if cookiecutter.use_mailhog == 'y' %}
@@ -105,7 +107,7 @@ services:
command: /start-flower
{%- endif %}
- {%- if cookiecutter.js_task_runner == 'Gulp' %}
+ {%- if cookiecutter.frontend_pipeline == 'Gulp' %}
node:
build:
diff --git a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py
index d1170eff6..d702a5f67 100644
--- a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py
+++ b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py
@@ -1,6 +1,6 @@
import os
+from collections.abc import Sequence
from pathlib import Path
-from typing import Sequence
import pytest
@@ -18,7 +18,7 @@ def merge(
) -> None:
with open(output_file_path, "w") as output_file:
for merged_file_path in merged_file_paths:
- with open(merged_file_path, "r") as merged_file:
+ with open(merged_file_path) as merged_file:
merged_file_content = merged_file.read()
output_file.write(merged_file_content)
if append_linesep:
@@ -41,7 +41,7 @@ def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool):
for i in range(merged_file_count):
merged_file_ord = i + 1
- merged_filename = ".service{}".format(merged_file_ord)
+ merged_filename = f".service{merged_file_ord}"
merged_file_path = tmp_dir_path / merged_filename
merged_file_content = merged_filename * merged_file_ord
@@ -57,7 +57,7 @@ def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool):
merge(output_file_path, merged_file_paths, append_linesep)
- with open(output_file_path, "r") as output_file:
+ with open(output_file_path) as output_file:
actual_output_file_content = output_file.read()
assert actual_output_file_content == expected_output_file_content
diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml
index 1f623c2ad..d0be91273 100644
--- a/{{cookiecutter.project_slug}}/production.yml
+++ b/{{cookiecutter.project_slug}}/production.yml
@@ -18,6 +18,7 @@ services:
volumes:
- production_nginx_media:/app/{{ cookiecutter.project_slug }}/media:z
{% endif %}
+ platform: linux/x86_64
depends_on:
- postgres
- redis
diff --git a/{{cookiecutter.project_slug}}/pytest.ini b/{{cookiecutter.project_slug}}/pytest.ini
index e3b2248d9..969c7921e 100644
--- a/{{cookiecutter.project_slug}}/pytest.ini
+++ b/{{cookiecutter.project_slug}}/pytest.ini
@@ -1,6 +1,6 @@
[pytest]
addopts = --ds=config.settings.test --reuse-db
python_files = tests.py test_*.py
-{%- if cookiecutter.js_task_runner != 'None' %}
+{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
norecursedirs = node_modules
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt
index 9c2c9b042..de5c61416 100644
--- a/{{cookiecutter.project_slug}}/requirements/base.txt
+++ b/{{cookiecutter.project_slug}}/requirements/base.txt
@@ -1,7 +1,7 @@
-pytz==2021.3 # https://github.com/stub42/pytz
-python-slugify==5.0.2 # https://github.com/un33k/python-slugify
-Pillow==9.0.0 # https://github.com/python-pillow/Pillow
-{%- if cookiecutter.use_compressor == "y" %}
+pytz==2022.5 # https://github.com/stub42/pytz
+python-slugify==6.1.2 # https://github.com/un33k/python-slugify
+Pillow==9.2.0 # https://github.com/python-pillow/Pillow
+{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin
{%- else %}
@@ -10,39 +10,39 @@ rcssmin==1.1.0 # https://github.com/ndparker/rcssmin
{%- endif %}
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %}
-whitenoise==5.3.0 # https://github.com/evansd/whitenoise
+whitenoise==6.2.0 # https://github.com/evansd/whitenoise
{%- endif %}
-redis==4.1.2 # https://github.com/redis/redis-py
+redis==4.3.4 # 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 %}
{%- if cookiecutter.use_celery == "y" %}
-celery==5.2.3 # pyup: < 6.0 # https://github.com/celery/celery
-django-celery-beat==2.2.1 # https://github.com/celery/django-celery-beat
+celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery
+django-celery-beat==2.4.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %}
-flower==1.0.0 # https://github.com/mher/flower
+flower==1.2.0 # https://github.com/mher/flower
{%- endif %}
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
-uvicorn[standard]==0.17.0.post1 # https://github.com/encode/uvicorn
+uvicorn[standard]==0.18.3 # https://github.com/encode/uvicorn
{%- endif %}
# Django
# ------------------------------------------------------------------------------
-django==3.2.11 # pyup: < 4.0 # https://www.djangoproject.com/
-django-environ==0.8.1 # https://github.com/joke2k/django-environ
+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-allauth==0.47.0 # https://github.com/pennersr/django-allauth
+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.6 # https://github.com/django-crispy-forms/crispy-bootstrap5
-{%- if cookiecutter.use_compressor == "y" %}
-django-compressor==3.1 # https://github.com/django-compressor/django-compressor
+{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
+django-compressor==4.1 # https://github.com/django-compressor/django-compressor
{%- endif %}
django-redis==5.2.0 # https://github.com/jazzband/django-redis
-{%- if cookiecutter.use_drf == "y" %}
+{%- if cookiecutter.use_drf == 'y' %}
# Django REST Framework
-djangorestframework==3.13.1 # https://github.com/encode/django-rest-framework
-django-cors-headers==3.11.0 # https://github.com/adamchainz/django-cors-headers
+djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
+django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation
-drf-spectacular==0.21.1
+drf-spectacular==0.24.2 # https://github.com/tfranzel/drf-spectacular
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index 784d02349..77cba3177 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -1,48 +1,48 @@
-r base.txt
-Werkzeug[watchdog]==2.0.2 # https://github.com/pallets/werkzeug
+Werkzeug[watchdog]==2.2.2 # https://github.com/pallets/werkzeug
ipdb==0.13.9 # https://github.com/gotcha/ipdb
{%- if cookiecutter.use_docker == 'y' %}
-psycopg2==2.9.3 # https://github.com/psycopg/psycopg2
+psycopg2==2.9.4 # https://github.com/psycopg/psycopg2
{%- else %}
-psycopg2-binary==2.9.3 # https://github.com/psycopg/psycopg2
+psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2
{%- endif %}
{%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %}
-watchgod==0.7 # https://github.com/samuelcolvin/watchgod
+watchfiles==0.18.0 # https://github.com/samuelcolvin/watchfiles
{%- endif %}
# Testing
# ------------------------------------------------------------------------------
-mypy==0.931 # https://github.com/python/mypy
-django-stubs==1.9.0 # https://github.com/typeddjango/django-stubs
-pytest==6.2.5 # https://github.com/pytest-dev/pytest
-pytest-sugar==0.9.4 # https://github.com/Frozenball/pytest-sugar
+mypy==0.982 # https://github.com/python/mypy
+django-stubs==1.12.0 # https://github.com/typeddjango/django-stubs
+pytest==7.1.3 # https://github.com/pytest-dev/pytest
+pytest-sugar==0.9.5 # https://github.com/Frozenball/pytest-sugar
{%- if cookiecutter.use_drf == "y" %}
-djangorestframework-stubs==1.4.0 # https://github.com/typeddjango/djangorestframework-stubs
+djangorestframework-stubs==1.7.0 # https://github.com/typeddjango/djangorestframework-stubs
{%- endif %}
# Documentation
# ------------------------------------------------------------------------------
-sphinx==4.4.0 # https://github.com/sphinx-doc/sphinx
+sphinx==5.3.0 # https://github.com/sphinx-doc/sphinx
sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild
# Code quality
# ------------------------------------------------------------------------------
-flake8==4.0.1 # https://github.com/PyCQA/flake8
-flake8-isort==4.1.1 # https://github.com/gforcada/flake8-isort
-coverage==6.3 # https://github.com/nedbat/coveragepy
-black==21.12b0 # https://github.com/psf/black
-pylint-django==2.5.0 # https://github.com/PyCQA/pylint-django
+flake8==5.0.4 # https://github.com/PyCQA/flake8
+flake8-isort==5.0.0 # 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
{%- if cookiecutter.use_celery == 'y' %}
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
{%- endif %}
-pre-commit==2.17.0 # https://github.com/pre-commit/pre-commit
+pre-commit==2.20.0 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy
-django-debug-toolbar==3.2.4 # https://github.com/jazzband/django-debug-toolbar
-django-extensions==3.1.5 # https://github.com/django-extensions/django-extensions
-django-coverage-plugin==2.0.2 # https://github.com/nedbat/django_coverage_plugin
+django-debug-toolbar==3.7.0 # https://github.com/jazzband/django-debug-toolbar
+django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions
+django-coverage-plugin==2.0.3 # https://github.com/nedbat/django_coverage_plugin
pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django
diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt
index faefd1245..88f6a706a 100644
--- a/{{cookiecutter.project_slug}}/requirements/production.txt
+++ b/{{cookiecutter.project_slug}}/requirements/production.txt
@@ -3,12 +3,12 @@
-r base.txt
gunicorn==20.1.0 # https://github.com/benoitc/gunicorn
-psycopg2==2.9.3 # https://github.com/psycopg/psycopg2
+psycopg2==2.9.4 # https://github.com/psycopg/psycopg2
{%- if cookiecutter.use_whitenoise == 'n' %}
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
-sentry-sdk==1.5.4 # https://github.com/getsentry/sentry-python
+sentry-sdk==1.10.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
@@ -17,26 +17,26 @@ hiredis==2.0.0 # https://github.com/redis/hiredis-py
# Django
# ------------------------------------------------------------------------------
{%- if cookiecutter.cloud_provider == 'AWS' %}
-django-storages[boto3]==1.12.3 # https://github.com/jschneier/django-storages
+django-storages[boto3]==1.13.1 # https://github.com/jschneier/django-storages
{%- elif cookiecutter.cloud_provider == 'GCP' %}
-django-storages[google]==1.12.3 # https://github.com/jschneier/django-storages
+django-storages[google]==1.13.1 # https://github.com/jschneier/django-storages
{%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %}
-django-anymail[mailgun]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[mailgun]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Amazon SES' %}
-django-anymail[amazon_ses]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[amazon_ses]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mailjet' %}
-django-anymail[mailjet]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[mailjet]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mandrill' %}
-django-anymail[mandrill]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[mandrill]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Postmark' %}
-django-anymail[postmark]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[postmark]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Sendgrid' %}
-django-anymail[sendgrid]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[sendgrid]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SendinBlue' %}
-django-anymail[sendinblue]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[sendinblue]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SparkPost' %}
-django-anymail[sparkpost]==8.5 # https://github.com/anymail/django-anymail
+django-anymail[sparkpost]==8.6 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
-django-anymail==8.5 # https://github.com/anymail/django-anymail
+django-anymail==8.6 # https://github.com/anymail/django-anymail
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt
index 425359e69..69b0ccfc8 100644
--- a/{{cookiecutter.project_slug}}/runtime.txt
+++ b/{{cookiecutter.project_slug}}/runtime.txt
@@ -1 +1 @@
-python-3.9.9
+python-3.10.8
diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg
index dad64e1fa..3bec1fbee 100644
--- a/{{cookiecutter.project_slug}}/setup.cfg
+++ b/{{cookiecutter.project_slug}}/setup.cfg
@@ -18,7 +18,7 @@ force_grid_wrap = 0
use_parentheses = true
[mypy]
-python_version = 3.9
+python_version = 3.10
check_untyped_defs = True
ignore_missing_imports = True
warn_unused_ignores = True
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py
index b4056707a..fb6532709 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py
@@ -1,7 +1,5 @@
__version__ = "{{ cookiecutter.version }}"
__version_info__ = tuple(
- [
- int(num) if num.isdigit() else num
- for num in __version__.replace("-", ".", 1).split(".")
- ]
+ int(num) if num.isdigit() else num
+ for num in __version__.replace("-", ".", 1).split(".")
)
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py
index 335648e07..7095a4714 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py
@@ -10,5 +10,5 @@ def media_storage(settings, tmpdir):
@pytest.fixture
-def user() -> User:
+def user(db) -> User:
return UserFactory()
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss
index 9fbf1b746..370096bb3 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/static/sass/project.scss
@@ -1,8 +1,5 @@
-{% if cookiecutter.custom_bootstrap_compilation == 'y' %}
@import "custom_bootstrap_vars";
@import "bootstrap";
-{% endif %}
-
// project specific CSS goes here
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
index e5087534d..58aca7208 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
@@ -1,4 +1,4 @@
-{% raw %}{% load static i18n {% endraw %}{% if cookiecutter.use_compressor == "y" %}compress{% endif %}{% raw %}%}
+{% raw %}{% load static i18n {% endraw %}{% if cookiecutter.frontend_pipeline == 'Django Compressor' %}compress{% endif %}{% raw %}%}
{% get_current_language as LANGUAGE_CODE %}
@@ -12,30 +12,34 @@
{% block css %}
- {%- endraw %}{% if cookiecutter.custom_bootstrap_compilation == "n" %}{% raw %}
+ {%- endraw %}
+ {%- if cookiecutter.frontend_pipeline != 'Gulp' %}
+ {%- raw %}
- {%- endraw %}{% endif %}{% raw %}
-
+ {%- endraw %}
+ {%- endif %}
+ {%- raw %}
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress css %}{% endraw %}{% endif %}{% raw %}
+
- {%- endraw %}{% if cookiecutter.js_task_runner == "Gulp" and cookiecutter.use_compressor == "n" %}{% raw %}
-
- {%- endraw %}{% else %}{% raw %}
+ {%- endraw %}{% if cookiecutter.frontend_pipeline == 'None' %}{% raw %}
+ {%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Django Compressor' %}{% raw %}
+ {% compress css %}
+
+ {% endcompress %}
+ {%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
+
{%- endraw %}{% endif %}{% raw %}
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock %}
{# Placed at the top of the document so pages load faster with defer #}
{% block javascript %}
- {%- endraw %}{% if cookiecutter.custom_bootstrap_compilation == "y" and cookiecutter.js_task_runner == "Gulp" %}{% raw %}
+ {%- endraw %}{% if cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
-
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
+
{%- endraw %}{% else %}{% raw %}
@@ -43,9 +47,15 @@
{%- endraw %}{% endif %}{% raw %}
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
+ {%- endraw %}{% if cookiecutter.frontend_pipeline == 'None' %}{% raw %}
- {%- endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
+ {%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Django Compressor' %}{% raw %}
+ {% compress js %}
+
+ {% endcompress %}
+ {%- endraw %}{% elif cookiecutter.frontend_pipeline == 'Gulp' %}{% raw %}
+
+ {%- endraw %}{% endif %}{% raw %}
{% endblock javascript %}
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py
index 4c4d6954c..acd18512f 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py
@@ -1,4 +1,3 @@
-# Generated by Django 3.2.9 on 2021-11-20 11:23
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py
index edd306cb8..e30476227 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py
@@ -1,4 +1,5 @@
-from typing import Any, Sequence
+from collections.abc import Sequence
+from typing import Any
from django.contrib.auth import get_user_model
from factory import Faker, post_generation
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py
index c50a4be4c..a370784fc 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py
@@ -1,10 +1,7 @@
-import pytest
from django.urls import reverse
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
class TestUserAdmin:
def test_changelist(self, admin_client):
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py
index 83b623f45..7d9c444d3 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py
@@ -1,10 +1,7 @@
-import pytest
from django.urls import resolve, reverse
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
def test_user_detail(user: User):
assert (
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py
index 924573089..4d163bf08 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py
@@ -1,11 +1,8 @@
-import pytest
from django.test import RequestFactory
from {{ cookiecutter.project_slug }}.users.api.views import UserViewSet
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
class TestUserViewSet:
def test_get_queryset(self, user: User, rf: RequestFactory):
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py
index e51bb6bf2..261f88c8c 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py
@@ -1,14 +1,11 @@
"""
Module for all Form Tests.
"""
-import pytest
from django.utils.translation import gettext_lazy as _
from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
class TestUserAdminCreationForm:
"""
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py
index 3194be1fd..b09bcdf0b 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py
@@ -1,9 +1,5 @@
-import pytest
-
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
def test_user_get_absolute_url(user: User):
assert user.get_absolute_url() == f"/users/{user.username}/"
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py
similarity index 65%
rename from {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py
rename to {{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py
index b0c24d91b..f97658b55 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger_ui.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py
@@ -1,8 +1,6 @@
import pytest
from django.urls import reverse
-pytestmark = pytest.mark.django_db
-
def test_swagger_accessible_by_admin(admin_client):
url = reverse("api-docs")
@@ -10,7 +8,14 @@ def test_swagger_accessible_by_admin(admin_client):
assert response.status_code == 200
+@pytest.mark.django_db
def test_swagger_ui_not_accessible_by_normal_user(client):
url = reverse("api-docs")
response = client.get(url)
assert response.status_code == 403
+
+
+def test_api_schema_generated_successfully(admin_client):
+ url = reverse("api-schema")
+ response = admin_client.get(url)
+ assert response.status_code == 200
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py
index aab6d0a87..7cd056db5 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py
@@ -1,10 +1,7 @@
-import pytest
from django.urls import resolve, reverse
from {{ cookiecutter.project_slug }}.users.models import User
-pytestmark = pytest.mark.django_db
-
def test_detail(user: User):
assert (
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py
index 944daca52..d968d7ec9 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py
@@ -63,7 +63,8 @@ class TestUserUpdateView:
# Initialize the form
form = UserAdminChangeForm()
- form.cleaned_data = []
+ form.cleaned_data = {}
+ form.instance = user
view.form_valid(form)
messages_sent = [m.message for m in messages.get_messages(request)]
|