Merge branch 'cookiecutter:master' into main

This commit is contained in:
Jimmy Gitonga 2024-07-18 12:57:38 +03:00 committed by GitHub
commit 21e835d1de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
86 changed files with 1444 additions and 315 deletions

2
.github/FUNDING.yml vendored
View File

@ -1,5 +1,5 @@
# These are supported funding model platforms # These are supported funding model platforms
github: [pydanny, browniebroke] github: [pydanny, browniebroke, luzfcb]
patreon: feldroy patreon: feldroy
open_collective: cookiecutter-django open_collective: cookiecutter-django

View File

@ -1538,5 +1538,70 @@
"name": "Simeon Emanuilov", "name": "Simeon Emanuilov",
"github_login": "s-emanuilov", "github_login": "s-emanuilov",
"twitter_username": "s_emanuilov" "twitter_username": "s_emanuilov"
},
{
"name": "Patrick Zhang",
"github_login": "PatDuJour",
"twitter_username": ""
},
{
"name": "GvS",
"github_login": "GvS666",
"twitter_username": ""
},
{
"name": "David Păcioianu",
"github_login": "DavidPacioianu",
"twitter_username": ""
},
{
"name": "farwill",
"github_login": "farwill",
"twitter_username": ""
},
{
"name": "quroom",
"github_login": "quroom",
"twitter_username": ""
},
{
"name": "Marios Frixou",
"github_login": "frixou89",
"twitter_username": ""
},
{
"name": "Geo Maciolek",
"github_login": "GeoMaciolek",
"twitter_username": ""
},
{
"name": "Nadav Peretz",
"github_login": "nadavperetz",
"twitter_username": ""
},
{
"name": "Param Kapur",
"github_login": "paramkpr",
"twitter_username": "ParamKapur"
},
{
"name": "Jason Mok",
"github_login": "jasonmokk",
"twitter_username": ""
},
{
"name": "Manas Mallick",
"github_login": "ManDun",
"twitter_username": ""
},
{
"name": "Alexandr Artemyev",
"github_login": "Mogost",
"twitter_username": "MOGOST"
},
{
"name": "Ali Shamakhi",
"github_login": "ali-shamakhi",
"twitter_username": ""
} }
] ]

View File

@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
cache: pip cache: pip
- name: Install dependencies - name: Install dependencies
run: pip install -r requirements.txt run: pip install -r requirements.txt
@ -56,7 +56,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
cache: pip cache: pip
- name: Install dependencies - name: Install dependencies
run: pip install -r requirements.txt run: pip install -r requirements.txt
@ -100,7 +100,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
cache: pip cache: pip
cache-dependency-path: | cache-dependency-path: |
requirements.txt requirements.txt

View File

@ -19,7 +19,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip

View File

@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v5 - uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
- name: Install pre-commit - name: Install pre-commit
run: pip install pre-commit run: pip install pre-commit

View File

@ -8,7 +8,7 @@ on:
workflow_dispatch: workflow_dispatch:
jobs: jobs:
release: update:
# Disables this workflow from running in a repository that is not part of the indicated organization/user # Disables this workflow from running in a repository that is not part of the indicated organization/user
if: github.repository_owner == 'cookiecutter' if: github.repository_owner == 'cookiecutter'
@ -19,7 +19,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip

View File

@ -22,7 +22,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: "3.11" python-version: "3.12"
- name: Install dependencies - name: Install dependencies
run: | run: |
python -m pip install --upgrade pip python -m pip install --upgrade pip
@ -33,7 +33,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes - name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5.0.0 uses: stefanzweifel/git-auto-commit-action@v5.0.1
with: with:
commit_message: Update Contributors commit_message: Update Contributors
file_pattern: CONTRIBUTORS.md .github/contributors.json file_pattern: CONTRIBUTORS.md .github/contributors.json

View File

@ -2,11 +2,11 @@ exclude: "{{cookiecutter.project_slug}}|.github/contributors.json|CHANGELOG.md|C
default_stages: [commit] default_stages: [commit]
default_language_version: default_language_version:
python: python3.11 python: python3.12
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.6.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
@ -26,14 +26,14 @@ repos:
args: ["--tab-width", "2"] args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.15.1 rev: v3.16.0
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py311-plus] args: [--py312-plus]
exclude: hooks/ exclude: hooks/
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 24.2.0 rev: 24.4.2
hooks: hooks:
- id: black - id: black
@ -43,7 +43,7 @@ repos:
- id: isort - id: isort
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 7.0.0 rev: 7.1.0
hooks: hooks:
- id: flake8 - id: flake8

View File

@ -8,7 +8,7 @@ version: 2
build: build:
os: ubuntu-22.04 os: ubuntu-22.04
tools: tools:
python: "3.11" python: "3.12"
# Build documentation in the docs/ directory with Sphinx # Build documentation in the docs/ directory with Sphinx
sphinx: sphinx:

View File

@ -3,6 +3,805 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
<!-- GENERATOR_PLACEHOLDER --> <!-- GENERATOR_PLACEHOLDER -->
## 2024.07.17
### Updated
- Update sphinx to 7.4.5 ([#5222](https://github.com/cookiecutter/cookiecutter-django/pull/5222))
## 2024.07.16
### Fixed
- Clear `ENTRYPOINT` in `awscli` image to allow script execution ([#5221](https://github.com/cookiecutter/cookiecutter-django/pull/5221))
### Updated
- Update sphinx to 7.4.4 ([#5218](https://github.com/cookiecutter/cookiecutter-django/pull/5218))
## 2024.07.15
### Updated
- Update sentry-sdk to 2.10.0 ([#5216](https://github.com/cookiecutter/cookiecutter-django/pull/5216))
- Update sphinx to 7.4.2 ([#5215](https://github.com/cookiecutter/cookiecutter-django/pull/5215))
- Update ruff to 0.5.2 ([#5211](https://github.com/cookiecutter/cookiecutter-django/pull/5211))
- Update sphinx to 7.4.0 ([#5214](https://github.com/cookiecutter/cookiecutter-django/pull/5214))
## 2024.07.12
### Updated
- Update django-allauth to 0.63.6 ([#5210](https://github.com/cookiecutter/cookiecutter-django/pull/5210))
- Update django-allauth to 0.63.5 ([#5206](https://github.com/cookiecutter/cookiecutter-django/pull/5206))
- Update coverage to 7.6.0 ([#5207](https://github.com/cookiecutter/cookiecutter-django/pull/5207))
- Update django-anymail to 11.0.1 ([#5208](https://github.com/cookiecutter/cookiecutter-django/pull/5208))
## 2024.07.10
### Updated
- Update django-allauth to 0.63.4 ([#5204](https://github.com/cookiecutter/cookiecutter-django/pull/5204))
- Update django to 4.2.14 ([#5200](https://github.com/cookiecutter/cookiecutter-django/pull/5200))
- Update collectfasta to 3.2.0 ([#5201](https://github.com/cookiecutter/cookiecutter-django/pull/5201))
- Update sentry-sdk to 2.9.0 ([#5202](https://github.com/cookiecutter/cookiecutter-django/pull/5202))
- Update django-debug-toolbar to 4.4.6 ([#5203](https://github.com/cookiecutter/cookiecutter-django/pull/5203))
## 2024.07.09
### Changed
- Migrate from Collectfast to Collestfasta ([#5172](https://github.com/cookiecutter/cookiecutter-django/pull/5172))
### Documentation
- Fix a typo in the `--all` option of the `makemessages` command ([#5198](https://github.com/cookiecutter/cookiecutter-django/pull/5198))
### Updated
- Update django-storages to 1.14.4 ([#5197](https://github.com/cookiecutter/cookiecutter-django/pull/5197))
## 2024.07.08
### Updated
- Update ruff to 0.5.1 ([#5190](https://github.com/cookiecutter/cookiecutter-django/pull/5190))
- Update django-debug-toolbar to 4.4.5 ([#5192](https://github.com/cookiecutter/cookiecutter-django/pull/5192))
- Update sentry-sdk to 2.8.0 ([#5195](https://github.com/cookiecutter/cookiecutter-django/pull/5195))
## 2024.07.05
### Updated
- Update django-debug-toolbar to 4.4.3 ([#5189](https://github.com/cookiecutter/cookiecutter-django/pull/5189))
## 2024.07.02
### Updated
- Update pillow to 10.4.0 ([#5182](https://github.com/cookiecutter/cookiecutter-django/pull/5182))
## 2024.07.01
### Updated
- Update ruff to 0.5.0 ([#5181](https://github.com/cookiecutter/cookiecutter-django/pull/5181))
- Update sentry-sdk to 2.7.1 ([#5174](https://github.com/cookiecutter/cookiecutter-django/pull/5174))
- Auto-update pre-commit hooks ([#5175](https://github.com/cookiecutter/cookiecutter-django/pull/5175))
- Update psycopg to 3.2.1 ([#5180](https://github.com/cookiecutter/cookiecutter-django/pull/5180))
## 2024.06.30
### Updated
- Update django-upgrade to 1.19.0 ([#5171](https://github.com/cookiecutter/cookiecutter-django/pull/5171))
## 2024.06.26
### Fixed
- Fix keywords case warning in Dockerfile ([#5164](https://github.com/cookiecutter/cookiecutter-django/pull/5164))
### Updated
- Update redis to 5.0.7 ([#5170](https://github.com/cookiecutter/cookiecutter-django/pull/5170))
- Update sentry-sdk to 2.7.0 ([#5169](https://github.com/cookiecutter/cookiecutter-django/pull/5169))
## 2024.06.24
### Updated
- Update django-anymail to 11.0 ([#5163](https://github.com/cookiecutter/cookiecutter-django/pull/5163))
- Update coverage to 7.5.4 ([#5162](https://github.com/cookiecutter/cookiecutter-django/pull/5162))
## 2024.06.22
### Updated
- Bump amazon/aws-cli from 2.16.10 to 2.17.0 ([#5161](https://github.com/cookiecutter/cookiecutter-django/pull/5161))
- Auto-update pre-commit hooks ([#5160](https://github.com/cookiecutter/cookiecutter-django/pull/5160))
- Update ruff to 0.4.10 ([#5159](https://github.com/cookiecutter/cookiecutter-django/pull/5159))
## 2024.06.20
### Fixed
- Remove deprecated docker and python tags from GitLab CI config ([#5158](https://github.com/cookiecutter/cookiecutter-django/pull/5158))
## 2024.06.19
### Updated
- Update djangorestframework to 3.15.2 ([#5156](https://github.com/cookiecutter/cookiecutter-django/pull/5156))
- Update django-cors-headers to 4.4.0 ([#5154](https://github.com/cookiecutter/cookiecutter-django/pull/5154))
- Update sentry-sdk to 2.6.0 ([#5153](https://github.com/cookiecutter/cookiecutter-django/pull/5153))
- Update whitenoise to 6.7.0 ([#5155](https://github.com/cookiecutter/cookiecutter-django/pull/5155))
## 2024.06.18
### Updated
- Bump amazon/aws-cli from 2.16.8 to 2.16.10 ([#5149](https://github.com/cookiecutter/cookiecutter-django/pull/5149))
## 2024.06.17
### Updated
- Update django-compressor to 4.5 ([#5145](https://github.com/cookiecutter/cookiecutter-django/pull/5145))
- Update rcssmin to 1.1.2 ([#4614](https://github.com/cookiecutter/cookiecutter-django/pull/4614))
## 2024.06.15
### Changed
- Update start-flower in flower to wait until all celery workers are online ([#5012](https://github.com/cookiecutter/cookiecutter-django/pull/5012))
- Enhancing the security of cookies ([#5102](https://github.com/cookiecutter/cookiecutter-django/pull/5102))
### Updated
- Update django-crispy-forms to 2.2 ([#5143](https://github.com/cookiecutter/cookiecutter-django/pull/5143))
- Update sentry-sdk to 2.5.1 ([#5142](https://github.com/cookiecutter/cookiecutter-django/pull/5142))
- Auto-update pre-commit hooks ([#5140](https://github.com/cookiecutter/cookiecutter-django/pull/5140))
- Update django-allauth to 0.63.3 ([#5111](https://github.com/cookiecutter/cookiecutter-django/pull/5111))
## 2024.06.14
### Updated
- Bump python from 3.12.3-slim-bookworm to 3.12.4-slim-bookworm in /{{cookiecutter.project_slug}}/compose/local/docs ([#5129](https://github.com/cookiecutter/cookiecutter-django/pull/5129))
- Bump python from 3.12.3-slim-bookworm to 3.12.4-slim-bookworm in /{{cookiecutter.project_slug}}/compose/local/django ([#5130](https://github.com/cookiecutter/cookiecutter-django/pull/5130))
- Bump python from 3.12.3-slim-bookworm to 3.12.4-slim-bookworm in /{{cookiecutter.project_slug}}/compose/production/django ([#5132](https://github.com/cookiecutter/cookiecutter-django/pull/5132))
- Bump amazon/aws-cli from 2.16.6 to 2.16.8 in /{{cookiecutter.project_slug}}/compose/production/aws ([#5138](https://github.com/cookiecutter/cookiecutter-django/pull/5138))
- Update ruff to 0.4.9 ([#5139](https://github.com/cookiecutter/cookiecutter-django/pull/5139))
## 2024.06.13
### Updated
- Update redis to 5.0.6 ([#5137](https://github.com/cookiecutter/cookiecutter-django/pull/5137))
## 2024.06.12
### Updated
- Bump amazon/aws-cli Docker image from 2.15.58 to 2.16.6 ([#5135](https://github.com/cookiecutter/cookiecutter-django/pull/5135))
## 2024.06.08
### Changed
- Replace deprecated `uvicorn.workers` with `uvicorn-worker` ([#5110](https://github.com/cookiecutter/cookiecutter-django/pull/5110))
- Change aws-cli docker image to use official amazon image ([#5116](https://github.com/cookiecutter/cookiecutter-django/pull/5116))
## 2024.06.06
### Updated
- Update sentry-sdk to 2.5.0 ([#5126](https://github.com/cookiecutter/cookiecutter-django/pull/5126))
- Update ruff to 0.4.8 ([#5122](https://github.com/cookiecutter/cookiecutter-django/pull/5122))
- Update redis to 5.0.5 ([#5125](https://github.com/cookiecutter/cookiecutter-django/pull/5125))
## 2024.06.04
### Updated
- Update pytest to 8.2.2 ([#5120](https://github.com/cookiecutter/cookiecutter-django/pull/5120))
- Update sh to 2.0.7 ([#5114](https://github.com/cookiecutter/cookiecutter-django/pull/5114))
- Update sentry-sdk to 2.4.0 ([#5119](https://github.com/cookiecutter/cookiecutter-django/pull/5119))
## 2024.06.02
### Updated
- Update uvicorn to 0.30.1 ([#5115](https://github.com/cookiecutter/cookiecutter-django/pull/5115))
## 2024.06.01
### Updated
- Update ruff to 0.4.7 ([#5112](https://github.com/cookiecutter/cookiecutter-django/pull/5112))
## 2024.05.30
### Updated
- Update uvicorn to 0.30.0 ([#5101](https://github.com/cookiecutter/cookiecutter-django/pull/5101))
## 2024.05.29
### Updated
- Update requests to 2.32.3 ([#5108](https://github.com/cookiecutter/cookiecutter-django/pull/5108))
- Update ruff to 0.4.6 ([#5107](https://github.com/cookiecutter/cookiecutter-django/pull/5107))
- Auto-update pre-commit hooks ([#5106](https://github.com/cookiecutter/cookiecutter-django/pull/5106))
- Update coverage to 7.5.3 ([#5104](https://github.com/cookiecutter/cookiecutter-django/pull/5104))
- Update django-upgrade to 1.18.0 ([#5105](https://github.com/cookiecutter/cookiecutter-django/pull/5105))
## 2024.05.27
### Changed
- Rename SendInBlue ESP to Brevo ([#5094](https://github.com/cookiecutter/cookiecutter-django/pull/5094))
### Updated
- Update django-stubs to 5.0.2 ([#5100](https://github.com/cookiecutter/cookiecutter-django/pull/5100))
- Update watchfiles to 0.22.0 ([#5099](https://github.com/cookiecutter/cookiecutter-django/pull/5099))
- Update django-allauth to 0.63.2 ([#5092](https://github.com/cookiecutter/cookiecutter-django/pull/5092))
- Update coverage to 7.5.2 ([#5095](https://github.com/cookiecutter/cookiecutter-django/pull/5095))
- Update django-debug-toolbar to 4.4.2 ([#5098](https://github.com/cookiecutter/cookiecutter-django/pull/5098))
## 2024.05.23
### Updated
- Update sentry-sdk to 2.3.1 ([#5091](https://github.com/cookiecutter/cookiecutter-django/pull/5091))
- Auto-update pre-commit hooks ([#5087](https://github.com/cookiecutter/cookiecutter-django/pull/5087))
- Update ruff to 0.4.5 ([#5086](https://github.com/cookiecutter/cookiecutter-django/pull/5086))
## 2024.05.21
### Updated
- Update sentry-sdk to 2.2.1 ([#5083](https://github.com/cookiecutter/cookiecutter-django/pull/5083))
## 2024.05.20
### Fixed
- Fix PyCharm Run Configurations After local.yml Rename ([#5080](https://github.com/cookiecutter/cookiecutter-django/pull/5080))
### Updated
- Update pytest to 8.2.1 ([#5079](https://github.com/cookiecutter/cookiecutter-django/pull/5079))
## 2024.05.18
### Fixed
- Fix redirect error when forcing allauth login in admin site ([#5078](https://github.com/cookiecutter/cookiecutter-django/pull/5078))
## 2024.05.17
### Updated
- Update django-allauth to 0.63.1 ([#5076](https://github.com/cookiecutter/cookiecutter-django/pull/5076))
## 2024.05.16
### Documentation
- Update Two scoops of Django book link &amp; image ([#5073](https://github.com/cookiecutter/cookiecutter-django/pull/5073))
### Updated
- Update sentry-sdk to 2.2.0 ([#5074](https://github.com/cookiecutter/cookiecutter-django/pull/5074))
- Update django-allauth to 0.63.0 ([#5070](https://github.com/cookiecutter/cookiecutter-django/pull/5070))
## 2024.05.15
### Fixed
- Disable DDT profiling panel ([#5069](https://github.com/cookiecutter/cookiecutter-django/pull/5069))
## 2024.05.13
### Changed
- Rename docker compose files to include &#39;docker-compose&#39; ([#4995](https://github.com/cookiecutter/cookiecutter-django/pull/4995))
- Remove obsolete `version` element from docker compose files ([#5059](https://github.com/cookiecutter/cookiecutter-django/pull/5059))
- Add Redis persistent storage when using celery ([#5063](https://github.com/cookiecutter/cookiecutter-django/pull/5063))
### Fixed
- Add noqa to ignore ruff false positive ([#5068](https://github.com/cookiecutter/cookiecutter-django/pull/5068))
- Fix staticfile settings with cloud provider and whitenoise ([#5057](https://github.com/cookiecutter/cookiecutter-django/pull/5057))
### Updated
- Update djangorestframework-stubs to 3.15.0 ([#5041](https://github.com/cookiecutter/cookiecutter-django/pull/5041))
- Update django-stubs to 5.0.0 ([#5040](https://github.com/cookiecutter/cookiecutter-django/pull/5040))
- Update mypy to 1.10.0 ([#5022](https://github.com/cookiecutter/cookiecutter-django/pull/5022))
- Update werkzeug to 3.0.3 ([#5050](https://github.com/cookiecutter/cookiecutter-django/pull/5050))
## 2024.05.11
### Updated
- Update pre-commit to 3.7.1 ([#5066](https://github.com/cookiecutter/cookiecutter-django/pull/5066))
- Auto-update pre-commit hooks ([#5067](https://github.com/cookiecutter/cookiecutter-django/pull/5067))
## 2024.05.10
### Updated
- Update psycopg to 3.1.19 ([#5064](https://github.com/cookiecutter/cookiecutter-django/pull/5064))
- Update django-upgrade to 1.17.0 ([#5065](https://github.com/cookiecutter/cookiecutter-django/pull/5065))
- Auto-update pre-commit hooks ([#5062](https://github.com/cookiecutter/cookiecutter-django/pull/5062))
- Update ruff to 0.4.4 ([#5061](https://github.com/cookiecutter/cookiecutter-django/pull/5061))
## 2024.05.07
### Updated
- Update django to 4.2.13 ([#5058](https://github.com/cookiecutter/cookiecutter-django/pull/5058))
## 2024.05.06
### Fixed
- Fix nginx image name in production.yml ([#5053](https://github.com/cookiecutter/cookiecutter-django/pull/5053))
### Updated
- Update django-model-utils to 4.5.1 ([#5044](https://github.com/cookiecutter/cookiecutter-django/pull/5044))
- Update django to 4.2.12 ([#5056](https://github.com/cookiecutter/cookiecutter-django/pull/5056))
- Update sentry-sdk to 2.1.1 ([#5055](https://github.com/cookiecutter/cookiecutter-django/pull/5055))
- Update ruff to 0.4.3 ([#5049](https://github.com/cookiecutter/cookiecutter-django/pull/5049))
## 2024.05.05
### Updated
- Auto-update pre-commit hooks ([#5046](https://github.com/cookiecutter/cookiecutter-django/pull/5046))
- Update django-storages to 1.14.3 ([#5047](https://github.com/cookiecutter/cookiecutter-django/pull/5047))
- Update coverage to 7.5.1 ([#5048](https://github.com/cookiecutter/cookiecutter-django/pull/5048))
## 2024.04.28
### Updated
- Update pytest to 8.2.0 ([#5034](https://github.com/cookiecutter/cookiecutter-django/pull/5034))
## 2024.04.27
### Updated
- Update sentry-sdk to 2.0.1 ([#5030](https://github.com/cookiecutter/cookiecutter-django/pull/5030))
## 2024.04.26
### Updated
- Auto-update pre-commit hooks ([#5029](https://github.com/cookiecutter/cookiecutter-django/pull/5029))
- Update ruff to 0.4.2 ([#5028](https://github.com/cookiecutter/cookiecutter-django/pull/5028))
## 2024.04.25
### Updated
- Update coverage to 7.5.0 ([#5025](https://github.com/cookiecutter/cookiecutter-django/pull/5025))
- Bump cssnano from 6.1.2 to 7.0.0 ([#5024](https://github.com/cookiecutter/cookiecutter-django/pull/5024))
- Auto-update pre-commit hooks ([#5023](https://github.com/cookiecutter/cookiecutter-django/pull/5023))
## 2024.04.24
### Changed
- Disable UP038 Ruff rule to avoid introducing slower code ([#5020](https://github.com/cookiecutter/cookiecutter-django/pull/5020))
### Updated
- Update django-allauth to 0.62.1 ([#5021](https://github.com/cookiecutter/cookiecutter-django/pull/5021))
## 2024.04.23
### Changed
- Update link to djlint on pyproject.toml ([#5019](https://github.com/cookiecutter/cookiecutter-django/pull/5019))
### Updated
- Update redis to 5.0.4 ([#5018](https://github.com/cookiecutter/cookiecutter-django/pull/5018))
- Update django-allauth to 0.62.0 ([#5016](https://github.com/cookiecutter/cookiecutter-django/pull/5016))
## 2024.04.22
### Fixed
- Fix broken link for sphinx-doc in generated docs ([#5015](https://github.com/cookiecutter/cookiecutter-django/pull/5015))
## 2024.04.20
### Updated
- Auto-update pre-commit hooks ([#5014](https://github.com/cookiecutter/cookiecutter-django/pull/5014))
- Update pytest-xdist to 3.6.0 ([#5013](https://github.com/cookiecutter/cookiecutter-django/pull/5013))
## 2024.04.19
### Updated
- Update ruff to 0.4.1 ([#5011](https://github.com/cookiecutter/cookiecutter-django/pull/5011))
- Update ruff to 0.4.0 ([#5007](https://github.com/cookiecutter/cookiecutter-django/pull/5007))
- Auto-update pre-commit hooks ([#5008](https://github.com/cookiecutter/cookiecutter-django/pull/5008))
- Update sphinx to 7.3.7 ([#5010](https://github.com/cookiecutter/cookiecutter-django/pull/5010))
## 2024.04.18
### Updated
- Update celery to 5.4.0 ([#5005](https://github.com/cookiecutter/cookiecutter-django/pull/5005))
- Update sphinx to 7.3.6 ([#5004](https://github.com/cookiecutter/cookiecutter-django/pull/5004))
## 2024.04.17
### Updated
- Update sphinx to 7.3.5 ([#5003](https://github.com/cookiecutter/cookiecutter-django/pull/5003))
- Update gunicorn to 22.0.0 ([#5001](https://github.com/cookiecutter/cookiecutter-django/pull/5001))
- Update sphinx to 7.3.3 ([#5000](https://github.com/cookiecutter/cookiecutter-django/pull/5000))
## 2024.04.16
### Changed
- Add a prefix setting so that swagger tags are generated in a readable way ([#4975](https://github.com/cookiecutter/cookiecutter-django/pull/4975))
### Fixed
- Fix `runserver_plus` hot-reload when under Windows + Docker ([#4971](https://github.com/cookiecutter/cookiecutter-django/pull/4971))
### Documentation
- Update docs for `test_bare.sh` ([#4996](https://github.com/cookiecutter/cookiecutter-django/pull/4996))
### Updated
- Bump traefik from 2.11.0 to 2.11.2 ([#4993](https://github.com/cookiecutter/cookiecutter-django/pull/4993))
- Update sphinx-autobuild to 2024.4.16 ([#4999](https://github.com/cookiecutter/cookiecutter-django/pull/4999))
- Update sphinx-autobuild to 2024.4.13 ([#4991](https://github.com/cookiecutter/cookiecutter-django/pull/4991))
- Update sentry-sdk to 1.45.0 ([#4982](https://github.com/cookiecutter/cookiecutter-django/pull/4982))
- Update ruff to 0.3.7 ([#4989](https://github.com/cookiecutter/cookiecutter-django/pull/4989))
- Auto-update pre-commit hooks ([#4988](https://github.com/cookiecutter/cookiecutter-django/pull/4988))
## 2024.04.10
### Updated
- Bump python from 3.12.2 to 3.12.3 in docs ([#4979](https://github.com/cookiecutter/cookiecutter-django/pull/4979))
- Bump python from 3.12.2 to 3.12.3 in local ([#4981](https://github.com/cookiecutter/cookiecutter-django/pull/4981))
- Bump python from 3.12.2 to 3.12.3 in production ([#4980](https://github.com/cookiecutter/cookiecutter-django/pull/4980))
## 2024.04.09
### Documentation
- Fix start command for docs ([#4978](https://github.com/cookiecutter/cookiecutter-django/pull/4978))
## 2024.04.07
### Updated
- Auto-update pre-commit hooks ([#4974](https://github.com/cookiecutter/cookiecutter-django/pull/4974))
## 2024.04.06
### Fixed
- Fix syntax error in GitHub CI workflow ([#4972](https://github.com/cookiecutter/cookiecutter-django/pull/4972))
## 2024.04.05
### Updated
- Update django-webpack-loader to 3.1.0 ([#4965](https://github.com/cookiecutter/cookiecutter-django/pull/4965))
## 2024.04.03
### Changed
- Update GH actions to resolve deprecation warnings ([#4964](https://github.com/cookiecutter/cookiecutter-django/pull/4964))
### Updated
- Update sentry-sdk to 1.44.1 ([#4963](https://github.com/cookiecutter/cookiecutter-django/pull/4963))
## 2024.04.02
### Changed
- Change pytest import mode to importlib ([#4950](https://github.com/cookiecutter/cookiecutter-django/pull/4950))
- Use main over master for branch name in deployment-on-heroku instruction ([#4954](https://github.com/cookiecutter/cookiecutter-django/pull/4954))
- change obsolete docker image &#34;docker/compose:1.29.2&#34; to &#34;docker:25.0&#34; ([#4961](https://github.com/cookiecutter/cookiecutter-django/pull/4961))
### Updated
- Update sentry-sdk to 1.44.0 ([#4948](https://github.com/cookiecutter/cookiecutter-django/pull/4948))
- Update ruff to 0.3.5 ([#4955](https://github.com/cookiecutter/cookiecutter-django/pull/4955))
- Update gitpython to 3.1.43 ([#4951](https://github.com/cookiecutter/cookiecutter-django/pull/4951))
- Update pillow to 10.3.0 ([#4953](https://github.com/cookiecutter/cookiecutter-django/pull/4953))
- Update django-model-utils to 4.5.0 ([#4956](https://github.com/cookiecutter/cookiecutter-django/pull/4956))
- Update drf-spectacular to 0.27.2 ([#4957](https://github.com/cookiecutter/cookiecutter-django/pull/4957))
- Update werkzeug to 3.0.2 ([#4958](https://github.com/cookiecutter/cookiecutter-django/pull/4958))
- Auto-update pre-commit hooks ([#4959](https://github.com/cookiecutter/cookiecutter-django/pull/4959))
## 2024.03.29
### Documentation
- Add instruction for adding a django app ([#4944](https://github.com/cookiecutter/cookiecutter-django/pull/4944))
## 2024.03.27
### Updated
- Update pre-commit to 3.7.0 ([#4943](https://github.com/cookiecutter/cookiecutter-django/pull/4943))
- Update djangorestframework to 3.15.1 ([#4941](https://github.com/cookiecutter/cookiecutter-django/pull/4941))
- Update ruff to 0.3.4 ([#4936](https://github.com/cookiecutter/cookiecutter-django/pull/4936))
- Auto-update pre-commit hooks ([#4937](https://github.com/cookiecutter/cookiecutter-django/pull/4937))
## 2024.03.26
### Documentation
- Update mentions of psycopg in comments ([#4947](https://github.com/cookiecutter/cookiecutter-django/pull/4947))
## 2024.03.21
### Changed
- Add PostgreSQL 16, remove Postgres 10 and 11 ([#4935](https://github.com/cookiecutter/cookiecutter-django/pull/4935))
### Updated
- Update uvicorn to 0.29.0 ([#4933](https://github.com/cookiecutter/cookiecutter-django/pull/4933))
- Update sentry-sdk to 1.43.0 ([#4934](https://github.com/cookiecutter/cookiecutter-django/pull/4934))
## 2024.03.19
### Changed
- Add documentation to upgrade Postgres in Docker environment. Fix: #461 ([#4898](https://github.com/cookiecutter/cookiecutter-django/pull/4898))
- Upgrade Python to version 3.12 ([#4930](https://github.com/cookiecutter/cookiecutter-django/pull/4930))
## 2024.03.18
### Changed
- Split the docs from local.yml and build the service in CI ([#4909](https://github.com/cookiecutter/cookiecutter-django/pull/4909))
### Updated
- Update django-anymail to 10.3 ([#4919](https://github.com/cookiecutter/cookiecutter-django/pull/4919))
- Update sentry-sdk to 1.42.0 ([#4921](https://github.com/cookiecutter/cookiecutter-django/pull/4921))
- Update coverage to 7.4.4 ([#4926](https://github.com/cookiecutter/cookiecutter-django/pull/4926))
- Update ruff to 0.3.3 ([#4927](https://github.com/cookiecutter/cookiecutter-django/pull/4927))
- Auto-update pre-commit hooks ([#4928](https://github.com/cookiecutter/cookiecutter-django/pull/4928))
## 2024.03.17
### Updated
- Update djangorestframework to 3.15.0 ([#4929](https://github.com/cookiecutter/cookiecutter-django/pull/4929))
## 2024.03.10
### Updated
- Auto-update pre-commit hooks ([#4912](https://github.com/cookiecutter/cookiecutter-django/pull/4912))
- Update ruff to 0.3.2 ([#4911](https://github.com/cookiecutter/cookiecutter-django/pull/4911))
- Update uvicorn to 0.28.0 ([#4913](https://github.com/cookiecutter/cookiecutter-django/pull/4913))
- Update redis to 5.0.3 ([#4916](https://github.com/cookiecutter/cookiecutter-django/pull/4916))
- Update pytest to 8.1.1 ([#4914](https://github.com/cookiecutter/cookiecutter-django/pull/4914))
## 2024.03.07
### Updated
- Auto-update pre-commit hooks ([#4907](https://github.com/cookiecutter/cookiecutter-django/pull/4907))
- Update sentry-sdk to 1.41.0 ([#4908](https://github.com/cookiecutter/cookiecutter-django/pull/4908))
## 2024.03.06
### Fixed
- Fix fully qualified docker images ([#4905](https://github.com/cookiecutter/cookiecutter-django/pull/4905))
## 2024.03.04
### Updated
- Update pytest to 8.1.0 ([#4900](https://github.com/cookiecutter/cookiecutter-django/pull/4900))
- Update django to 4.2.11 ([#4901](https://github.com/cookiecutter/cookiecutter-django/pull/4901))
## 2024.03.03 ## 2024.03.03

View File

@ -18,20 +18,20 @@ This last step is very important, don't start developing from master, it'll caus
## Testing ## Testing
You'll need to run the tests using Python 3.11. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/). You'll need to run the tests using Python 3.12. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/).
We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it. We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it.
### Installation ### Installation
First, make sure that your version of Python is 3.11: First, make sure that your version of Python is 3.12:
```bash ```bash
$ python --version $ python --version
Python 3.11.3 Python 3.12.2
``` ```
Any version that starts with 3.11 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/). Any version that starts with 3.12 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/).
Then install `tox`, if not already installed: Then install `tox`, if not already installed:
@ -66,13 +66,13 @@ $ source venv/bin/activate
These tests are slower and can be run with or without Docker: These tests are slower and can be run with or without Docker:
- Without Docker: `scripts/test_bare.sh` (for bare metal) - Without Docker: `tests/test_bare.sh` (for bare metal)
- With Docker: `scripts/test_docker.sh` - With Docker: `tests/test_docker.sh`
All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example: All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example:
```bash ```bash
$ scripts/test_bare.sh use_celery=y $ tests/test_bare.sh use_celery=y
``` ```
## Submitting a pull request ## Submitting a pull request

View File

@ -215,6 +215,20 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Alexandr Artemyev</td>
<td>
<a href="https://github.com/Mogost">Mogost</a>
</td>
<td>MOGOST</td>
</tr>
<tr>
<td>Ali Shamakhi</td>
<td>
<a href="https://github.com/ali-shamakhi">ali-shamakhi</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Alvaro [Andor]</td> <td>Alvaro [Andor]</td>
<td> <td>
@ -656,6 +670,13 @@ Listed in alphabetical order.
</td> </td>
<td>DavidDiazPinto</td> <td>DavidDiazPinto</td>
</tr> </tr>
<tr>
<td>David Păcioianu</td>
<td>
<a href="https://github.com/DavidPacioianu">DavidPacioianu</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Davit Tovmasyan</td> <td>Davit Tovmasyan</td>
<td> <td>
@ -810,6 +831,13 @@ Listed in alphabetical order.
</td> </td>
<td>fabaff</td> <td>fabaff</td>
</tr> </tr>
<tr>
<td>farwill</td>
<td>
<a href="https://github.com/farwill">farwill</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Fateme Fouladkar</td> <td>Fateme Fouladkar</td>
<td> <td>
@ -873,6 +901,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Geo Maciolek</td>
<td>
<a href="https://github.com/GeoMaciolek">GeoMaciolek</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>ghazi-git</td> <td>ghazi-git</td>
<td> <td>
@ -915,6 +950,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>GvS</td>
<td>
<a href="https://github.com/GvS666">GvS666</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Hamish Durkin</td> <td>Hamish Durkin</td>
<td> <td>
@ -1090,6 +1132,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Jason Mok</td>
<td>
<a href="https://github.com/jasonmokk">jasonmokk</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Jens Kaeske</td> <td>Jens Kaeske</td>
<td> <td>
@ -1370,6 +1419,13 @@ Listed in alphabetical order.
</td> </td>
<td>flyudvik</td> <td>flyudvik</td>
</tr> </tr>
<tr>
<td>Manas Mallick</td>
<td>
<a href="https://github.com/ManDun">ManDun</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Manjit Pardeshi</td> <td>Manjit Pardeshi</td>
<td> <td>
@ -1384,6 +1440,13 @@ Listed in alphabetical order.
</td> </td>
<td>marciomazza</td> <td>marciomazza</td>
</tr> </tr>
<tr>
<td>Marios Frixou</td>
<td>
<a href="https://github.com/frixou89">frixou89</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Martin Blech</td> <td>Martin Blech</td>
<td> <td>
@ -1587,6 +1650,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Nadav Peretz</td>
<td>
<a href="https://github.com/nadavperetz">nadavperetz</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Naveen</td> <td>Naveen</td>
<td> <td>
@ -1650,6 +1720,13 @@ Listed in alphabetical order.
</td> </td>
<td>pamelafox</td> <td>pamelafox</td>
</tr> </tr>
<tr>
<td>Param Kapur</td>
<td>
<a href="https://github.com/paramkpr">paramkpr</a>
</td>
<td>ParamKapur</td>
</tr>
<tr> <tr>
<td>Parbhat Puri</td> <td>Parbhat Puri</td>
<td> <td>
@ -1664,6 +1741,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Patrick Zhang</td>
<td>
<a href="https://github.com/PatDuJour">PatDuJour</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Paul Wulff</td> <td>Paul Wulff</td>
<td> <td>
@ -1727,6 +1811,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>quroom</td>
<td>
<a href="https://github.com/quroom">quroom</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Raony Guimarães Corrêa</td> <td>Raony Guimarães Corrêa</td>
<td> <td>

View File

@ -6,7 +6,7 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![Updates](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/shield.svg)](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/) [![Updates](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/shield.svg)](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/)
[![Join our Discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/uFXweDQc5a) [![Join our Discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/rAWFUP47d2)
[![Code Helpers Badge](https://www.codetriage.com/cookiecutter/cookiecutter-django/badges/users.svg)](https://www.codetriage.com/cookiecutter/cookiecutter-django) [![Code Helpers Badge](https://www.codetriage.com/cookiecutter/cookiecutter-django/badges/users.svg)](https://www.codetriage.com/cookiecutter/cookiecutter-django)
Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting
@ -20,7 +20,7 @@ production-ready Django projects quickly.
## Features ## Features
- For Django 4.2 - For Django 4.2
- Works with Python 3.11 - Works with Python 3.12
- Renders Django projects with 100% starting test coverage - Renders Django projects with 100% starting test coverage
- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5 - Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5
- [12-Factor](https://12factor.net) based settings via [django-environ](https://github.com/joke2k/django-environ) - [12-Factor](https://12factor.net) based settings via [django-environ](https://github.com/joke2k/django-environ)
@ -51,7 +51,7 @@ _These features can be enabled during initial project setup._
## Constraints ## Constraints
- Only maintained 3rd party libraries are used. - Only maintained 3rd party libraries are used.
- Uses PostgreSQL everywhere: 10 - 15 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available). - Uses PostgreSQL everywhere: 12 - 16 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available).
- Environment variables for configuration (This won't work with Apache/mod_wsgi). - Environment variables for configuration (This won't work with Apache/mod_wsgi).
## Support this Project! ## Support this Project!
@ -65,19 +65,15 @@ This project is an open source project run by volunteers. You can sponsor us via
Projects that provide financial support to the maintainers: Projects that provide financial support to the maintainers:
--- ### Two Scoops of Django
<p align="center"> [![Cover of the book "Two Scoops of Django 3.x"](https://www.feldroy.com/static/book-TSD3-800.jpg)](https://www.feldroy.com/two-scoops-press#two-scoops-of-django)
<a href="https://www.feldroy.com/products//two-scoops-of-django-3-x"><img src="https://cdn.shopify.com/s/files/1/0304/6901/products/Two-Scoops-of-Django-3-Alpha-Cover_540x_26507b15-e489-470b-8a97-02773dd498d1_1080x.jpg"></a>
</p>
Two Scoops of Django 3.x is the best ice cream-themed Django reference in the universe! Two Scoops of Django 3.x is the best ice cream-themed Django reference in the universe!
### PyUp ### PyUp
<p align="center"> [![PyUp Logo](https://pyup.io/static/images/logo.png)](https://pyup.io)
<a href="https://pyup.io/"><img src="https://pyup.io/static/images/logo.png"></a>
</p>
PyUp brings you automated security and dependency updates used by Google and other organizations. Free for open source projects! PyUp brings you automated security and dependency updates used by Google and other organizations. Free for open source projects!
@ -133,12 +129,11 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
Choose from 1, 2, 3 [1]: 1 Choose from 1, 2, 3 [1]: 1
use_docker [n]: n use_docker [n]: n
Select postgresql_version: Select postgresql_version:
1 - 15 1 - 16
2 - 14 2 - 15
3 - 13 3 - 14
4 - 12 4 - 13
5 - 11 5 - 12
6 - 10
Choose from 1, 2, 3, 4, 5 [1]: 1 Choose from 1, 2, 3, 4, 5 [1]: 1
Select cloud_provider: Select cloud_provider:
1 - AWS 1 - AWS
@ -152,7 +147,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
4 - Mandrill 4 - Mandrill
5 - Postmark 5 - Postmark
6 - Sendgrid 6 - Sendgrid
7 - SendinBlue 7 - Brevo (formerly SendinBlue)
8 - SparkPost 8 - SparkPost
9 - Other SMTP 9 - Other SMTP
Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 1 Choose from 1, 2, 3, 4, 5, 6, 7, 8, 9 [1]: 1

View File

@ -18,7 +18,7 @@
"windows": "n", "windows": "n",
"editor": ["None", "PyCharm", "VS Code"], "editor": ["None", "PyCharm", "VS Code"],
"use_docker": "n", "use_docker": "n",
"postgresql_version": ["15", "14", "13", "12", "11", "10"], "postgresql_version": ["16", "15", "14", "13", "12"],
"cloud_provider": ["AWS", "GCP", "Azure", "None"], "cloud_provider": ["AWS", "GCP", "Azure", "None"],
"mail_service": [ "mail_service": [
"Mailgun", "Mailgun",
@ -27,7 +27,7 @@
"Mandrill", "Mandrill",
"Postmark", "Postmark",
"Sendgrid", "Sendgrid",
"SendinBlue", "Brevo",
"SparkPost", "SparkPost",
"Other SMTP" "Other SMTP"
], ],

View File

@ -46,7 +46,7 @@ Run these commands to deploy the project to Heroku:
# Assign with AWS_STORAGE_BUCKET_NAME # Assign with AWS_STORAGE_BUCKET_NAME
heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME= heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME=
git push heroku master git push heroku main
heroku run python manage.py createsuperuser heroku run python manage.py createsuperuser

View File

@ -37,7 +37,7 @@ Make sure your project is fully committed and pushed up to Bitbucket or Github o
mkvirtualenv --python=/usr/bin/python3.10 my-project-name mkvirtualenv --python=/usr/bin/python3.10 my-project-name
pip install -r requirements/production.txt # may take a few minutes pip install -r requirements/production.txt # may take a few minutes
.. note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.11. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.11 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section. .. note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.12. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.12 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section.
Setting environment variables in the console Setting environment variables in the console
-------------------------------------------- --------------------------------------------

View File

@ -14,7 +14,7 @@ Prerequisites
Understanding the Docker Compose Setup Understanding the Docker Compose Setup
-------------------------------------- --------------------------------------
Before you begin, check out the ``production.yml`` file in the root of this project. Keep note of how it provides configuration for the following services: Before you begin, check out the ``docker-compose.production.yml`` file in the root of this project. Keep note of how it provides configuration for the following services:
* ``django``: your application running behind ``Gunicorn``; * ``django``: your application running behind ``Gunicorn``;
* ``postgres``: PostgreSQL database with the application's relational data; * ``postgres``: PostgreSQL database with the application's relational data;
@ -107,7 +107,7 @@ To solve this, you can either:
2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them). 2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them).
3. set these variables when running the build command:: 3. set these variables when running the build command::
DJANGO_AWS_S3_CUSTOM_DOMAIN=example.com docker compose -f production.yml build``. DJANGO_AWS_S3_CUSTOM_DOMAIN=example.com docker compose -f docker-compose.production.yml build``.
None of these options are ideal, we're open to suggestions on how to improve this. If you think you have one, please open an issue or a pull request. None of these options are ideal, we're open to suggestions on how to improve this. If you think you have one, please open an issue or a pull request.
@ -122,42 +122,42 @@ Building & Running Production Stack
You will need to build the stack first. To do that, run:: You will need to build the stack first. To do that, run::
docker compose -f production.yml build docker compose -f docker-compose.production.yml build
Once this is ready, you can run it with:: Once this is ready, you can run it with::
docker compose -f production.yml up docker compose -f docker-compose.production.yml up
To run the stack and detach the containers, run:: To run the stack and detach the containers, run::
docker compose -f production.yml up -d docker compose -f docker-compose.production.yml up -d
To run a migration, open up a second terminal and run:: To run a migration, open up a second terminal and run::
docker compose -f production.yml run --rm django python manage.py migrate docker compose -f docker-compose.production.yml run --rm django python manage.py migrate
To create a superuser, run:: To create a superuser, run::
docker compose -f production.yml run --rm django python manage.py createsuperuser docker compose -f docker-compose.production.yml run --rm django python manage.py createsuperuser
If you need a shell, run:: If you need a shell, run::
docker compose -f production.yml run --rm django python manage.py shell docker compose -f docker-compose.production.yml run --rm django python manage.py shell
To check the logs out, run:: To check the logs out, run::
docker compose -f production.yml logs docker compose -f docker-compose.production.yml logs
If you want to scale your application, run:: If you want to scale your application, run::
docker compose -f production.yml up --scale django=4 docker compose -f docker-compose.production.yml up --scale django=4
docker compose -f production.yml up --scale celeryworker=2 docker compose -f docker-compose.production.yml up --scale celeryworker=2
.. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``traefik``. .. warning:: don't try to scale ``postgres``, ``celerybeat``, or ``traefik``.
To see how your containers are doing run:: To see how your containers are doing run::
docker compose -f production.yml ps docker compose -f docker-compose.production.yml ps
Example: Supervisor Example: Supervisor
@ -165,12 +165,12 @@ Example: Supervisor
Once you are ready with your initial setup, you want to make sure that your application is run by a process manager to Once you are ready with your initial setup, you want to make sure that your application is run by a process manager to
survive reboots and auto restarts in case of an error. You can use the process manager you are most familiar with. All survive reboots and auto restarts in case of an error. You can use the process manager you are most familiar with. All
it needs to do is to run ``docker compose -f production.yml up`` in your projects root directory. it needs to do is to run ``docker compose -f docker-compose.production.yml up`` in your projects root directory.
If you are using ``supervisor``, you can use this file as a starting point:: If you are using ``supervisor``, you can use this file as a starting point::
[program:{{cookiecutter.project_slug}}] [program:{{cookiecutter.project_slug}}]
command=docker compose -f production.yml up command=docker compose -f docker-compose.production.yml up
directory=/path/to/{{cookiecutter.project_slug}} directory=/path/to/{{cookiecutter.project_slug}}
redirect_stderr=true redirect_stderr=true
autostart=true autostart=true

View File

@ -32,9 +32,9 @@ Build the Stack
This can take a while, especially the first time you run this particular command on your development system:: This can take a while, especially the first time you run this particular command on your development system::
$ docker compose -f local.yml build $ docker compose -f docker-compose.local.yml build
Generally, if you want to emulate production environment use ``production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it! Generally, if you want to emulate production environment use ``docker-compose.production.yml`` instead. And this is true for any other actions you might need to perform: whenever a switch is required, just do it!
Before doing any git commit, `pre-commit`_ should be installed globally on your local machine, and then:: Before doing any git commit, `pre-commit`_ should be installed globally on your local machine, and then::
@ -51,11 +51,11 @@ This brings up both Django and PostgreSQL. The first time it is run it might tak
Open a terminal at the project root and run the following for local development:: Open a terminal at the project root and run the following for local development::
$ docker compose -f local.yml up $ docker compose -f docker-compose.local.yml up
You can also set the environment variable ``COMPOSE_FILE`` pointing to ``local.yml`` like this:: You can also set the environment variable ``COMPOSE_FILE`` pointing to ``docker-compose.local.yml`` like this::
$ export COMPOSE_FILE=local.yml $ export COMPOSE_FILE=docker-compose.local.yml
And then run:: And then run::
@ -65,16 +65,23 @@ To run in a detached (background) mode, just::
$ docker compose up -d $ docker compose up -d
These commands don't run the docs service. In order to run docs service you can run::
$ docker compose -f docker-compose.docs.yml up
To run the docs with local services just use::
$ docker compose -f docker-compose.local.yml -f docker-compose.docs.yml up
The site should start and be accessible at http://localhost:3000 if you selected Webpack or Gulp as frontend pipeline and http://localhost:8000 otherwise. The site should start and be accessible at http://localhost:3000 if you selected Webpack or Gulp as frontend pipeline and http://localhost:8000 otherwise.
Execute Management Commands Execute Management Commands
--------------------------- ---------------------------
As with any shell command that we wish to run in our container, this is done using the ``docker compose -f local.yml run --rm`` command: :: As with any shell command that we wish to run in our container, this is done using the ``docker compose -f docker-compose.local.yml run --rm`` command: ::
$ docker compose -f local.yml run --rm django python manage.py migrate $ docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
$ docker compose -f local.yml run --rm django python manage.py createsuperuser $ docker compose -f docker-compose.local.yml run --rm django python manage.py createsuperuser
Here, ``django`` is the target service we are executing the commands against. Here, ``django`` is the target service we are executing the commands against.
Also, please note that the ``docker exec`` does not work for running management commands. Also, please note that the ``docker exec`` does not work for running management commands.
@ -90,7 +97,7 @@ When ``DEBUG`` is set to ``True``, the host is validated against ``['localhost',
Configuring the Environment Configuring the Environment
--------------------------- ---------------------------
This is the excerpt from your project's ``local.yml``: :: This is the excerpt from your project's ``docker-compose.local.yml``: ::
# ... # ...
@ -156,8 +163,8 @@ You have to modify the relevant requirement file: base, local or production by a
To get this change picked up, you'll need to rebuild the image(s) and restart the running container: :: To get this change picked up, you'll need to rebuild the image(s) and restart the running container: ::
docker compose -f local.yml build docker compose -f docker-compose.local.yml build
docker compose -f local.yml up docker compose -f docker-compose.local.yml up
Debugging Debugging
~~~~~~~~~ ~~~~~~~~~
@ -171,7 +178,7 @@ If you are using the following within your code to debug: ::
Then you may need to run the following for it to work as desired: :: Then you may need to run the following for it to work as desired: ::
$ docker compose -f local.yml run --rm --service-ports django $ docker compose -f docker-compose.local.yml run --rm --service-ports django
django-debug-toolbar django-debug-toolbar
@ -224,7 +231,7 @@ Prerequisites:
* ``use_docker`` was set to ``y`` on project initialization; * ``use_docker`` was set to ``y`` on project initialization;
* ``use_celery`` was set to ``y`` on project initialization. * ``use_celery`` was set to ``y`` on project initialization.
By default, it's enabled both in local and production environments (``local.yml`` and ``production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django`` ``CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself. By default, it's enabled both in local and production environments (``docker-compose.local.yml`` and ``docker-compose.production.yml`` Docker Compose configs, respectively) through a ``flower`` service. For added security, ``flower`` requires its clients to provide authentication credentials specified as the corresponding environments' ``.envs/.local/.django`` and ``.envs/.production/.django`` ``CELERY_FLOWER_USER`` and ``CELERY_FLOWER_PASSWORD`` environment variables. Check out ``localhost:5555`` and see for yourself.
.. _`Flower`: https://github.com/mher/flower .. _`Flower`: https://github.com/mher/flower
@ -272,7 +279,7 @@ certs
Take the certificates that you generated and place them in a folder called ``certs`` in the project's root folder. Assuming that you registered your local hostname as ``my-dev-env.local``, the certificates you will put in the folder should have the names ``my-dev-env.local.crt`` and ``my-dev-env.local.key``. Take the certificates that you generated and place them in a folder called ``certs`` in the project's root folder. Assuming that you registered your local hostname as ``my-dev-env.local``, the certificates you will put in the folder should have the names ``my-dev-env.local.crt`` and ``my-dev-env.local.key``.
local.yml docker-compose.local.yml
~~~~~~~~~ ~~~~~~~~~
#. Add the ``nginx-proxy`` service. :: #. Add the ``nginx-proxy`` service. ::
@ -316,7 +323,7 @@ You should allow the new hostname. ::
Rebuild your ``docker`` application. :: Rebuild your ``docker`` application. ::
$ docker compose -f local.yml up -d --build $ docker compose -f docker-compose.local.yml up -d --build
Go to your browser and type in your URL bar ``https://my-dev-env.local`` Go to your browser and type in your URL bar ``https://my-dev-env.local``
@ -336,9 +343,9 @@ Webpack
If you are using Webpack: If you are using Webpack:
1. On the ``nginx-proxy`` service in ``local.yml``, change ``depends_on`` to ``node`` instead of ``django``. 1. On the ``nginx-proxy`` service in ``docker-compose.local.yml``, change ``depends_on`` to ``node`` instead of ``django``.
2. On the ``node`` service in ``local.yml``, add the following environment configuration: 2. On the ``node`` service in ``docker-compose.local.yml``, add the following environment configuration:
:: ::

View File

@ -9,7 +9,7 @@ Setting Up Development Environment
Make sure to have the following on your host: Make sure to have the following on your host:
* Python 3.11 * Python 3.12
* PostgreSQL_. * PostgreSQL_.
* Redis_, if using Celery * Redis_, if using Celery
* Cookiecutter_ * Cookiecutter_
@ -18,7 +18,7 @@ First things first.
#. Create a virtualenv: :: #. Create a virtualenv: ::
$ python3.11 -m venv <virtual env path> $ python3.12 -m venv <virtual env path>
#. Activate the virtualenv you have just created: :: #. Activate the virtualenv you have just created: ::
@ -96,6 +96,61 @@ First things first.
.. _direnv: https://direnv.net/ .. _direnv: https://direnv.net/
Creating Your First Django App
-------------------------------
After setting up your environment, you're ready to add your first app. This project uses the setup from "Two Scoops of Django" with a two-tier layout:
- **Top Level Repository Root** has config files, documentation, `manage.py`, and more.
- **Second Level Django Project Root** is where your Django apps live.
- **Second Level Configuration Root** holds settings and URL configurations.
The project layout looks something like this: ::
<repository_root>/
├── config/
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── local.py
│ │ └── production.py
│ ├── urls.py
│ └── wsgi.py
├── <django_project_root>/
│ ├── <name_of_the_app>/
│ │ ├── migrations/
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ └── views.py
│ ├── __init__.py
│ └── ...
├── requirements/
│ ├── base.txt
│ ├── local.txt
│ └── production.txt
├── manage.py
├── README.md
└── ...
Following this structured approach, here's how to add a new app:
#. **Create the app** using Django's ``startapp`` command, replacing ``<name-of-the-app>`` with your desired app name: ::
$ python manage.py startapp <name-of-the-app>
#. **Move the app** to the Django Project Root, maintaining the project's two-tier structure: ::
$ mv <name-of-the-app> <django_project_root>/
#. **Edit the app's apps.py** change ``name = '<name-of-the-app>'`` to ``name = '<django_project_root>.<name-of-the-app>'``.
#. **Register the new app** by adding it to the ``LOCAL_APPS`` list in ``config/settings/base.py``, integrating it as an official component of your project.
Setup Email Backend Setup Email Backend
------------------- -------------------

View File

@ -1,14 +1,14 @@
PostgreSQL Backups with Docker PostgreSQL Backups with Docker
============================== ==============================
.. note:: For brevity it is assumed that you will be running the below commands against local environment, however, this is by no means mandatory so feel free to switch to ``production.yml`` when needed. .. note:: For brevity it is assumed that you will be running the below commands against local environment, however, this is by no means mandatory so feel free to switch to ``docker-compose.production.yml`` when needed.
Prerequisites Prerequisites
------------- -------------
#. the project was generated with ``use_docker`` set to ``y``; #. the project was generated with ``use_docker`` set to ``y``;
#. the stack is up and running: ``docker compose -f local.yml up -d postgres``. #. the stack is up and running: ``docker compose -f docker-compose.local.yml up -d postgres``.
Creating a Backup Creating a Backup
@ -16,7 +16,7 @@ Creating a Backup
To create a backup, run:: To create a backup, run::
$ docker compose -f local.yml exec postgres backup $ docker compose -f docker-compose.local.yml exec postgres backup
Assuming your project's database is named ``my_project`` here is what you will see: :: Assuming your project's database is named ``my_project`` here is what you will see: ::
@ -31,7 +31,7 @@ Viewing the Existing Backups
To list existing backups, :: To list existing backups, ::
$ docker compose -f local.yml exec postgres backups $ docker compose -f docker-compose.local.yml exec postgres backups
These are the sample contents of ``/backups``: :: These are the sample contents of ``/backups``: ::
@ -55,9 +55,9 @@ With a single backup file copied to ``.`` that would be ::
$ docker cp 9c5c3f055843:/backups/backup_2018_03_13T09_05_07.sql.gz . $ docker cp 9c5c3f055843:/backups/backup_2018_03_13T09_05_07.sql.gz .
You can also get the container ID using ``docker compose -f local.yml ps -q postgres`` so if you want to automate your backups, you don't have to check the container ID manually every time. Here is the full command :: You can also get the container ID using ``docker compose -f docker-compose.local.yml ps -q postgres`` so if you want to automate your backups, you don't have to check the container ID manually every time. Here is the full command ::
$ docker cp $(docker compose -f local.yml ps -q postgres):/backups ./backups $ docker cp $(docker compose -f docker-compose.local.yml ps -q postgres):/backups ./backups
.. _`command`: https://docs.docker.com/engine/reference/commandline/cp/ .. _`command`: https://docs.docker.com/engine/reference/commandline/cp/
@ -66,7 +66,7 @@ Restoring from the Existing Backup
To restore from one of the backups you have already got (take the ``backup_2018_03_13T09_05_07.sql.gz`` for example), :: To restore from one of the backups you have already got (take the ``backup_2018_03_13T09_05_07.sql.gz`` for example), ::
$ docker compose -f local.yml exec postgres restore backup_2018_03_13T09_05_07.sql.gz $ docker compose -f docker-compose.local.yml exec postgres restore backup_2018_03_13T09_05_07.sql.gz
You will see something like :: You will see something like ::
@ -95,12 +95,33 @@ Backup to Amazon S3
For uploading your backups to Amazon S3 you can use the aws cli container. There is an upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. :: For uploading your backups to Amazon S3 you can use the aws cli container. There is an upload command for uploading the postgres /backups directory recursively and there is a download command for downloading a specific backup. The default S3 environment variables are used. ::
$ docker compose -f production.yml run --rm awscli upload $ docker compose -f docker-compose.production.yml run --rm awscli upload
$ docker compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz $ docker compose -f docker-compose.production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz
Remove Backup Remove Backup
---------------------------------- ----------------------------------
To remove backup you can use the ``rmbackup`` command. This will remove the backup from the ``/backups`` directory. :: To remove backup you can use the ``rmbackup`` command. This will remove the backup from the ``/backups`` directory. ::
$ docker compose -f local.yml exec postgres rmbackup backup_2018_03_13T09_05_07.sql.gz $ docker compose -f docker-compose.local.yml exec postgres rmbackup backup_2018_03_13T09_05_07.sql.gz
Upgrading PostgreSQL
----------------------------------
Upgrading PostgreSQL in your project requires a series of carefully executed steps. Start by halting all containers, excluding the postgres container. Following this, create a backup and proceed to remove the outdated data volume. ::
$ docker compose -f docker-compose.local.yml down
$ docker compose -f docker-compose.local.yml up -d postgres
$ docker compose -f docker-compose.local.yml run --rm postgres backup
$ docker compose -f docker-compose.local.yml down
$ docker volume rm my_project_postgres_data
.. note:: Neglecting to remove the old data volume may lead to issues, such as the new postgres container failing to start with errors like ``FATAL: database files are incompatible with server``, and ``could not translate host name "postgres" to address: Name or service not known``.
To complete the upgrade, update the PostgreSQL version in the corresponding Dockerfile (e.g. ``compose/production/postgres/Dockerfile``) and build a new version of PostgreSQL. ::
$ docker compose -f docker-compose.local.yml build postgres
$ docker compose -f docker-compose.local.yml up -d postgres
$ docker compose -f docker-compose.local.yml run --rm postgres restore backup_2018_03_13T09_05_07.sql.gz
$ docker compose -f docker-compose.local.yml up -d

View File

@ -11,7 +11,7 @@ After you have set up to `develop locally`_, run the following command from the
If you set up your project to `develop locally with docker`_, run the following command: :: If you set up your project to `develop locally with docker`_, run the following command: ::
$ docker compose -f local.yml up docs $ docker compose -f docker-compose.docs.yml up
Navigate to port 9000 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.

View File

@ -24,4 +24,4 @@ Why doesn't this follow the layout from Two Scoops of Django?
You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 3.x`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored. You may notice that some elements of this project do not exactly match what we describe in chapter 3 of `Two Scoops of Django 3.x`_. The reason for that is this project, amongst other things, serves as a test bed for trying out new ideas and concepts. Sometimes they work, sometimes they don't, but the end result is that it won't necessarily match precisely what is described in the book I co-authored.
.. _Two Scoops of Django 3.x: https://www.feldroy.com/books/two-scoops-of-django-3-x .. _Two Scoops of Django 3.x: https://www.feldroy.com/two-scoops-press#two-scoops-of-django

View File

@ -66,12 +66,11 @@ use_docker:
postgresql_version: postgresql_version:
Select a PostgreSQL_ version to use. The choices are: Select a PostgreSQL_ version to use. The choices are:
1. 15 1. 16
2. 14 2. 15
3. 13 3. 14
4. 12 4. 13
5. 11 5. 12
6. 10
cloud_provider: cloud_provider:
Select a cloud provider for static & media files. The choices are: Select a cloud provider for static & media files. The choices are:
@ -92,7 +91,7 @@ mail_service:
4. Mandrill_ 4. Mandrill_
5. Postmark_ 5. Postmark_
6. SendGrid_ 6. SendGrid_
7. SendinBlue_ 7. `Brevo (formerly SendinBlue)`_
8. SparkPost_ 8. SparkPost_
9. `Other SMTP`_ 9. `Other SMTP`_
@ -175,7 +174,7 @@ debug:
.. _Mandrill: http://mandrill.com .. _Mandrill: http://mandrill.com
.. _Postmark: https://postmarkapp.com .. _Postmark: https://postmarkapp.com
.. _SendGrid: https://sendgrid.com .. _SendGrid: https://sendgrid.com
.. _SendinBlue: https://www.sendinblue.com .. _Brevo (formerly SendinBlue): https://www.brevo.com
.. _SparkPost: https://www.sparkpost.com .. _SparkPost: https://www.sparkpost.com
.. _Other SMTP: https://anymail.readthedocs.io/en/stable/ .. _Other SMTP: https://anymail.readthedocs.io/en/stable/

View File

@ -1,3 +1,3 @@
sphinx==7.2.6 sphinx==7.4.5
sphinx-rtd-theme==2.0.0 sphinx-rtd-theme==2.0.0
myst-parser==2.0.0 myst-parser==3.0.1

View File

@ -69,8 +69,8 @@ SENDGRID_API_KEY SENDGRID_API_KEY n/a
SENDGRID_GENERATE_MESSAGE_ID True n/a raises error SENDGRID_GENERATE_MESSAGE_ID True n/a raises error
SENDGRID_MERGE_FIELD_FORMAT None n/a raises error SENDGRID_MERGE_FIELD_FORMAT None n/a raises error
SENDGRID_API_URL n/a n/a "https://api.sendgrid.com/v3/" SENDGRID_API_URL n/a n/a "https://api.sendgrid.com/v3/"
SENDINBLUE_API_KEY SENDINBLUE_API_KEY n/a raises error BREVO_API_KEY BREVO_API_KEY n/a raises error
SENDINBLUE_API_URL n/a n/a "https://api.sendinblue.com/v3/" BREVO_API_URL n/a n/a "https://api.brevo.com/v3/"
SPARKPOST_API_KEY SPARKPOST_API_KEY n/a raises error SPARKPOST_API_KEY SPARKPOST_API_KEY n/a raises error
SPARKPOST_API_URL n/a n/a "https://api.sparkpost.com/api/v1" SPARKPOST_API_URL n/a n/a "https://api.sparkpost.com/api/v1"
======================================= =========================== ============================================== ====================================================================== ======================================= =========================== ============================================== ======================================================================

View File

@ -19,7 +19,7 @@ You will get a readout of the `users` app that has already been set up with test
If you set up your project to `develop locally with docker`_, run the following command: :: If you set up your project to `develop locally with docker`_, run the following command: ::
$ docker compose -f local.yml run --rm django pytest $ docker compose -f docker-compose.local.yml run --rm django pytest
Targeting particular apps for testing in ``docker`` follows a similar pattern as previously shown above. Targeting particular apps for testing in ``docker`` follows a similar pattern as previously shown above.
@ -36,8 +36,8 @@ Once the tests are complete, in order to see the code coverage, run the followin
If you're running the project locally with Docker, use these commands instead: :: If you're running the project locally with Docker, use these commands instead: ::
$ docker compose -f local.yml run --rm django coverage run -m pytest $ docker compose -f docker-compose.local.yml run --rm django coverage run -m pytest
$ docker compose -f local.yml run --rm django coverage report $ docker compose -f docker-compose.local.yml run --rm django coverage report
.. note:: .. note::

View File

@ -30,7 +30,7 @@ If you recreate the project multiple times with the same name, Docker would pres
To fix this, you can either: To fix this, you can either:
- Clear your project-related Docker cache with ``docker compose -f local.yml down --volumes --rmi all``. - Clear your project-related Docker cache with ``docker compose -f docker-compose.local.yml down --volumes --rmi all``.
- Use the Docker volume sub-commands to find volumes (`ls`_) and remove them (`rm`_). - Use the Docker volume sub-commands to find volumes (`ls`_) and remove them (`rm`_).
- Use the `prune`_ command to clear system-wide (use with care!). - Use the `prune`_ command to clear system-wide (use with care!).

View File

@ -78,7 +78,11 @@ def remove_docker_files():
shutil.rmtree(".devcontainer") shutil.rmtree(".devcontainer")
shutil.rmtree("compose") shutil.rmtree("compose")
file_names = ["local.yml", "production.yml", ".dockerignore"] file_names = [
"docker-compose.local.yml",
"docker-compose.production.yml",
".dockerignore",
]
for file_name in file_names: for file_name in file_names:
os.remove(file_name) os.remove(file_name)
if "{{ cookiecutter.editor }}" == "PyCharm": if "{{ cookiecutter.editor }}" == "PyCharm":

View File

@ -39,7 +39,7 @@ if "{{ cookiecutter.use_docker }}".lower() == "n":
if python_major_version == 2: if python_major_version == 2:
print( print(
WARNING + "You're running cookiecutter under Python 2, but the generated " WARNING + "You're running cookiecutter under Python 2, but the generated "
"project requires Python 3.11+. Do you want to proceed (y/n)? " + TERMINATOR "project requires Python 3.12+. Do you want to proceed (y/n)? " + TERMINATOR
) )
yes_options, no_options = frozenset(["y"]), frozenset(["n"]) yes_options, no_options = frozenset(["y"]), frozenset(["n"])
while True: while True:

View File

@ -15,7 +15,7 @@ norecursedirs = [
# ==== black ==== # ==== black ====
[tool.black] [tool.black]
line-length = 119 line-length = 119
target-version = ['py311'] target-version = ['py312']
# ==== isort ==== # ==== isort ====

View File

@ -1,26 +1,26 @@
cookiecutter==2.6.0 cookiecutter==2.6.0
sh==2.0.6; sys_platform != "win32" sh==2.0.7; sys_platform != "win32"
binaryornot==0.4.4 binaryornot==0.4.4
# Code quality # Code quality
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ruff==0.3.0 ruff==0.5.2
django-upgrade==1.16.0 django-upgrade==1.19.0
djlint==1.34.1 djlint==1.34.1
pre-commit==3.6.2 pre-commit==3.7.1
# Testing # Testing
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
tox==4.13.0 tox==4.16.0
pytest==8.1.0 pytest==8.2.2
pytest-xdist==3.5.0 pytest-xdist==3.6.1
pytest-cookies==0.7.0 pytest-cookies==0.7.0
pytest-instafail==0.5.0 pytest-instafail==0.5.0
pyyaml==6.0.1 pyyaml==6.0.1
# Scripting # Scripting
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PyGithub==2.2.0 PyGithub==2.3.0
gitpython==3.1.42 gitpython==3.1.43
jinja2==3.1.3 jinja2==3.1.4
requests==2.31.0 requests==2.32.3

View File

@ -5,7 +5,7 @@ except ImportError:
from distutils.core import setup from distutils.core import setup
# We use calendar versioning # We use calendar versioning
version = "2024.03.03" version = "2024.07.17"
with open("README.md") as readme_file: with open("README.md") as readme_file:
long_description = readme_file.read() long_description = readme_file.read()
@ -30,7 +30,7 @@ setup(
"License :: OSI Approved :: BSD License", "License :: OSI Approved :: BSD License",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development", "Topic :: Software Development",
], ],

View File

@ -57,12 +57,11 @@ SUPPORTED_COMBINATIONS = [
{"editor": "VS Code"}, {"editor": "VS Code"},
{"use_docker": "y"}, {"use_docker": "y"},
{"use_docker": "n"}, {"use_docker": "n"},
{"postgresql_version": "16"},
{"postgresql_version": "15"}, {"postgresql_version": "15"},
{"postgresql_version": "14"}, {"postgresql_version": "14"},
{"postgresql_version": "13"}, {"postgresql_version": "13"},
{"postgresql_version": "12"}, {"postgresql_version": "12"},
{"postgresql_version": "11"},
{"postgresql_version": "10"},
{"cloud_provider": "AWS", "use_whitenoise": "y"}, {"cloud_provider": "AWS", "use_whitenoise": "y"},
{"cloud_provider": "AWS", "use_whitenoise": "n"}, {"cloud_provider": "AWS", "use_whitenoise": "n"},
{"cloud_provider": "GCP", "use_whitenoise": "y"}, {"cloud_provider": "GCP", "use_whitenoise": "y"},
@ -74,7 +73,7 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Postmark"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Postmark"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Sendgrid"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Sendgrid"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SendinBlue"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Brevo"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SparkPost"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "SparkPost"},
{"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Other SMTP"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Other SMTP"},
# Note: cloud_provider=None AND use_whitenoise=n is not supported # Note: cloud_provider=None AND use_whitenoise=n is not supported
@ -84,7 +83,7 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "AWS", "mail_service": "Mandrill"}, {"cloud_provider": "AWS", "mail_service": "Mandrill"},
{"cloud_provider": "AWS", "mail_service": "Postmark"}, {"cloud_provider": "AWS", "mail_service": "Postmark"},
{"cloud_provider": "AWS", "mail_service": "Sendgrid"}, {"cloud_provider": "AWS", "mail_service": "Sendgrid"},
{"cloud_provider": "AWS", "mail_service": "SendinBlue"}, {"cloud_provider": "AWS", "mail_service": "Brevo"},
{"cloud_provider": "AWS", "mail_service": "SparkPost"}, {"cloud_provider": "AWS", "mail_service": "SparkPost"},
{"cloud_provider": "AWS", "mail_service": "Other SMTP"}, {"cloud_provider": "AWS", "mail_service": "Other SMTP"},
{"cloud_provider": "GCP", "mail_service": "Mailgun"}, {"cloud_provider": "GCP", "mail_service": "Mailgun"},
@ -92,7 +91,7 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "GCP", "mail_service": "Mandrill"}, {"cloud_provider": "GCP", "mail_service": "Mandrill"},
{"cloud_provider": "GCP", "mail_service": "Postmark"}, {"cloud_provider": "GCP", "mail_service": "Postmark"},
{"cloud_provider": "GCP", "mail_service": "Sendgrid"}, {"cloud_provider": "GCP", "mail_service": "Sendgrid"},
{"cloud_provider": "GCP", "mail_service": "SendinBlue"}, {"cloud_provider": "GCP", "mail_service": "Brevo"},
{"cloud_provider": "GCP", "mail_service": "SparkPost"}, {"cloud_provider": "GCP", "mail_service": "SparkPost"},
{"cloud_provider": "GCP", "mail_service": "Other SMTP"}, {"cloud_provider": "GCP", "mail_service": "Other SMTP"},
{"cloud_provider": "Azure", "mail_service": "Mailgun"}, {"cloud_provider": "Azure", "mail_service": "Mailgun"},
@ -100,7 +99,7 @@ SUPPORTED_COMBINATIONS = [
{"cloud_provider": "Azure", "mail_service": "Mandrill"}, {"cloud_provider": "Azure", "mail_service": "Mandrill"},
{"cloud_provider": "Azure", "mail_service": "Postmark"}, {"cloud_provider": "Azure", "mail_service": "Postmark"},
{"cloud_provider": "Azure", "mail_service": "Sendgrid"}, {"cloud_provider": "Azure", "mail_service": "Sendgrid"},
{"cloud_provider": "Azure", "mail_service": "SendinBlue"}, {"cloud_provider": "Azure", "mail_service": "Brevo"},
{"cloud_provider": "Azure", "mail_service": "SparkPost"}, {"cloud_provider": "Azure", "mail_service": "SparkPost"},
{"cloud_provider": "Azure", "mail_service": "Other SMTP"}, {"cloud_provider": "Azure", "mail_service": "Other SMTP"},
# Note: cloud_providers GCP, Azure, and None # Note: cloud_providers GCP, Azure, and None
@ -248,7 +247,13 @@ def test_djlint_lint_passes(cookies, context_override):
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687 # TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687
ignored_rules = "H006,H030,H031,T002" ignored_rules = "H006,H030,H031,T002"
try: try:
sh.djlint("--lint", "--ignore", f"{autofixable_rules},{ignored_rules}", ".", _cwd=str(result.project_path)) sh.djlint(
"--lint",
"--ignore",
f"{autofixable_rules},{ignored_rules}",
".",
_cwd=str(result.project_path),
)
except sh.ErrorReturnCode as e: except sh.ErrorReturnCode as e:
pytest.fail(e.stdout.decode()) pytest.fail(e.stdout.decode())
@ -269,7 +274,7 @@ def test_djlint_check_passes(cookies, context_override):
["use_docker", "expected_test_script"], ["use_docker", "expected_test_script"],
[ [
("n", "pytest"), ("n", "pytest"),
("y", "docker compose -f local.yml run django pytest"), ("y", "docker compose -f docker-compose.local.yml run django pytest"),
], ],
) )
def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_script): def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_script):
@ -294,7 +299,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip
["use_docker", "expected_test_script"], ["use_docker", "expected_test_script"],
[ [
("n", "pytest"), ("n", "pytest"),
("y", "docker compose -f local.yml run django pytest"), ("y", "docker compose -f docker-compose.local.yml run django pytest"),
], ],
) )
def test_gitlab_invokes_precommit_and_pytest(cookies, context, use_docker, expected_test_script): def test_gitlab_invokes_precommit_and_pytest(cookies, context, use_docker, expected_test_script):
@ -321,7 +326,7 @@ def test_gitlab_invokes_precommit_and_pytest(cookies, context, use_docker, expec
["use_docker", "expected_test_script"], ["use_docker", "expected_test_script"],
[ [
("n", "pytest"), ("n", "pytest"),
("y", "docker compose -f local.yml run django pytest"), ("y", "docker compose -f docker-compose.local.yml run django pytest"),
], ],
) )
def test_github_invokes_linter_and_pytest(cookies, context, use_docker, expected_test_script): def test_github_invokes_linter_and_pytest(cookies, context, use_docker, expected_test_script):

View File

@ -15,22 +15,22 @@ cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@"
cd my_awesome_project cd my_awesome_project
# make sure all images build # make sure all images build
docker compose -f local.yml build docker compose -f docker-compose.local.yml build
# run the project's type checks # run the project's type checks
docker compose -f local.yml run django mypy my_awesome_project docker compose -f docker-compose.local.yml run django mypy my_awesome_project
# run the project's tests # run the project's tests
docker compose -f local.yml run django pytest docker compose -f docker-compose.local.yml run django pytest
# return non-zero status code if there are migrations that have not been created # return non-zero status code if there are migrations that have not been created
docker compose -f local.yml run django python manage.py makemigrations --dry-run --check || { echo "ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control"; exit 1; } docker compose -f docker-compose.local.yml run django python manage.py makemigrations --dry-run --check || { echo "ERROR: there were changes in the models, but migration listed above have not been created and are not saved in version control"; exit 1; }
# Test support for translations # Test support for translations
docker compose -f local.yml run django python manage.py makemessages --all docker compose -f docker-compose.local.yml run django python manage.py makemessages --all
# Make sure the check doesn't raise any warnings # Make sure the check doesn't raise any warnings
docker compose -f local.yml run \ docker compose -f docker-compose.local.yml run \
-e DJANGO_SECRET_KEY="$(openssl rand -base64 64)" \ -e DJANGO_SECRET_KEY="$(openssl rand -base64 64)" \
-e REDIS_URL=redis://redis:6379/0 \ -e REDIS_URL=redis://redis:6379/0 \
-e CELERY_BROKER_URL=redis://redis:6379/0 \ -e CELERY_BROKER_URL=redis://redis:6379/0 \
@ -43,10 +43,10 @@ docker compose -f local.yml run \
django python manage.py check --settings=config.settings.production --deploy --database default --fail-level WARNING django python manage.py check --settings=config.settings.production --deploy --database default --fail-level WARNING
# Generate the HTML for the documentation # Generate the HTML for the documentation
docker compose -f local.yml run docs make html docker compose -f docker-compose.docs.yml run docs make html
# Run npm build script if package.json is present # Run npm build script if package.json is present
if [ -f "package.json" ] if [ -f "package.json" ]
then then
docker compose -f local.yml run node npm run build docker compose -f docker-compose.local.yml run node npm run build
fi fi

View File

@ -1,6 +1,6 @@
[tox] [tox]
skipsdist = true skipsdist = true
envlist = py311,black-template envlist = py312,black-template
[testenv] [testenv]
deps = -rrequirements.txt deps = -rrequirements.txt

View File

@ -2,7 +2,7 @@
{ {
"name": "{{cookiecutter.project_slug}}_dev", "name": "{{cookiecutter.project_slug}}_dev",
"dockerComposeFile": [ "dockerComposeFile": [
"../local.yml" "../docker-compose.local.yml"
], ],
"init": true, "init": true,
"mounts": [ "mounts": [

View File

@ -13,7 +13,7 @@ environment:
steps: steps:
- name: lint - name: lint
pull: if-not-exists pull: if-not-exists
image: python:3.11 image: python:3.12
environment: environment:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
volumes: volumes:
@ -27,16 +27,17 @@ steps:
- name: test - name: test
pull: if-not-exists pull: if-not-exists
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
image: docker/compose:1.29.2 image: docker:25.0
environment: environment:
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
commands: commands:
- docker-compose -f local.yml build - docker-compose -f docker-compose.local.yml build
- docker-compose -f local.yml run --rm django python manage.py migrate - docker-compose -f docker-compose.docs.yml build
- docker-compose -f local.yml up -d - docker-compose -f docker-compose.local.yml run --rm django python manage.py migrate
- docker-compose -f local.yml run django pytest - docker-compose -f docker-compose.local.yml up -d
- docker-compose -f docker-compose.local.yml run django pytest
{%- else %} {%- else %}
image: python:3.11 image: python:3.12
commands: commands:
- pip install -r requirements/local.txt - pip install -r requirements/local.txt
- pytest - pytest

View File

@ -28,8 +28,8 @@ POSTMARK_SERVER_TOKEN=
SENDGRID_API_KEY= SENDGRID_API_KEY=
SENDGRID_GENERATE_MESSAGE_ID=True SENDGRID_GENERATE_MESSAGE_ID=True
SENDGRID_MERGE_FIELD_FORMAT=None SENDGRID_MERGE_FIELD_FORMAT=None
{% elif cookiecutter.mail_service == 'SendinBlue' %} {% elif cookiecutter.mail_service == 'Brevo' %}
SENDINBLUE_API_KEY= BREVO_API_KEY=
{% elif cookiecutter.mail_service == 'SparkPost' %} {% elif cookiecutter.mail_service == 'SparkPost' %}
SPARKPOST_API_KEY= SPARKPOST_API_KEY=
{% endif %} {% endif %}

View File

@ -26,15 +26,15 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.11' python-version: '3.12'
{%- if cookiecutter.open_source_license != 'Not open source' %} {%- if cookiecutter.open_source_license != 'Not open source' %}
# Consider using pre-commit.ci for open source project # Consider using pre-commit.ci for open source project
{%- endif %} {%- endif %}
- name: Run pre-commit - name: Run pre-commit
uses: pre-commit/action@v3.0.0 uses: pre-commit/action@v3.0.1
# With no caching at all the entire ci process takes 3m to complete! # With no caching at all the entire ci process takes 3m to complete!
pytest: pytest:
@ -69,22 +69,25 @@ jobs:
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
- name: Build the Stack - name: Build the Stack
run: docker compose -f local.yml build django run: docker compose -f docker-compose.local.yml build django
- name: Build the docs
run: docker compose -f docker-compose.docs.yml build docs
- name: Run DB Migrations - name: Run DB Migrations
run: docker compose -f local.yml run --rm django python manage.py migrate run: docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
- name: Run Django Tests - name: Run Django Tests
run: docker compose -f local.yml run django pytest run: docker compose -f docker-compose.local.yml run django pytest
- name: Tear down the Stack - name: Tear down the Stack
run: docker compose -f local.yml down run: docker compose -f docker-compose.local.yml down
{%- else %} {%- else %}
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: '3.11' python-version: '3.12'
cache: pip cache: pip
cache-dependency-path: | cache-dependency-path: |
requirements/base.txt requirements/base.txt

View File

@ -13,7 +13,7 @@ variables:
precommit: precommit:
stage: lint stage: lint
image: python:3.11 image: python:3.12
variables: variables:
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
cache: cache:
@ -27,22 +27,19 @@ precommit:
pytest: pytest:
stage: test stage: test
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
image: docker/compose:1.29.2 image: docker:25.0
tags:
- docker
services: services:
- docker:dind - docker:dind
before_script: before_script:
- docker compose -f local.yml build - docker compose -f docker-compose.local.yml build
- docker compose -f docker-compose.docs.yml build
# Ensure celerybeat does not crash due to non-existent tables # Ensure celerybeat does not crash due to non-existent tables
- docker compose -f local.yml run --rm django python manage.py migrate - docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
- docker compose -f local.yml up -d - docker compose -f docker-compose.local.yml up -d
script: script:
- docker compose -f local.yml run django pytest - docker compose -f docker-compose.local.yml run django pytest
{%- else %} {%- else %}
image: python:3.11 image: python:3.12
tags:
- python
services: services:
- postgres:{{ cookiecutter.postgresql_version }} - postgres:{{ cookiecutter.postgresql_version }}
variables: variables:

View File

@ -15,7 +15,7 @@
{%- endif %} {%- endif %}
</list> </list>
</option> </option>
<option name="sourceFilePath" value="local.yml"/> <option name="sourceFilePath" value="docker-compose.local.yml"/>
</settings> </settings>
</deployment> </deployment>
<method v="2"/> <method v="2"/>

View File

@ -8,7 +8,7 @@
<option value="docs"/> <option value="docs"/>
</list> </list>
</option> </option>
<option name="sourceFilePath" value="local.yml"/> <option name="sourceFilePath" value="docker-compose.local.yml"/>
</settings> </settings>
</deployment> </deployment>
<method v="2"/> <method v="2"/>

View File

@ -2,11 +2,11 @@ exclude: '^docs/|/migrations/|devcontainer.json'
default_stages: [commit] default_stages: [commit]
default_language_version: default_language_version:
python: python3.11 python: python3.12
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.6.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
@ -28,14 +28,14 @@ repos:
exclude: '{{cookiecutter.project_slug}}/templates/' exclude: '{{cookiecutter.project_slug}}/templates/'
- repo: https://github.com/adamchainz/django-upgrade - repo: https://github.com/adamchainz/django-upgrade
rev: '1.16.0' rev: '1.19.0'
hooks: hooks:
- id: django-upgrade - id: django-upgrade
args: ['--target-version', '4.2'] args: ['--target-version', '4.2']
# Run the Ruff linter. # Run the Ruff linter.
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.0 rev: v0.5.2
hooks: hooks:
# Linter # Linter
- id: ruff - id: ruff

View File

@ -8,7 +8,7 @@ version: 2
build: build:
os: ubuntu-22.04 os: ubuntu-22.04
tools: tools:
python: '3.11' python: '3.12'
# Build documentation in the docs/ directory with Sphinx # Build documentation in the docs/ directory with Sphinx
sphinx: sphinx:

View File

@ -2,7 +2,7 @@ dist: focal
language: python language: python
python: python:
- "3.11" - "3.12"
services: services:
- {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %} - {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %}
@ -19,14 +19,15 @@ jobs:
before_script: before_script:
- docker compose -v - docker compose -v
- docker -v - docker -v
- docker compose -f local.yml build - docker compose -f docker-compose.local.yml build
- docker compose -f docker-compose.docs.yml build
# Ensure celerybeat does not crash due to non-existent tables # Ensure celerybeat does not crash due to non-existent tables
- docker compose -f local.yml run --rm django python manage.py migrate - docker compose -f docker-compose.local.yml run --rm django python manage.py migrate
- docker compose -f local.yml up -d - docker compose -f docker-compose.local.yml up -d
script: script:
- docker compose -f local.yml run django pytest - docker compose -f docker-compose.local.yml run django pytest
after_failure: after_failure:
- docker compose -f local.yml logs - docker compose -f docker-compose.local.yml logs
{%- else %} {%- else %}
before_install: before_install:
- sudo apt-get update -qq - sudo apt-get update -qq
@ -37,7 +38,7 @@ jobs:
- sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm - sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm
language: python language: python
python: python:
- "3.11" - "3.12"
install: install:
- pip install -r requirements/local.txt - pip install -r requirements/local.txt
script: script:

View File

@ -1,6 +1,6 @@
release: python manage.py migrate release: python manage.py migrate
{%- if cookiecutter.use_async == "y" %} {%- if cookiecutter.use_async == "y" %}
web: gunicorn config.asgi:application -k uvicorn.workers.UvicornWorker web: gunicorn config.asgi:application -k uvicorn_worker.UvicornWorker
{%- else %} {%- else %}
web: gunicorn config.wsgi:application web: gunicorn config.wsgi:application
{%- endif %} {%- endif %}

View File

@ -1,8 +1,8 @@
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.11.8-slim-bookworm as python FROM docker.io/python:3.12.4-slim-bookworm AS python
# Python build stage # Python build stage
FROM docker.io/python as python-build-stage FROM python AS python-build-stage
ARG BUILD_ENVIRONMENT=local ARG BUILD_ENVIRONMENT=local
@ -10,7 +10,7 @@ ARG BUILD_ENVIRONMENT=local
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev libpq-dev
# Requirements are installed here to ensure they will be cached. # Requirements are installed here to ensure they will be cached.
@ -22,7 +22,7 @@ RUN pip wheel --wheel-dir /usr/src/app/wheels \
# Python 'run' stage # Python 'run' stage
FROM docker.io/python as python-run-stage FROM python AS python-run-stage
ARG BUILD_ENVIRONMENT=local ARG BUILD_ENVIRONMENT=local
ARG APP_HOME=/app ARG APP_HOME=/app
@ -47,7 +47,7 @@ RUN groupadd --gid 1000 dev-user \
# Install required system dependencies # Install required system dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -3,6 +3,14 @@
set -o errexit set -o errexit
set -o nounset set -o nounset
until timeout 10 celery -A config.celery_app inspect ping; do
>&2 echo "Celery workers not available"
done
echo 'Starting flower'
exec watchfiles --filter python celery.__main__.main \ exec watchfiles --filter python celery.__main__.main \
--args \ --args \
"-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\"" "-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\""

View File

@ -1,16 +1,16 @@
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.11.8-slim-bookworm as python FROM docker.io/python:3.12.4-slim-bookworm AS python
# Python build stage # Python build stage
FROM docker.io/python as python-build-stage FROM python AS python-build-stage
ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# cleaning up unused files # cleaning up unused files
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
@ -26,7 +26,7 @@ RUN pip wheel --no-cache-dir --wheel-dir /usr/src/app/wheels \
# Python 'run' stage # Python 'run' stage
FROM docker.io/python as python-run-stage FROM python AS python-run-stage
ARG BUILD_ENVIRONMENT ARG BUILD_ENVIRONMENT
ENV PYTHONUNBUFFERED 1 ENV PYTHONUNBUFFERED 1
@ -35,7 +35,7 @@ ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# To run the Makefile # To run the Makefile
make \ make \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -1,4 +1,7 @@
FROM docker.io/garland/aws-cli-docker:1.16.140 FROM docker.io/amazon/aws-cli:2.17.0
# Clear entrypoint from the base image, otherwise it's always calling the aws CLI
ENTRYPOINT []
COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance
COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced

View File

@ -3,7 +3,7 @@
### Download a file from your Amazon S3 bucket to the postgres /backups folder ### Download a file from your Amazon S3 bucket to the postgres /backups folder
### ###
### Usage: ### Usage:
### $ docker compose -f production.yml run --rm awscli <1> ### $ docker compose -f docker-compose.production.yml run --rm awscli <1>
set -o errexit set -o errexit
set -o pipefail set -o pipefail

View File

@ -3,7 +3,7 @@
### Upload the /backups folder to Amazon S3 ### Upload the /backups folder to Amazon S3
### ###
### Usage: ### Usage:
### $ docker compose -f production.yml run --rm awscli upload ### $ docker compose -f docker-compose.production.yml run --rm awscli upload
set -o errexit set -o errexit
set -o pipefail set -o pipefail

View File

@ -1,5 +1,5 @@
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%} {% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%}
FROM docker.io/node:20-bookworm-slim as client-builder FROM docker.io/node:20-bookworm-slim AS client-builder
ARG APP_HOME=/app ARG APP_HOME=/app
WORKDIR ${APP_HOME} WORKDIR ${APP_HOME}
@ -25,10 +25,10 @@ RUN npm run build
{%- endif %} {%- endif %}
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.11.8-slim-bookworm as python FROM docker.io/python:3.12.4-slim-bookworm AS python
# Python build stage # Python build stage
FROM docker.io/python as python-build-stage FROM python AS python-build-stage
ARG BUILD_ENVIRONMENT=production ARG BUILD_ENVIRONMENT=production
@ -36,7 +36,7 @@ ARG BUILD_ENVIRONMENT=production
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev libpq-dev
# Requirements are installed here to ensure they will be cached. # Requirements are installed here to ensure they will be cached.
@ -48,7 +48,7 @@ RUN pip wheel --wheel-dir /usr/src/app/wheels \
# Python 'run' stage # Python 'run' stage
FROM docker.io/python as python-run-stage FROM python AS python-run-stage
ARG BUILD_ENVIRONMENT=production ARG BUILD_ENVIRONMENT=production
ARG APP_HOME=/app ARG APP_HOME=/app
@ -65,7 +65,7 @@ RUN addgroup --system django \
# Install required system dependencies # Install required system dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -4,6 +4,14 @@ set -o errexit
set -o nounset set -o nounset
until timeout 10 celery -A config.celery_app inspect ping; do
>&2 echo "Celery workers not available"
done
echo 'Starting flower'
exec celery \ exec celery \
-A config.celery_app \ -A config.celery_app \
-b "${CELERY_BROKER_URL}" \ -b "${CELERY_BROKER_URL}" \

View File

@ -28,7 +28,7 @@ if compress_enabled; then
fi fi
{%- endif %} {%- endif %}
{%- if cookiecutter.use_async == 'y' %} {%- if cookiecutter.use_async == 'y' %}
exec /usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker exec /usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn_worker.UvicornWorker
{%- else %} {%- else %}
exec /usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app exec /usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
{%- endif %} {%- endif %}

View File

@ -1,4 +1,4 @@
FROM docker.io/traefik:2.11.0 FROM docker.io/traefik:2.11.2
RUN mkdir -p /etc/traefik/acme \ RUN mkdir -p /etc/traefik/acme \
&& touch /etc/traefik/acme/acme.json \ && touch /etc/traefik/acme/acme.json \
&& chmod 600 /etc/traefik/acme/acme.json && chmod 600 /etc/traefik/acme/acme.json

View File

@ -372,6 +372,7 @@ SPECTACULAR_SETTINGS = {
"DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}", "DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}",
"VERSION": "1.0.0", "VERSION": "1.0.0",
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"], "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
"SCHEMA_PATH_PREFIX": "/api/",
} }
{%- endif %} {%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %}

View File

@ -64,7 +64,12 @@ INSTALLED_APPS += ["debug_toolbar"]
MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
# https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config
DEBUG_TOOLBAR_CONFIG = { DEBUG_TOOLBAR_CONFIG = {
"DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], "DISABLE_PANELS": [
"debug_toolbar.panels.redirects.RedirectsPanel",
# Disable profiling panel due to an issue with Python 3.12:
# https://github.com/jazzband/django-debug-toolbar/issues/1875
"debug_toolbar.panels.profiling.ProfilingPanel",
],
"SHOW_TEMPLATE_CONTEXT": True, "SHOW_TEMPLATE_CONTEXT": True,
} }
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips
@ -83,6 +88,15 @@ if env("USE_DOCKER") == "yes":
# The node container isn't started (yet?) # The node container isn't started (yet?)
pass pass
{%- endif %} {%- endif %}
{%- if cookiecutter.windows == 'y' %}
# RunServerPlus
# ------------------------------------------------------------------------------
# This is a custom setting for RunServerPlus to fix reloader issue in Windows docker environment
# Werkzeug reloader type [auto, watchdog, or stat]
RUNSERVERPLUS_POLLER_RELOADER_TYPE = 'stat'
# If you have CPU and IO load issues, you can increase this poller interval e.g) 5
RUNSERVERPLUS_POLLER_RELOADER_INTERVAL = 1
{%- endif %}
{%- endif %} {%- endif %}
# django-extensions # django-extensions

View File

@ -55,8 +55,12 @@ SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = env.bool("DJANGO_SECURE_SSL_REDIRECT", default=True) SECURE_SSL_REDIRECT = env.bool("DJANGO_SECURE_SSL_REDIRECT", default=True)
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure # https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-secure
SESSION_COOKIE_SECURE = True SESSION_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#session-cookie-name
SESSION_COOKIE_NAME = "__Secure-sessionid"
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure # https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-secure
CSRF_COOKIE_SECURE = True CSRF_COOKIE_SECURE = True
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-name
CSRF_COOKIE_NAME = "__Secure-csrftoken"
# https://docs.djangoproject.com/en/dev/topics/security/#ssl-https # https://docs.djangoproject.com/en/dev/topics/security/#ssl-https
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-seconds
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works # TODO: set this to 60 seconds first and then to 518400 once you prove the former works
@ -118,7 +122,7 @@ AZURE_CONTAINER = env("DJANGO_AZURE_CONTAINER_NAME")
# STATIC & MEDIA # STATIC & MEDIA
# ------------------------ # ------------------------
STORAGES = { STORAGES = {
{%- if cookiecutter.use_whitenoise == 'y' %} {%- if cookiecutter.use_whitenoise == 'y' and cookiecutter.cloud_provider == 'None' %}
"default": { "default": {
"BACKEND": "django.core.files.storage.FileSystemStorage", "BACKEND": "django.core.files.storage.FileSystemStorage",
}, },
@ -133,6 +137,11 @@ STORAGES = {
"file_overwrite": False, "file_overwrite": False,
}, },
}, },
{%- if cookiecutter.use_whitenoise == 'y' %}
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
{%- else %}
"staticfiles": { "staticfiles": {
"BACKEND": "storages.backends.s3.S3Storage", "BACKEND": "storages.backends.s3.S3Storage",
"OPTIONS": { "OPTIONS": {
@ -140,6 +149,7 @@ STORAGES = {
"default_acl": "public-read", "default_acl": "public-read",
}, },
}, },
{%- endif %}
{%- elif cookiecutter.cloud_provider == 'GCP' %} {%- elif cookiecutter.cloud_provider == 'GCP' %}
"default": { "default": {
"BACKEND": "storages.backends.gcloud.GoogleCloudStorage", "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
@ -148,6 +158,11 @@ STORAGES = {
"file_overwrite": False, "file_overwrite": False,
}, },
}, },
{%- if cookiecutter.use_whitenoise == 'y' %}
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
{%- else %}
"staticfiles": { "staticfiles": {
"BACKEND": "storages.backends.gcloud.GoogleCloudStorage", "BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
"OPTIONS": { "OPTIONS": {
@ -155,6 +170,7 @@ STORAGES = {
"default_acl": "publicRead", "default_acl": "publicRead",
}, },
}, },
{%- endif %}
{%- elif cookiecutter.cloud_provider == 'Azure' %} {%- elif cookiecutter.cloud_provider == 'Azure' %}
"default": { "default": {
"BACKEND": "storages.backends.azure_storage.AzureStorage", "BACKEND": "storages.backends.azure_storage.AzureStorage",
@ -163,6 +179,11 @@ STORAGES = {
"file_overwrite": False, "file_overwrite": False,
}, },
}, },
{%- if cookiecutter.use_whitenoise == 'y' %}
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
{%- else %}
"staticfiles": { "staticfiles": {
"BACKEND": "storages.backends.azure_storage.AzureStorage", "BACKEND": "storages.backends.azure_storage.AzureStorage",
"OPTIONS": { "OPTIONS": {
@ -170,21 +191,28 @@ STORAGES = {
}, },
}, },
{%- endif %} {%- endif %}
{%- endif %}
} }
{%- endif %} {%- endif %}
{%- if cookiecutter.cloud_provider == 'AWS' %} {%- if cookiecutter.cloud_provider == 'AWS' %}
MEDIA_URL = f"https://{aws_s3_domain}/media/" MEDIA_URL = f"https://{aws_s3_domain}/media/"
COLLECTFAST_STRATEGY = "collectfast.strategies.boto3.Boto3Strategy" {%- if cookiecutter.use_whitenoise == 'n' %}
COLLECTFASTA_STRATEGY = "collectfasta.strategies.boto3.Boto3Strategy"
STATIC_URL = f"https://{aws_s3_domain}/static/" STATIC_URL = f"https://{aws_s3_domain}/static/"
{%- endif %}
{%- elif cookiecutter.cloud_provider == 'GCP' %} {%- elif cookiecutter.cloud_provider == 'GCP' %}
MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/" MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/"
COLLECTFAST_STRATEGY = "collectfast.strategies.gcloud.GoogleCloudStrategy" {%- if cookiecutter.use_whitenoise == 'n' %}
COLLECTFASTA_STRATEGY = "collectfasta.strategies.gcloud.GoogleCloudStrategy"
STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/" STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/"
{%- endif %}
{%- elif cookiecutter.cloud_provider == 'Azure' %} {%- elif cookiecutter.cloud_provider == 'Azure' %}
MEDIA_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/media/" MEDIA_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/media/"
{%- if cookiecutter.use_whitenoise == 'n' %}
STATIC_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/" STATIC_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/"
{%- endif %} {%- endif %}
{%- endif %}
# EMAIL # EMAIL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -252,12 +280,12 @@ ANYMAIL = {
"SENDGRID_API_KEY": env("SENDGRID_API_KEY"), "SENDGRID_API_KEY": env("SENDGRID_API_KEY"),
"SENDGRID_API_URL": env("SENDGRID_API_URL", default="https://api.sendgrid.com/v3/"), "SENDGRID_API_URL": env("SENDGRID_API_URL", default="https://api.sendgrid.com/v3/"),
} }
{%- elif cookiecutter.mail_service == 'SendinBlue' %} {%- elif cookiecutter.mail_service == 'Brevo' %}
# https://anymail.readthedocs.io/en/stable/esps/sendinblue/ # https://anymail.readthedocs.io/en/stable/esps/brevo/
EMAIL_BACKEND = "anymail.backends.sendinblue.EmailBackend" EMAIL_BACKEND = "anymail.backends.brevo.EmailBackend"
ANYMAIL = { ANYMAIL = {
"SENDINBLUE_API_KEY": env("SENDINBLUE_API_KEY"), "BREVO_API_KEY": env("BREVO_API_KEY"),
"SENDINBLUE_API_URL": env("SENDINBLUE_API_URL", default="https://api.sendinblue.com/v3/"), "BREVO_API_URL": env("BREVO_API_URL", default="https://api.brevo.com/v3/"),
} }
{%- elif cookiecutter.mail_service == 'SparkPost' %} {%- elif cookiecutter.mail_service == 'SparkPost' %}
# https://anymail.readthedocs.io/en/stable/esps/sparkpost/ # https://anymail.readthedocs.io/en/stable/esps/sparkpost/
@ -285,7 +313,8 @@ COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage"
COMPRESS_STORAGE = STORAGES["staticfiles"]["BACKEND"] COMPRESS_STORAGE = STORAGES["staticfiles"]["BACKEND"]
{%- endif %} {%- endif %}
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL
COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %}{% endif %} COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa: F405
{%- endif -%}
{%- if cookiecutter.use_whitenoise == 'y' %} {%- if cookiecutter.use_whitenoise == 'y' %}
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE
COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise
@ -300,10 +329,10 @@ COMPRESS_FILTERS = {
} }
{% endif %} {% endif %}
{%- if cookiecutter.use_whitenoise == 'n' -%} {%- if cookiecutter.use_whitenoise == 'n' -%}
# Collectfast # Collectfasta
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# https://github.com/antonagestam/collectfast#installation # https://github.com/jasongi/collectfasta#installation
INSTALLED_APPS = ["collectfast", *INSTALLED_APPS] INSTALLED_APPS = ["collectfasta", *INSTALLED_APPS]
{% endif %} {% endif %}
# LOGGING # LOGGING
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -43,7 +43,7 @@ urlpatterns += [
# API base url # API base url
path("api/", include("config.api_router")), path("api/", include("config.api_router")),
# DRF auth token # DRF auth token
path("auth-token/", obtain_auth_token), path("api/auth-token/", obtain_auth_token),
path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"), path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
path( path(
"api/docs/", "api/docs/",

View File

@ -0,0 +1,16 @@
services:
docs:
image: {{ cookiecutter.project_slug }}_local_docs
container_name: {{ cookiecutter.project_slug }}_local_docs
build:
context: .
dockerfile: ./compose/local/docs/Dockerfile
env_file:
- ./.envs/.local/.django
volumes:
- ./docs:/docs:z
- ./config:/app/config:z
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
ports:
- '9000:9000'
command: /start-docs

View File

@ -1,8 +1,7 @@
version: '3'
volumes: volumes:
{{ cookiecutter.project_slug }}_local_postgres_data: {} {{ cookiecutter.project_slug }}_local_postgres_data: {}
{{ cookiecutter.project_slug }}_local_postgres_data_backups: {} {{ cookiecutter.project_slug }}_local_postgres_data_backups: {}
{% if cookiecutter.use_celery == 'y' %}{{ cookiecutter.project_slug }}_local_redis_data: {}{% endif %}
services: services:
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %} django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
@ -40,21 +39,6 @@ services:
env_file: env_file:
- ./.envs/.local/.postgres - ./.envs/.local/.postgres
docs:
image: {{ cookiecutter.project_slug }}_local_docs
container_name: {{ cookiecutter.project_slug }}_local_docs
build:
context: .
dockerfile: ./compose/local/docs/Dockerfile
env_file:
- ./.envs/.local/.django
volumes:
- ./docs:/docs:z
- ./config:/app/config:z
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
ports:
- '9000:9000'
command: /start-docs
{%- if cookiecutter.use_mailpit == 'y' %} {%- if cookiecutter.use_mailpit == 'y' %}
mailpit: mailpit:
@ -69,6 +53,10 @@ services:
redis: redis:
image: docker.io/redis:6 image: docker.io/redis:6
container_name: {{ cookiecutter.project_slug }}_local_redis container_name: {{ cookiecutter.project_slug }}_local_redis
{% if cookiecutter.use_celery == 'y' %}
volumes:
- {{ cookiecutter.project_slug }}_local_redis_data:/data
{% endif %}
celeryworker: celeryworker:
<<: *django <<: *django

View File

@ -1,5 +1,3 @@
version: '3'
volumes: volumes:
production_postgres_data: {} production_postgres_data: {}
production_postgres_data_backups: {} production_postgres_data_backups: {}
@ -7,6 +5,10 @@ volumes:
{%- if cookiecutter.cloud_provider == 'None' %} {%- if cookiecutter.cloud_provider == 'None' %}
production_django_media: {} production_django_media: {}
{%- endif %} {%- endif %}
{% if cookiecutter.use_celery == 'y' %}
production_redis_data: {}
{% endif %}
services: services:
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %} django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
@ -68,6 +70,12 @@ services:
redis: redis:
image: docker.io/redis:6 image: docker.io/redis:6
{% if cookiecutter.use_celery == 'y' %}
volumes:
- production_redis_data:/data
{% endif %}
{%- if cookiecutter.use_celery == 'y' %} {%- if cookiecutter.use_celery == 'y' %}
celeryworker: celeryworker:
@ -102,7 +110,7 @@ services:
build: build:
context: . context: .
dockerfile: ./compose/production/nginx/Dockerfile dockerfile: ./compose/production/nginx/Dockerfile
image: {{ cookiecutter.project_slug }}_local_nginx image: {{ cookiecutter.project_slug }}_production_nginx
depends_on: depends_on:
- django - django
volumes: volumes:

View File

@ -15,7 +15,7 @@ from inside the `{{cookiecutter.project_slug}}/docs` directory.
{% else %} {% else %}
To build and serve docs, use the commands:: To build and serve docs, use the commands::
docker compose -f local.yml up docs docker compose -f docker-compose.local.yml up docs
{% endif %} {% endif %}
@ -26,7 +26,7 @@ Changes to files in `docs/_source` will be picked up and reloaded automatically.
Docstrings to Documentation Docstrings to Documentation
---------------------------------------------------------------------- ----------------------------------------------------------------------
The sphinx extension `apidoc <https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html/>`_ is used to automatically document code using signatures and docstrings. The sphinx extension `apidoc <https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html>`_ is used to automatically document code using signatures and docstrings.
Numpy or Google style docstrings will be picked up from project files and available for documentation. See the `Napoleon <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/>`_ extension for details. Numpy or Google style docstrings will be picked up from project files and available for documentation. See the `Napoleon <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/>`_ extension for details.

View File

@ -21,7 +21,7 @@ Next, you have to add new remote python interpreter, based on already tested dep
.. image:: images/3.png .. image:: images/3.png
Switch to *Docker Compose* and select `local.yml` file from directory of your project, next set *Service name* to `django` Switch to *Docker Compose* and select `docker-compose.local.yml` file from directory of your project, next set *Service name* to `django`
.. image:: images/4.png .. image:: images/4.png

View File

@ -106,7 +106,7 @@ function imgCompression() {
function asyncRunServer() { function asyncRunServer() {
const cmd = spawn( const cmd = spawn(
'gunicorn', 'gunicorn',
['config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload'], ['config.asgi', '-k', 'uvicorn_worker.UvicornWorker', '--reload'],
{stdio: 'inherit'}, {stdio: 'inherit'},
); );
cmd.on('close', function (code) { cmd.on('close', function (code) {

View File

@ -3,7 +3,7 @@
Start by configuring the `LANGUAGES` settings in `base.py`, by uncommenting languages you are willing to support. Then, translations strings will be placed in this folder when running: Start by configuring the `LANGUAGES` settings in `base.py`, by uncommenting languages you are willing to support. Then, translations strings will be placed in this folder when running:
```bash ```bash
{% if cookiecutter.use_docker == 'y' %}docker compose -f local.yml run --rm django {% endif %}python manage.py makemessages -all --no-location {% if cookiecutter.use_docker == 'y' %}docker compose -f docker-compose.local.yml run --rm django {% endif %}python manage.py makemessages --all --no-location
``` ```
This should generate `django.po` (stands for Portable Object) files under each locale `<locale name>/LC_MESSAGES/django.po`. Each translatable string in the codebase is collected with its `msgid` and need to be translated as `msgstr`, for example: This should generate `django.po` (stands for Portable Object) files under each locale `<locale name>/LC_MESSAGES/django.po`. Each translatable string in the codebase is collected with its `msgid` and need to be translated as `msgstr`, for example:
@ -16,7 +16,7 @@ msgstr "utilisateurs"
Once all translations are done, they need to be compiled into `.mo` files (stands for Machine Object), which are the actual binary files used by the application: Once all translations are done, they need to be compiled into `.mo` files (stands for Machine Object), which are the actual binary files used by the application:
```bash ```bash
{% if cookiecutter.use_docker == 'y' %}docker compose -f local.yml run --rm django {% endif %}python manage.py compilemessages {% if cookiecutter.use_docker == 'y' %}docker compose -f docker-compose.local.yml run --rm django {% endif %}python manage.py compilemessages
``` ```
Note that the `.po` files are NOT used by the application directly, so if the `.mo` files are out of dates, the content won't appear as translated even if the `.po` files are up-to-date. Note that the `.po` files are NOT used by the application directly, so if the `.mo` files are out of dates, the content won't appear as translated even if the `.po` files are up-to-date.

View File

@ -12,7 +12,7 @@
"css-loader": "^6.5.1", "css-loader": "^6.5.1",
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"concurrently": "^8.0.1", "concurrently": "^8.0.1",
"cssnano": "^6.0.0", "cssnano": "^7.0.0",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-imagemin": "^7.1.0", "gulp-imagemin": "^7.1.0",
"gulp-plumber": "^1.2.1", "gulp-plumber": "^1.2.1",

View File

@ -1,7 +1,7 @@
# ==== pytest ==== # ==== pytest ====
[tool.pytest.ini_options] [tool.pytest.ini_options]
minversion = "6.0" minversion = "6.0"
addopts = "--ds=config.settings.test --reuse-db" addopts = "--ds=config.settings.test --reuse-db --import-mode=importlib"
python_files = [ python_files = [
"tests.py", "tests.py",
"test_*.py", "test_*.py",
@ -18,7 +18,7 @@ plugins = ["django_coverage_plugin"]
# ==== mypy ==== # ==== mypy ====
[tool.mypy] [tool.mypy]
python_version = "3.11" python_version = "3.12"
check_untyped_defs = true check_untyped_defs = true
ignore_missing_imports = true ignore_missing_imports = true
warn_unused_ignores = true warn_unused_ignores = true
@ -45,7 +45,7 @@ blank_line_after_tag = "load,extends"
close_void_tags = true close_void_tags = true
format_css = true format_css = true
format_js = true format_js = true
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687 # TODO: remove T002 when fixed https://github.com/djlint/djLint/issues/687
ignore = "H006,H030,H031,T002" ignore = "H006,H030,H031,T002"
include = "H017,H035" include = "H017,H035"
indent = 2 indent = 2
@ -88,7 +88,7 @@ exclude = [
# Same as Django: https://github.com/cookiecutter/cookiecutter-django/issues/4792. # Same as Django: https://github.com/cookiecutter/cookiecutter-django/issues/4792.
line-length = 88 line-length = 88
indent-width = 4 indent-width = 4
target-version = "py311" target-version = "py312"
[tool.ruff.lint] [tool.ruff.lint]
select = [ select = [
@ -150,11 +150,20 @@ select = [
ignore = [ ignore = [
"S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/ "S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"SIM102" # sometimes it's better to nest "SIM102", # sometimes it's better to nest
"UP038" # Checks for uses of isinstance/issubclass that take a tuple
# of types for comparison.
# Deactivated because it can make the code slow:
# https://github.com/astral-sh/ruff/issues/7871
] ]
# Allow fix for all enabled rules (when `--fix`) is provided. # Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"] fixable = ["ALL"]
unfixable = [] unfixable = []
# The fixes in extend-unsafe-fixes will require
# provide the `--unsafe-fixes` flag when fixing.
extend-unsafe-fixes = [
"UP038"
]
# Allow unused variables when underscore-prefixed. # Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

View File

@ -1,50 +1,51 @@
python-slugify==8.0.4 # https://github.com/un33k/python-slugify python-slugify==8.0.4 # https://github.com/un33k/python-slugify
Pillow==10.2.0 # https://github.com/python-pillow/Pillow Pillow==10.4.0 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin rcssmin==1.1.2 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin
{%- else %} {%- else %}
rcssmin==1.1.1 # https://github.com/ndparker/rcssmin rcssmin==1.1.2 # https://github.com/ndparker/rcssmin
{%- endif %} {%- endif %}
{%- endif %} {%- endif %}
argon2-cffi==23.1.0 # https://github.com/hynek/argon2_cffi argon2-cffi==23.1.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %} {%- if cookiecutter.use_whitenoise == 'y' %}
whitenoise==6.6.0 # https://github.com/evansd/whitenoise whitenoise==6.7.0 # https://github.com/evansd/whitenoise
{%- endif %} {%- endif %}
redis==5.0.2 # https://github.com/redis/redis-py redis==5.0.7 # https://github.com/redis/redis-py
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
hiredis==2.3.2 # https://github.com/redis/hiredis-py hiredis==2.3.2 # https://github.com/redis/hiredis-py
{%- endif %} {%- endif %}
{%- if cookiecutter.use_celery == "y" %} {%- if cookiecutter.use_celery == "y" %}
celery==5.3.6 # pyup: < 6.0 # https://github.com/celery/celery celery==5.4.0 # pyup: < 6.0 # https://github.com/celery/celery
django-celery-beat==2.6.0 # https://github.com/celery/django-celery-beat django-celery-beat==2.6.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
flower==2.0.1 # https://github.com/mher/flower flower==2.0.1 # https://github.com/mher/flower
{%- endif %} {%- endif %}
{%- endif %} {%- endif %}
{%- if cookiecutter.use_async == 'y' %} {%- if cookiecutter.use_async == 'y' %}
uvicorn[standard]==0.27.1 # https://github.com/encode/uvicorn uvicorn[standard]==0.30.1 # https://github.com/encode/uvicorn
uvicorn-worker==0.2.0 # https://github.com/Kludex/uvicorn-worker
{%- endif %} {%- endif %}
# Django # Django
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
django==4.2.11 # pyup: < 5.0 # https://www.djangoproject.com/ django==4.2.14 # pyup: < 5.0 # https://www.djangoproject.com/
django-environ==0.11.2 # https://github.com/joke2k/django-environ django-environ==0.11.2 # https://github.com/joke2k/django-environ
django-model-utils==4.4.0 # https://github.com/jazzband/django-model-utils django-model-utils==4.5.1 # https://github.com/jazzband/django-model-utils
django-allauth[mfa]==0.61.1 # https://github.com/pennersr/django-allauth django-allauth[mfa]==0.63.6 # https://github.com/pennersr/django-allauth
django-crispy-forms==2.1 # https://github.com/django-crispy-forms/django-crispy-forms django-crispy-forms==2.2 # https://github.com/django-crispy-forms/django-crispy-forms
crispy-bootstrap5==2024.2 # https://github.com/django-crispy-forms/crispy-bootstrap5 crispy-bootstrap5==2024.2 # https://github.com/django-crispy-forms/crispy-bootstrap5
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
django-compressor==4.4 # https://github.com/django-compressor/django-compressor django-compressor==4.5 # https://github.com/django-compressor/django-compressor
{%- endif %} {%- endif %}
django-redis==5.4.0 # https://github.com/jazzband/django-redis django-redis==5.4.0 # https://github.com/jazzband/django-redis
{%- if cookiecutter.use_drf == 'y' %} {%- if cookiecutter.use_drf == 'y' %}
# Django REST Framework # Django REST Framework
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework djangorestframework==3.15.2 # https://github.com/encode/django-rest-framework
django-cors-headers==4.3.1 # https://github.com/adamchainz/django-cors-headers django-cors-headers==4.4.0 # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation # DRF-spectacular for api documentation
drf-spectacular==0.27.1 # https://github.com/tfranzel/drf-spectacular drf-spectacular==0.27.2 # https://github.com/tfranzel/drf-spectacular
{%- endif %} {%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %}
django-webpack-loader==3.0.1 # https://github.com/django-webpack/django-webpack-loader django-webpack-loader==3.1.0 # https://github.com/django-webpack/django-webpack-loader
{%- endif %} {%- endif %}

View File

@ -1,43 +1,43 @@
-r production.txt -r production.txt
Werkzeug[watchdog]==3.0.1 # https://github.com/pallets/werkzeug Werkzeug[watchdog]==3.0.3 # https://github.com/pallets/werkzeug
ipdb==0.13.13 # https://github.com/gotcha/ipdb ipdb==0.13.13 # https://github.com/gotcha/ipdb
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg psycopg[c]==3.2.1 # https://github.com/psycopg/psycopg
{%- else %} {%- else %}
psycopg[binary]==3.1.18 # https://github.com/psycopg/psycopg psycopg[binary]==3.2.1 # https://github.com/psycopg/psycopg
{%- endif %} {%- endif %}
{%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %}
watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles watchfiles==0.22.0 # https://github.com/samuelcolvin/watchfiles
{%- endif %} {%- endif %}
# Testing # Testing
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
mypy==1.7.1 # https://github.com/python/mypy mypy==1.10.0 # https://github.com/python/mypy
django-stubs[compatible-mypy]==4.2.7 # https://github.com/typeddjango/django-stubs django-stubs[compatible-mypy]==5.0.2 # https://github.com/typeddjango/django-stubs
pytest==8.1.0 # https://github.com/pytest-dev/pytest pytest==8.2.2 # https://github.com/pytest-dev/pytest
pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar
{%- if cookiecutter.use_drf == "y" %} {%- if cookiecutter.use_drf == "y" %}
djangorestframework-stubs[compatible-mypy]==3.14.5 # https://github.com/typeddjango/djangorestframework-stubs djangorestframework-stubs[compatible-mypy]==3.15.0 # https://github.com/typeddjango/djangorestframework-stubs
{%- endif %} {%- endif %}
# Documentation # Documentation
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
sphinx==7.2.6 # https://github.com/sphinx-doc/sphinx sphinx==7.4.5 # https://github.com/sphinx-doc/sphinx
sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild sphinx-autobuild==2024.4.16 # https://github.com/GaretJax/sphinx-autobuild
# Code quality # Code quality
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ruff==0.3.0 # https://github.com/astral-sh/ruff ruff==0.5.2 # https://github.com/astral-sh/ruff
coverage==7.4.3 # https://github.com/nedbat/coveragepy coverage==7.6.0 # https://github.com/nedbat/coveragepy
djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint
pre-commit==3.6.2 # https://github.com/pre-commit/pre-commit pre-commit==3.7.1 # https://github.com/pre-commit/pre-commit
# Django # Django
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
factory-boy==3.3.0 # https://github.com/FactoryBoy/factory_boy factory-boy==3.3.0 # https://github.com/FactoryBoy/factory_boy
django-debug-toolbar==4.3.0 # https://github.com/jazzband/django-debug-toolbar django-debug-toolbar==4.4.6 # https://github.com/jazzband/django-debug-toolbar
django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions
django-coverage-plugin==3.1.0 # https://github.com/nedbat/django_coverage_plugin django-coverage-plugin==3.1.0 # https://github.com/nedbat/django_coverage_plugin
pytest-django==4.8.0 # https://github.com/pytest-dev/pytest-django pytest-django==4.8.0 # https://github.com/pytest-dev/pytest-django

View File

@ -2,13 +2,13 @@
-r base.txt -r base.txt
gunicorn==21.2.0 # https://github.com/benoitc/gunicorn gunicorn==22.0.0 # https://github.com/benoitc/gunicorn
psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg psycopg[c]==3.2.1 # https://github.com/psycopg/psycopg
{%- if cookiecutter.use_whitenoise == 'n' %} {%- if cookiecutter.use_whitenoise == 'n' %}
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast Collectfasta==3.2.0 # https://github.com/jasongi/collectfasta
{%- endif %} {%- endif %}
{%- if cookiecutter.use_sentry == "y" %} {%- if cookiecutter.use_sentry == "y" %}
sentry-sdk==1.40.6 # https://github.com/getsentry/sentry-python sentry-sdk==2.10.0 # https://github.com/getsentry/sentry-python
{%- endif %} {%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
hiredis==2.3.2 # https://github.com/redis/hiredis-py hiredis==2.3.2 # https://github.com/redis/hiredis-py
@ -17,28 +17,28 @@ hiredis==2.3.2 # https://github.com/redis/hiredis-py
# Django # Django
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
{%- if cookiecutter.cloud_provider == 'AWS' %} {%- if cookiecutter.cloud_provider == 'AWS' %}
django-storages[s3]==1.14.2 # https://github.com/jschneier/django-storages django-storages[s3]==1.14.4 # https://github.com/jschneier/django-storages
{%- elif cookiecutter.cloud_provider == 'GCP' %} {%- elif cookiecutter.cloud_provider == 'GCP' %}
django-storages[google]==1.14.2 # https://github.com/jschneier/django-storages django-storages[google]==1.14.4 # https://github.com/jschneier/django-storages
{%- elif cookiecutter.cloud_provider == 'Azure' %} {%- elif cookiecutter.cloud_provider == 'Azure' %}
django-storages[azure]==1.14.2 # https://github.com/jschneier/django-storages django-storages[azure]==1.14.4 # https://github.com/jschneier/django-storages
{%- endif %} {%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %} {%- if cookiecutter.mail_service == 'Mailgun' %}
django-anymail[mailgun]==10.2 # https://github.com/anymail/django-anymail django-anymail[mailgun]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Amazon SES' %} {%- elif cookiecutter.mail_service == 'Amazon SES' %}
django-anymail[amazon-ses]==10.2 # https://github.com/anymail/django-anymail django-anymail[amazon-ses]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mailjet' %} {%- elif cookiecutter.mail_service == 'Mailjet' %}
django-anymail[mailjet]==10.2 # https://github.com/anymail/django-anymail django-anymail[mailjet]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mandrill' %} {%- elif cookiecutter.mail_service == 'Mandrill' %}
django-anymail[mandrill]==10.2 # https://github.com/anymail/django-anymail django-anymail[mandrill]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Postmark' %} {%- elif cookiecutter.mail_service == 'Postmark' %}
django-anymail[postmark]==10.2 # https://github.com/anymail/django-anymail django-anymail[postmark]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Sendgrid' %} {%- elif cookiecutter.mail_service == 'Sendgrid' %}
django-anymail[sendgrid]==10.2 # https://github.com/anymail/django-anymail django-anymail[sendgrid]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SendinBlue' %} {%- elif cookiecutter.mail_service == 'Brevo' %}
django-anymail[sendinblue]==10.2 # https://github.com/anymail/django-anymail django-anymail[brevo]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SparkPost' %} {%- elif cookiecutter.mail_service == 'SparkPost' %}
django-anymail[sparkpost]==10.2 # https://github.com/anymail/django-anymail django-anymail[sparkpost]==11.0.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Other SMTP' %} {%- elif cookiecutter.mail_service == 'Other SMTP' %}
django-anymail==10.2 # https://github.com/anymail/django-anymail django-anymail==11.0.1 # https://github.com/anymail/django-anymail
{%- endif %} {%- endif %}

View File

@ -1 +1 @@
python-3.11.8 python-3.12.3

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -1,7 +1,7 @@
from allauth.account.decorators import secure_admin_login
from django.conf import settings from django.conf import settings
from django.contrib import admin from django.contrib import admin
from django.contrib.auth import admin as auth_admin from django.contrib.auth import admin as auth_admin
from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .forms import UserAdminChangeForm from .forms import UserAdminChangeForm
@ -11,7 +11,8 @@ from .models import User
if settings.DJANGO_ADMIN_FORCE_ALLAUTH: if settings.DJANGO_ADMIN_FORCE_ALLAUTH:
# Force the `admin` sign in process to go through the `django-allauth` workflow: # Force the `admin` sign in process to go through the `django-allauth` workflow:
# https://docs.allauth.org/en/latest/common/admin.html#admin # https://docs.allauth.org/en/latest/common/admin.html#admin
admin.site.login = login_required(admin.site.login) # type: ignore[method-assign] admin.autodiscover()
admin.site.login = secure_admin_login(admin.site.login) # type: ignore[method-assign]
@admin.register(User) @admin.register(User)

View File

@ -10,7 +10,7 @@ from .models import User
class UserAdminChangeForm(admin_forms.UserChangeForm): class UserAdminChangeForm(admin_forms.UserChangeForm):
class Meta(admin_forms.UserChangeForm.Meta): class Meta(admin_forms.UserChangeForm.Meta): # type: ignore[name-defined]
model = User model = User
{%- if cookiecutter.username_type == "email" %} {%- if cookiecutter.username_type == "email" %}
field_classes = {"email": EmailField} field_classes = {"email": EmailField}
@ -23,7 +23,7 @@ class UserAdminCreationForm(admin_forms.UserCreationForm):
To change user signup, see UserSignupForm and UserSocialSignupForm. To change user signup, see UserSignupForm and UserSocialSignupForm.
""" """
class Meta(admin_forms.UserCreationForm.Meta): class Meta(admin_forms.UserCreationForm.Meta): # type: ignore[name-defined]
model = User model = User
{%- if cookiecutter.username_type == "email" %} {%- if cookiecutter.username_type == "email" %}
fields = ("email",) fields = ("email",)

View File

@ -62,7 +62,7 @@ class TestUserAdmin:
# Reload the admin module to apply the setting change # Reload the admin module to apply the setting change
import {{ cookiecutter.project_slug }}.users.admin as users_admin import {{ cookiecutter.project_slug }}.users.admin as users_admin
with contextlib.suppress(admin.sites.AlreadyRegistered): with contextlib.suppress(admin.sites.AlreadyRegistered): # type: ignore[attr-defined]
reload(users_admin) reload(users_admin)
@pytest.mark.django_db() @pytest.mark.django_db()