diff --git a/.flake8 b/.flake8 index 84b4b4411..3a87b269b 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,4 @@ [flake8] exclude = docs max-line-length = 119 +extend-ignore = E203 diff --git a/.github/contributors.json b/.github/contributors.json index 48e9faad3..723c72083 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1453,5 +1453,60 @@ "name": "zhaoruibing", "github_login": "zhaoruibing", "twitter_username": "" + }, + { + "name": "MinWoo Sung", + "github_login": "SungMinWoo", + "twitter_username": "" + }, + { + "name": "itisnotyourenv", + "github_login": "itisnotyourenv", + "twitter_username": "" + }, + { + "name": "Vageeshan Mankala", + "github_login": "vagi8", + "twitter_username": "" + }, + { + "name": "Jakub Boukal", + "github_login": "SukiCZ", + "twitter_username": "" + }, + { + "name": "Christian Jauvin", + "github_login": "cjauvin", + "twitter_username": "" + }, + { + "name": "Plurific", + "github_login": "paulschwenn", + "twitter_username": "" + }, + { + "name": "GitBib", + "github_login": "GitBib", + "twitter_username": "" + }, + { + "name": "Freddy", + "github_login": "Hraesvelg", + "twitter_username": "" + }, + { + "name": "aiden", + "github_login": "anyidea", + "twitter_username": "" + }, + { + "name": "Michael V. Battista", + "github_login": "mvbattista", + "twitter_username": "mvbattista" + }, + { + "name": "Nix Siow", + "github_login": "nixsiow", + "twitter_username": "nixsiow" } ] \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7642a3f2d..e6590469a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,7 +9,7 @@ updates: schedule: interval: "daily" labels: - - "update" + - "project infrastructure" # Update npm packages - package-ecosystem: "npm" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbda77b5e..82f7887f2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,8 +22,8 @@ jobs: name: "pytest ${{ matrix.os }}" runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip @@ -53,8 +53,8 @@ jobs: COMPOSE_DOCKER_CLI_BUILD: 1 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip @@ -75,7 +75,7 @@ jobs: - name: Webpack args: "frontend_pipeline=Webpack use_heroku=y" - name: Email Username - args: "username_type=email ci_tool=Github" + args: "username_type=email ci_tool=Github project_name='Something superduper long - the great amazing project' project_slug=my_awesome_project" name: "Bare metal ${{ matrix.script.name }}" runs-on: ubuntu-latest @@ -97,8 +97,8 @@ jobs: DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres" steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" cache: pip @@ -108,8 +108,8 @@ jobs: {{cookiecutter.project_slug}}/requirements/local.txt - name: Install dependencies run: pip install -r requirements.txt - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: "18" + node-version: "20" - name: Bare Metal ${{ matrix.script.name }} run: sh tests/test_bare.sh ${{ matrix.script.args }} diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml index cbfea922d..e1b36f292 100644 --- a/.github/workflows/django-issue-checker.yml +++ b/.github/workflows/django-issue-checker.yml @@ -16,8 +16,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies diff --git a/.github/workflows/issue-manager.yml b/.github/workflows/issue-manager.yml index a6e074137..e1bb614b1 100644 --- a/.github/workflows/issue-manager.yml +++ b/.github/workflows/issue-manager.yml @@ -23,18 +23,21 @@ jobs: runs-on: ubuntu-latest steps: - - uses: tiangolo/issue-manager@0.4.0 + - uses: tiangolo/issue-manager@0.4.1 with: token: ${{ secrets.GITHUB_TOKEN }} config: > { "answered": { + "delay": 864000, "message": "Assuming the question was answered, this will be automatically closed now." }, "solved": { + "delay": 864000, "message": "Assuming the original issue was solved, it will be automatically closed now." }, "waiting": { + "delay": 864000, "message": "Automatically closing after waiting for additional info. To re-open, please provide the additional information requested." } } diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 75bfe0a20..bfd906cea 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -21,8 +21,8 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index f48f297aa..b0150507d 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -14,10 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml index 78d72c241..0cda836dc 100644 --- a/.github/workflows/update-contributors.yml +++ b/.github/workflows/update-contributors.yml @@ -17,10 +17,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" - name: Install dependencies @@ -33,7 +33,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4.16.0 + uses: stefanzweifel/git-auto-commit-action@v5.0.0 with: commit_message: Update Contributors file_pattern: CONTRIBUTORS.md .github/contributors.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c7afbd52..8c10de974 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,12 @@ exclude: "{{cookiecutter.project_slug}}|.github/contributors.json|CHANGELOG.md|CONTRIBUTORS.md" default_stages: [commit] +default_language_version: + python: python3.11 + repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -17,30 +20,30 @@ repos: - id: detect-private-key - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.1" + rev: "v4.0.0-alpha.8" hooks: - id: prettier args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py311-plus] exclude: hooks/ - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.12.1 hooks: - id: black - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 70c5c84d7..707bef268 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,784 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.01.21 + + +### Documentation + +- Update traefik doc links ([#4798](https://github.com/cookiecutter/cookiecutter-django/pull/4798)) + +### Updated + +- Bump browser-sync from 2.29.3 to 3.0.2 in /{{cookiecutter.project_slug}} ([#4765](https://github.com/cookiecutter/cookiecutter-django/pull/4765)) + +## 2024.01.19 + + +### Updated + +- Update drf-spectacular to 0.27.1 ([#4797](https://github.com/cookiecutter/cookiecutter-django/pull/4797)) + +## 2024.01.17 + + +### Changed + +- Add a test to cover `DJANGO_ADMIN_FORCE_ALLAUTH` ([#4790](https://github.com/cookiecutter/cookiecutter-django/pull/4790)) + +### Updated + +- Bump webpack-bundle-tracker to 3.0.1 ([#4781](https://github.com/cookiecutter/cookiecutter-django/pull/4781)) + +- Update django-webpack-loader to 3.0.1 ([#4793](https://github.com/cookiecutter/cookiecutter-django/pull/4793)) + +- Bump postcss-loader to 8.0.0 ([#4795](https://github.com/cookiecutter/cookiecutter-django/pull/4795)) + +- Update uvicorn to 0.26.0 ([#4794](https://github.com/cookiecutter/cookiecutter-django/pull/4794)) + +## 2024.01.16 + + +### Updated + +- Bump sass-loader from 13.3.3 to 14.0.0 in /{{cookiecutter.project_slug}} ([#4791](https://github.com/cookiecutter/cookiecutter-django/pull/4791)) + +## 2024.01.15 + + +### Documentation + +- Update allauth documentation links ([#4786](https://github.com/cookiecutter/cookiecutter-django/pull/4786)) + +### Updated + +- Update django-allauth to 0.60.1 ([#4787](https://github.com/cookiecutter/cookiecutter-django/pull/4787)) + +## 2024.01.11 + + +### Updated + +- Update jinja2 to 3.1.3 ([#4784](https://github.com/cookiecutter/cookiecutter-django/pull/4784)) + +## 2024.01.10 + + +### Updated + +- Update sentry-sdk to 1.39.2 ([#4782](https://github.com/cookiecutter/cookiecutter-django/pull/4782)) + +## 2024.01.09 + + +### Documentation + +- Update allauth settings documentation links ([#4769](https://github.com/cookiecutter/cookiecutter-django/pull/4769)) + +### Updated + +- Update django-allauth to 0.60.0 ([#4776](https://github.com/cookiecutter/cookiecutter-django/pull/4776)) + +- Update psycopg to 3.1.17 ([#4777](https://github.com/cookiecutter/cookiecutter-django/pull/4777)) + +## 2024.01.05 + + +### Updated + +- Auto-update pre-commit hooks ([#4774](https://github.com/cookiecutter/cookiecutter-django/pull/4774)) + +- Update flake8 to 7.0.0 ([#4775](https://github.com/cookiecutter/cookiecutter-django/pull/4775)) + +## 2024.01.02 + + +### Updated + +- Update psycopg to 3.1.16 ([#4753](https://github.com/cookiecutter/cookiecutter-django/pull/4753)) + +- Update djlint to 1.34.1 ([#4773](https://github.com/cookiecutter/cookiecutter-django/pull/4773)) + +- Update uvicorn to 0.25.0 ([#4760](https://github.com/cookiecutter/cookiecutter-django/pull/4760)) + +- Auto-update pre-commit hooks ([#4749](https://github.com/cookiecutter/cookiecutter-django/pull/4749)) + +- Update black to 23.12.1 ([#4772](https://github.com/cookiecutter/cookiecutter-django/pull/4772)) + +- Update pillow to 10.2.0 ([#4770](https://github.com/cookiecutter/cookiecutter-django/pull/4770)) + +- Update django to 4.2.9 ([#4771](https://github.com/cookiecutter/cookiecutter-django/pull/4771)) + +- Update pytest to 7.4.4 ([#4767](https://github.com/cookiecutter/cookiecutter-django/pull/4767)) + +- Update coverage to 7.4.0 ([#4764](https://github.com/cookiecutter/cookiecutter-django/pull/4764)) + +## 2023.12.19 + + +### Changed + +- Upgrade debian to 12 bookworm ([#4745](https://github.com/cookiecutter/cookiecutter-django/pull/4745)) + +### Updated + +- Update hiredis to 2.3.2 ([#4750](https://github.com/cookiecutter/cookiecutter-django/pull/4750)) + +## 2023.12.15 + + +### Updated + +- Update coverage to 7.3.3 ([#4748](https://github.com/cookiecutter/cookiecutter-django/pull/4748)) + +- Update psycopg to 3.1.15 ([#4747](https://github.com/cookiecutter/cookiecutter-django/pull/4747)) + +- Update sentry-sdk to 1.39.1 ([#4746](https://github.com/cookiecutter/cookiecutter-django/pull/4746)) + +- Auto-update pre-commit hooks ([#4743](https://github.com/cookiecutter/cookiecutter-django/pull/4743)) + +## 2023.12.13 + + +### Updated + +- Auto-update pre-commit hooks ([#4740](https://github.com/cookiecutter/cookiecutter-django/pull/4740)) + +## 2023.12.12 + + +### Updated + +- Update django-allauth to 0.59.0 ([#4739](https://github.com/cookiecutter/cookiecutter-django/pull/4739)) + +- Update sentry-sdk to 1.39.0 ([#4738](https://github.com/cookiecutter/cookiecutter-django/pull/4738)) + +- Update black to 23.12.0 ([#4737](https://github.com/cookiecutter/cookiecutter-django/pull/4737)) + +- Auto-update pre-commit hooks ([#4736](https://github.com/cookiecutter/cookiecutter-django/pull/4736)) + +- Update drf-spectacular to 0.27.0 ([#4735](https://github.com/cookiecutter/cookiecutter-django/pull/4735)) + +## 2023.12.11 + + +### Updated + +- Auto-update pre-commit hooks ([#4730](https://github.com/cookiecutter/cookiecutter-django/pull/4730)) + +## 2023.12.10 + + +### Updated + +- Update pre-commit to 3.6.0 ([#4728](https://github.com/cookiecutter/cookiecutter-django/pull/4728)) + +- Auto-update pre-commit hooks ([#4729](https://github.com/cookiecutter/cookiecutter-django/pull/4729)) + +## 2023.12.09 + + +### Changed + +- Add missing __init__.py file to api module ([#4726](https://github.com/cookiecutter/cookiecutter-django/pull/4726)) + +## 2023.12.07 + + +### Updated + +- Bump actions/setup-python from 4 to 5 ([#4723](https://github.com/cookiecutter/cookiecutter-django/pull/4723)) + +- Auto-update pre-commit hooks ([#4709](https://github.com/cookiecutter/cookiecutter-django/pull/4709)) + +- Bump traefik from 2.10.6 to 2.10.7 ([#4722](https://github.com/cookiecutter/cookiecutter-django/pull/4722)) + +## 2023.12.06 + + +### Updated + +- Bump python from 3.11.6 to 3.11.7 ([#4719](https://github.com/cookiecutter/cookiecutter-django/pull/4719)) + +- Update mypy to 1.7.1, django-stubs to 4.2.7 and djangorestframework-stubs to 3.14.5 ([#4694](https://github.com/cookiecutter/cookiecutter-django/pull/4694)) + +## 2023.12.04 + + +### Updated + +- Update django to 4.2.8 ([#4713](https://github.com/cookiecutter/cookiecutter-django/pull/4713)) + +- Bump node from 18 to 20 ([#4283](https://github.com/cookiecutter/cookiecutter-django/pull/4283)) + +- Update psycopg to 3.1.14 ([#4711](https://github.com/cookiecutter/cookiecutter-django/pull/4711)) + +## 2023.12.02 + + +### Updated + +- Update mailpit to latest ([#4710](https://github.com/cookiecutter/cookiecutter-django/pull/4710)) + +## 2023.11.30 + + +### Fixed + +- Removed tmp mount in devcontainer.json. Fix #4686 ([#4708](https://github.com/cookiecutter/cookiecutter-django/pull/4708)) + +### Updated + +- Bump traefik from 2.10.5 to 2.10.6 ([#4706](https://github.com/cookiecutter/cookiecutter-django/pull/4706)) + +## 2023.11.29 + + +### Updated + +- Update sentry-sdk to 1.38.0 ([#4705](https://github.com/cookiecutter/cookiecutter-django/pull/4705)) + +## 2023.11.28 + + +### Fixed + +- Excludes devcontainer.json from the pre-commit ([#4702](https://github.com/cookiecutter/cookiecutter-django/pull/4702)) + +### Updated + +- Update sphinx-rtd-theme to 2.0.0 ([#4700](https://github.com/cookiecutter/cookiecutter-django/pull/4700)) + +## 2023.11.24 + + +### Updated + +- Update sentry-sdk to 1.37.1 ([#4696](https://github.com/cookiecutter/cookiecutter-django/pull/4696)) + +- Update sentry-sdk to 1.37.0 ([#4695](https://github.com/cookiecutter/cookiecutter-django/pull/4695)) + +## 2023.11.22 + + +### Updated + +- Update celery to 5.3.6 ([#4693](https://github.com/cookiecutter/cookiecutter-django/pull/4693)) + +## 2023.11.21 + + +### Updated + +- Update sentry-sdk to 1.36.0 ([#4687](https://github.com/cookiecutter/cookiecutter-django/pull/4687)) + +## 2023.11.20 + + +### Fixed + +- Fix bug with social account adapter name override, in very specific conditions ([#4650](https://github.com/cookiecutter/cookiecutter-django/pull/4650)) + +### Updated + +- Update django-cors-headers to 4.3.1 ([#4684](https://github.com/cookiecutter/cookiecutter-django/pull/4684)) + +- Update psycopg to 3.1.13 ([#4685](https://github.com/cookiecutter/cookiecutter-django/pull/4685)) + +## 2023.11.14 + + +### Updated + +- Update sentry-sdk to 1.35.0 ([#4681](https://github.com/cookiecutter/cookiecutter-django/pull/4681)) + +- Auto-update pre-commit hooks ([#4683](https://github.com/cookiecutter/cookiecutter-django/pull/4683)) + +## 2023.11.11 + + +### Updated + +- Update celery to 5.3.5 ([#4678](https://github.com/cookiecutter/cookiecutter-django/pull/4678)) + +## 2023.11.09 + + +### Updated + +- Auto-update pre-commit hooks ([#4673](https://github.com/cookiecutter/cookiecutter-django/pull/4673)) + +- Update black to 23.11.0 ([#4674](https://github.com/cookiecutter/cookiecutter-django/pull/4674)) + +## 2023.11.08 + + +### Updated + +- Update pytest-django to 4.7.0 ([#4672](https://github.com/cookiecutter/cookiecutter-django/pull/4672)) + +## 2023.11.06 + + +### Changed + +- Add `rmbackup` script to remove backups from `postgres/backups`. Fixes: #4663 ([#4664](https://github.com/cookiecutter/cookiecutter-django/pull/4664)) + +### Updated + +- Update django-allauth to 0.58.2 ([#4667](https://github.com/cookiecutter/cookiecutter-django/pull/4667)) + +- Update uvicorn to 0.24.0.post1 ([#4666](https://github.com/cookiecutter/cookiecutter-django/pull/4666)) + +## 2023.11.04 + + +### Updated + +- Update uvicorn to 0.24.0 ([#4665](https://github.com/cookiecutter/cookiecutter-django/pull/4665)) + +## 2023.11.03 + + +### Updated + +- Update flake8-isort to 6.1.1 ([#4662](https://github.com/cookiecutter/cookiecutter-django/pull/4662)) + +## 2023.11.02 + + +### Updated + +- Update sentry-sdk to 1.34.0 ([#4660](https://github.com/cookiecutter/cookiecutter-django/pull/4660)) + +## 2023.11.01 + + +### Updated + +- Update django to 4.2.7 ([#4658](https://github.com/cookiecutter/cookiecutter-django/pull/4658)) + +- Update django-stubs to 4.2.6 ([#4657](https://github.com/cookiecutter/cookiecutter-django/pull/4657)) + +## 2023.10.31 + + +### Updated + +- Update pytest-django to 4.6.0 ([#4656](https://github.com/cookiecutter/cookiecutter-django/pull/4656)) + +- Update pytest to 7.4.3 ([#4654](https://github.com/cookiecutter/cookiecutter-django/pull/4654)) + +- Update werkzeug to 3.0.1 ([#4655](https://github.com/cookiecutter/cookiecutter-django/pull/4655)) + +- Update sentry-sdk to 1.33.1 ([#4653](https://github.com/cookiecutter/cookiecutter-django/pull/4653)) + +- Update sentry-sdk to 1.33.0 ([#4652](https://github.com/cookiecutter/cookiecutter-django/pull/4652)) + +- Update crispy-bootstrap5 to 2023.10 ([#4651](https://github.com/cookiecutter/cookiecutter-django/pull/4651)) + +## 2023.10.26 + + +### Updated + +- Update django-anymail to 10.2 ([#4645](https://github.com/cookiecutter/cookiecutter-django/pull/4645)) + +## 2023.10.24 + + +### Updated + +- Update black to 23.10.1 ([#4639](https://github.com/cookiecutter/cookiecutter-django/pull/4639)) + +- Auto-update pre-commit hooks ([#4641](https://github.com/cookiecutter/cookiecutter-django/pull/4641)) + +## 2023.10.23 + + +### Updated + +- Update pylint-django to 2.5.5 ([#4638](https://github.com/cookiecutter/cookiecutter-django/pull/4638)) + +## 2023.10.19 + + +### Updated + +- Update mypy to 1.6.1 ([#4634](https://github.com/cookiecutter/cookiecutter-django/pull/4634)) + +- Update djangorestframework-stubs to 3.14.4 ([#4637](https://github.com/cookiecutter/cookiecutter-django/pull/4637)) + +- Update django-stubs to 4.2.5 ([#4636](https://github.com/cookiecutter/cookiecutter-django/pull/4636)) + +## 2023.10.17 + + +### Updated + +- Auto-update pre-commit hooks ([#4633](https://github.com/cookiecutter/cookiecutter-django/pull/4633)) + +- Update black to 23.10.0 ([#4632](https://github.com/cookiecutter/cookiecutter-django/pull/4632)) + +- Update pillow to 10.1.0 ([#4630](https://github.com/cookiecutter/cookiecutter-django/pull/4630)) + +- Update django-crispy-forms to 2.1 ([#4629](https://github.com/cookiecutter/cookiecutter-django/pull/4629)) + +## 2023.10.13 + + +### Updated + +- Update pre-commit to 3.5.0 ([#4628](https://github.com/cookiecutter/cookiecutter-django/pull/4628)) + +- Update watchfiles to 0.21.0 ([#4627](https://github.com/cookiecutter/cookiecutter-django/pull/4627)) + +## 2023.10.12 + + +### Updated + +- Update django-cors-headers to 4.3.0 ([#4625](https://github.com/cookiecutter/cookiecutter-django/pull/4625)) + +- Update whitenoise to 6.6.0 ([#4624](https://github.com/cookiecutter/cookiecutter-django/pull/4624)) + +- Update sentry-sdk to 1.32.0 ([#4623](https://github.com/cookiecutter/cookiecutter-django/pull/4623)) + +- Bump traefik from 2.10.4 to 2.10.5 ([#4626](https://github.com/cookiecutter/cookiecutter-django/pull/4626)) + +## 2023.10.09 + + +### Updated + +- Bump stefanzweifel/git-auto-commit-action from 4.16.0 to 5.0.0 ([#4621](https://github.com/cookiecutter/cookiecutter-django/pull/4621)) + +- Update django-storages to 1.14.2 ([#4620](https://github.com/cookiecutter/cookiecutter-django/pull/4620)) + +## 2023.10.08 + + +### Updated + +- Auto-update pre-commit hooks ([#4619](https://github.com/cookiecutter/cookiecutter-django/pull/4619)) + +## 2023.10.05 + + +### Updated + +- Update djangorestframework-stubs to 3.14.3 ([#4618](https://github.com/cookiecutter/cookiecutter-django/pull/4618)) + +- Update django-stubs to 4.2.4 ([#4566](https://github.com/cookiecutter/cookiecutter-django/pull/4566)) + +- Update mypy to 1.5.1 ([#4568](https://github.com/cookiecutter/cookiecutter-django/pull/4568)) + +## 2023.10.04 + + +### Updated + +- Update django to 4.2.6 ([#4617](https://github.com/cookiecutter/cookiecutter-django/pull/4617)) + +- Update coverage to 7.3.2 ([#4616](https://github.com/cookiecutter/cookiecutter-django/pull/4616)) + +- Update werkzeug to 3.0.0 ([#4608](https://github.com/cookiecutter/cookiecutter-django/pull/4608)) + +- Update django-redis to 5.4.0 ([#4609](https://github.com/cookiecutter/cookiecutter-django/pull/4609)) + +- Bump docs Python docker image from 3.11.5 to 3.11.6 ([#4615](https://github.com/cookiecutter/cookiecutter-django/pull/4615)) + +## 2023.10.03 + + +### Changed + +- [pre-commit.ci] pre-commit autoupdate ([#4613](https://github.com/cookiecutter/cookiecutter-django/pull/4613)) + +### Updated + +- Bump prod Python docker image from 3.11.5 to 3.11.6 ([#4611](https://github.com/cookiecutter/cookiecutter-django/pull/4611)) + +- Bump local Python docker image from 3.11.5 to 3.11.6 ([#4612](https://github.com/cookiecutter/cookiecutter-django/pull/4612)) + +- Auto-update pre-commit hooks ([#4610](https://github.com/cookiecutter/cookiecutter-django/pull/4610)) + +## 2023.09.29 + + +### Updated + +- Update django-storages to 1.14.1 ([#4604](https://github.com/cookiecutter/cookiecutter-django/pull/4604)) + +## 2023.09.28 + + +### Updated + +- Update psycopg to 3.1.12 ([#4601](https://github.com/cookiecutter/cookiecutter-django/pull/4601)) + +## 2023.09.27 + + +### Fixed + +- Fix ownership for /start-flower script in production Dockerfile ([#4603](https://github.com/cookiecutter/cookiecutter-django/pull/4603)) + +## 2023.09.26 + + +### Updated + +- Update redis to 5.0.1 ([#4600](https://github.com/cookiecutter/cookiecutter-django/pull/4600)) + +## 2023.09.25 + + +### Updated + +- Update django-upgrade to 1.15.0 ([#4598](https://github.com/cookiecutter/cookiecutter-django/pull/4598)) + +- Update django-allauth to 0.57.0 ([#4597](https://github.com/cookiecutter/cookiecutter-django/pull/4597)) + +- Auto-update pre-commit hooks ([#4596](https://github.com/cookiecutter/cookiecutter-django/pull/4596)) + +## 2023.09.23 + + +### Updated + +- Update psycopg to 3.1.11 ([#4595](https://github.com/cookiecutter/cookiecutter-django/pull/4595)) + +- Auto-update pre-commit hooks ([#4591](https://github.com/cookiecutter/cookiecutter-django/pull/4591)) + +- Update drf-spectacular to 0.26.5 ([#4594](https://github.com/cookiecutter/cookiecutter-django/pull/4594)) + +## 2023.09.21 + + +### Updated + +- Auto-update pre-commit hooks ([#4589](https://github.com/cookiecutter/cookiecutter-django/pull/4589)) + +- Update djlint to 1.34.0 ([#4590](https://github.com/cookiecutter/cookiecutter-django/pull/4590)) + +## 2023.09.19 + + +### Updated + +- Auto-update pre-commit hooks ([#4588](https://github.com/cookiecutter/cookiecutter-django/pull/4588)) + +- Update djlint to 1.33.0 ([#4587](https://github.com/cookiecutter/cookiecutter-django/pull/4587)) + +## 2023.09.16 + + +### Updated + +- Auto-update pre-commit hooks ([#4586](https://github.com/cookiecutter/cookiecutter-django/pull/4586)) + +## 2023.09.15 + + +### Updated + +- Update flake8-isort to 6.1.0 ([#4585](https://github.com/cookiecutter/cookiecutter-django/pull/4585)) + +- Update pillow to 10.0.1 ([#4584](https://github.com/cookiecutter/cookiecutter-django/pull/4584)) + +## 2023.09.14 + + +### Updated + +- Update sphinx to 7.2.6 ([#4583](https://github.com/cookiecutter/cookiecutter-django/pull/4583)) + +## 2023.09.13 + + +### Updated + +- Update sentry-sdk to 1.31.0 ([#4582](https://github.com/cookiecutter/cookiecutter-django/pull/4582)) + +## 2023.09.12 + + +### Updated + +- Update django-storages to 1.14 ([#4564](https://github.com/cookiecutter/cookiecutter-django/pull/4564)) + +## 2023.09.11 + + +### Updated + +- Auto-update pre-commit hooks ([#4579](https://github.com/cookiecutter/cookiecutter-django/pull/4579)) + +- Update black to 23.9.1 ([#4580](https://github.com/cookiecutter/cookiecutter-django/pull/4580)) + +- Update django-allauth to 0.56.1 ([#4576](https://github.com/cookiecutter/cookiecutter-django/pull/4576)) + +## 2023.09.08 + + +### Updated + +- Update pytest to 7.4.2 ([#4573](https://github.com/cookiecutter/cookiecutter-django/pull/4573)) + +## 2023.09.07 + + +### Updated + +- Update django-allauth to 0.56.0 ([#4571](https://github.com/cookiecutter/cookiecutter-django/pull/4571)) + +## 2023.09.06 + + +### Changed + +- Replace Mailhog with Mailpit ([#4551](https://github.com/cookiecutter/cookiecutter-django/pull/4551)) + +### Updated + +- Update sphinx to 7.2.5 ([#4569](https://github.com/cookiecutter/cookiecutter-django/pull/4569)) + +- Bump actions/checkout from 3 to 4 ([#4565](https://github.com/cookiecutter/cookiecutter-django/pull/4565)) + +- Update coverage to 7.3.1 ([#4567](https://github.com/cookiecutter/cookiecutter-django/pull/4567)) + +## 2023.09.04 + + +### Updated + +- Update django to 4.2.5 ([#4563](https://github.com/cookiecutter/cookiecutter-django/pull/4563)) + +## 2023.09.03 + + +### Updated + +- Update celery to 5.3.4 ([#4562](https://github.com/cookiecutter/cookiecutter-django/pull/4562)) + +## 2023.09.02 + + +### Updated + +- Update pytest to 7.4.1 ([#4561](https://github.com/cookiecutter/cookiecutter-django/pull/4561)) + +- Update pre-commit to 3.4.0 ([#4560](https://github.com/cookiecutter/cookiecutter-django/pull/4560)) + +- Update django-environ to 0.11.2 ([#4558](https://github.com/cookiecutter/cookiecutter-django/pull/4558)) + +## 2023.09.01 + + +## 2023.08.31 + + +### Updated + +- Auto-update pre-commit hooks ([#4550](https://github.com/cookiecutter/cookiecutter-django/pull/4550)) + +- Update django-allauth to 0.55.2 ([#4549](https://github.com/cookiecutter/cookiecutter-django/pull/4549)) + +- Update celery to 5.3.3 ([#4553](https://github.com/cookiecutter/cookiecutter-django/pull/4553)) + +## 2023.08.30 + + +### Updated + +- Update django-environ to 0.11.0 ([#4548](https://github.com/cookiecutter/cookiecutter-django/pull/4548)) + +## 2023.08.29 + + +### Updated + +- Update sentry-sdk to 1.30.0 ([#4546](https://github.com/cookiecutter/cookiecutter-django/pull/4546)) + +## 2023.08.28 + + +### Changed + +- Add French translations ([#4454](https://github.com/cookiecutter/cookiecutter-django/pull/4454)) + +- Change `MEDIA_URL` to an absolute URL in tests ([#4460](https://github.com/cookiecutter/cookiecutter-django/pull/4460)) + +### Fixed + +- Fix a small compatibility issue between black and flake8 ([#4541](https://github.com/cookiecutter/cookiecutter-django/pull/4541)) + +### Updated + +- Update django-allauth to 0.55.0 ([#4535](https://github.com/cookiecutter/cookiecutter-django/pull/4535)) + +- Update watchfiles to 0.20.0 ([#4537](https://github.com/cookiecutter/cookiecutter-django/pull/4537)) + +- Update Python version from 3.11.4 to 3.11.5 ([#4542](https://github.com/cookiecutter/cookiecutter-django/pull/4542)) + +## 2023.08.19 + + +### Changed + +- Override `_after_postgeneration` to force save in `UserFactory` ([#4534](https://github.com/cookiecutter/cookiecutter-django/pull/4534)) + +## 2023.08.17 + + +### Updated + +- Update argon2-cffi to 23.1.0 ([#4527](https://github.com/cookiecutter/cookiecutter-django/pull/4527)) + +- Auto-update pre-commit hooks ([#4530](https://github.com/cookiecutter/cookiecutter-django/pull/4530)) + +## 2023.08.16 + + +### Updated + +- Update django-upgrade to 1.14.1 ([#4528](https://github.com/cookiecutter/cookiecutter-django/pull/4528)) + +## 2023.08.15 + + +### Updated + +- Update redis to 5.0.0 ([#4526](https://github.com/cookiecutter/cookiecutter-django/pull/4526)) + +## 2023.08.14 + + +### Changed + +- Install Django and DRF stubs with `compatible-mypy` extra (as per offical recommendation) ([#4361](https://github.com/cookiecutter/cookiecutter-django/pull/4361)) + +- Fix `overrideCommand` value in `devcontainer` so that the `django` container can run (#4517) ([#4517](https://github.com/cookiecutter/cookiecutter-django/pull/4517)) + +### Fixed + +- Prevent error in data migration caused by long project name ([#4525](https://github.com/cookiecutter/cookiecutter-django/pull/4525)) + +- Remove unused gulp-concat when Webpack is selected ([#4520](https://github.com/cookiecutter/cookiecutter-django/pull/4520)) + +- Exclude env files from container image (add .envs/ to .dockerignore) ([#4476](https://github.com/cookiecutter/cookiecutter-django/pull/4476)) + +### Updated + +- Update werkzeug to 2.3.7 ([#4521](https://github.com/cookiecutter/cookiecutter-django/pull/4521)) + +- Update coverage to 7.3.0 ([#4516](https://github.com/cookiecutter/cookiecutter-django/pull/4516)) + +- Update django-debug-toolbar to 4.2.0 ([#4511](https://github.com/cookiecutter/cookiecutter-django/pull/4511)) + +- Update flower to 2.0.1 ([#4518](https://github.com/cookiecutter/cookiecutter-django/pull/4518)) + ## 2023.08.10 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 38fc87e9b..9a384d141 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -194,6 +194,13 @@ Listed in alphabetical order. scaramagus + + aiden + + anyidea + + + Alberto Sanchez @@ -509,6 +516,13 @@ Listed in alphabetical order. + + Christian Jauvin + + cjauvin + + + Christopher Clarke @@ -824,6 +838,13 @@ Listed in alphabetical order. + + Freddy + + Hraesvelg + + + Fuzzwah @@ -866,6 +887,13 @@ Listed in alphabetical order. + + GitBib + + GitBib + + + Glenn Wiskur @@ -999,6 +1027,13 @@ Listed in alphabetical order. + + itisnotyourenv + + itisnotyourenv + + + Ivan Khomutov @@ -1006,6 +1041,13 @@ Listed in alphabetical order. + + Jakub Boukal + + SukiCZ + + + Jakub Musko @@ -1454,6 +1496,13 @@ Listed in alphabetical order. + + Michael V. Battista + + mvbattista + + mvbattista + Mike97M @@ -1468,6 +1517,13 @@ Listed in alphabetical order. + + MinWoo Sung + + SungMinWoo + + + monosans @@ -1524,6 +1580,13 @@ Listed in alphabetical order. + + Nix Siow + + nixsiow + + nixsiow + Noah H @@ -1622,6 +1685,13 @@ Listed in alphabetical order. + + Plurific + + paulschwenn + + + Raony Guimarães Corrêa @@ -1930,6 +2000,13 @@ Listed in alphabetical order. egregors + + Vageeshan Mankala + + vagi8 + + + vascop diff --git a/README.md b/README.md index 7f2c358e7..a9bf1990f 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ _These features can be enabled during initial project setup._ - Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) - Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) -- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing +- Integration with [Mailpit](https://github.com/axllent/mailpit/) for local email testing - Integration with [Sentry](https://sentry.io/welcome/) for error logging ## Constraints @@ -165,7 +165,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re 4 - Webpack Choose from 1, 2, 3, 4 [1]: 1 use_celery [n]: y - use_mailhog [n]: n + use_mailpit [n]: n use_sentry [n]: y use_whitenoise [n]: n use_heroku [n]: y @@ -204,6 +204,8 @@ For local development, see the following: - If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues). - For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a). +Contributors + ## For Readers of Two Scoops of Django You may notice that some elements of this project do not exactly match what we describe in chapter 3. 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. diff --git a/cookiecutter.json b/cookiecutter.json index f66e281f5..e343617d1 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -35,7 +35,7 @@ "use_drf": "n", "frontend_pipeline": ["None", "Django Compressor", "Gulp", "Webpack"], "use_celery": "n", - "use_mailhog": "n", + "use_mailpit": "n", "use_sentry": "n", "use_whitenoise": "n", "use_heroku": "n", diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index 6af4fe7c2..a8f945adf 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -191,16 +191,16 @@ The ``container_name`` from the yml file can be used to check on containers with Notice that the ``container_name`` is generated dynamically using your project slug as a prefix -Mailhog +Mailpit ~~~~~~~ -When developing locally you can go with MailHog_ for email testing provided ``use_mailhog`` was set to ``y`` on setup. To proceed, +When developing locally you can go with Mailpit_ for email testing provided ``use_mailpit`` was set to ``y`` on setup. To proceed, -#. make sure ``_local_mailhog`` container is up and running; +#. make sure ``_local_mailpit`` container is up and running; #. open up ``http://127.0.0.1:8025``. -.. _Mailhog: https://github.com/mailhog/MailHog/ +.. _Mailpit: https://github.com/axllent/mailpit/ .. _`CeleryTasks`: diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst index 88c8b3206..92379f4fd 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -99,39 +99,37 @@ First things first. Setup Email Backend ------------------- -MailHog +Mailpit ~~~~~~~ -.. note:: In order for the project to support MailHog_ it must have been bootstrapped with ``use_mailhog`` set to ``y``. +.. note:: In order for the project to support Mailpit_ it must have been bootstrapped with ``use_mailpit`` set to ``y``. -MailHog is used to receive emails during development, it is written in Go and has no external dependencies. +Mailpit is used to receive emails during development, it is written in Go and has no external dependencies. For instance, one of the packages we depend upon, ``django-allauth`` sends verification emails to new users signing up as well as to the existing ones who have not yet verified themselves. -#. `Download the latest MailHog release`_ for your OS. +#. `Download the latest Mailpit release`_ for your OS. -#. Rename the build to ``MailHog``. - -#. Copy the file to the project root. +#. Copy the binary file to the project root. #. Make it executable: :: - $ chmod +x MailHog + $ chmod +x mailpit #. Spin up another terminal window and start it there: :: - ./MailHog + ./mailpit #. Check out ``_ to see how it goes. Now you have your own mail server running locally, ready to receive whatever you send it. -.. _`Download the latest MailHog release`: https://github.com/mailhog/MailHog +.. _`Download the latest Mailpit release`: https://github.com/axllent/mailpit Console ~~~~~~~ -.. note:: If you have generated your project with ``use_mailhog`` set to ``n`` this will be a default setup. +.. note:: If you have generated your project with ``use_mailpit`` set to ``n`` this will be a default setup. Alternatively, deliver emails over console via ``EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'``. diff --git a/docs/docker-postgres-backups.rst b/docs/docker-postgres-backups.rst index c40b6fd69..fdf446030 100644 --- a/docs/docker-postgres-backups.rst +++ b/docs/docker-postgres-backups.rst @@ -92,7 +92,15 @@ You will see something like :: 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. :: $ docker compose -f production.yml run --rm awscli upload $ docker compose -f production.yml run --rm awscli download backup_2018_03_13T09_05_07.sql.gz + +Remove Backup +---------------------------------- + +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 diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index bd368ae84..967b42426 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -115,8 +115,8 @@ Both Gulp and Webpack support Bootstrap recompilation with real-time variables a use_celery: Indicates whether the project should be configured to use Celery_. -use_mailhog: - Indicates whether the project should be configured to use MailHog_. +use_mailpit: + Indicates whether the project should be configured to use Mailpit_. use_sentry: Indicates whether the project should be configured to use Sentry_. @@ -185,7 +185,7 @@ debug: .. _Celery: https://github.com/celery/celery -.. _MailHog: https://github.com/mailhog/MailHog +.. _Mailpit: https://github.com/axllent/mailpit .. _Sentry: https://github.com/getsentry/sentry diff --git a/docs/requirements.txt b/docs/requirements.txt index d06b651b3..d002affa7 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx==6.2.1 -sphinx-rtd-theme==1.2.2 +sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 myst-parser==2.0.0 diff --git a/requirements.txt b/requirements.txt index fbe8dfdeb..aadf4abb1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,28 +1,28 @@ -cookiecutter==2.3.0 +cookiecutter==2.5.0 sh==2.0.6; sys_platform != "win32" binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==23.7.0 -isort==5.12.0 -flake8==6.1.0 -django-upgrade==1.14.0 -djlint==1.32.1 -pre-commit==3.3.3 +black==23.12.1 +isort==5.13.2 +flake8==7.0.0 +django-upgrade==1.15.0 +djlint==1.34.1 +pre-commit==3.6.0 # Testing # ------------------------------------------------------------------------------ -tox==4.8.0 -pytest==7.4.0 -pytest-xdist==3.3.1 +tox==4.12.1 +pytest==7.4.4 +pytest-xdist==3.5.0 pytest-cookies==0.7.0 pytest-instafail==0.5.0 pyyaml==6.0.1 # Scripting # ------------------------------------------------------------------------------ -PyGithub==1.59.1 -gitpython==3.1.32 -jinja2==3.1.2 +PyGithub==2.1.1 +gitpython==3.1.41 +jinja2==3.1.3 requests==2.31.0 diff --git a/scripts/create_django_issue.py b/scripts/create_django_issue.py index 236a126fb..f9ff76545 100644 --- a/scripts/create_django_issue.py +++ b/scripts/create_django_issue.py @@ -212,7 +212,7 @@ class GitHubManager: for classifier in package_info["info"]["classifiers"]: # Usually in the form of "Framework :: Django :: 3.2" tokens = classifier.split(" ") - if len(tokens) >= 5 and tokens[2].lower() == "django": + if len(tokens) >= 5 and tokens[2].lower() == "django" and "." in tokens[4]: version = DjVersion.parse(tokens[4]) if len(version) == 2: supported_dj_versions.append(version) diff --git a/scripts/update_changelog.py b/scripts/update_changelog.py index 7d43a0b57..5f3ad5ec3 100644 --- a/scripts/update_changelog.py +++ b/scripts/update_changelog.py @@ -32,6 +32,9 @@ def main() -> None: # Group pull requests by type of change grouped_pulls = group_pulls_by_change_type(merged_pulls) + if not any(grouped_pulls.values()): + print("Pull requests merged aren't worth a changelog mention.") + return # Generate portion of markdown release_changes_summary = generate_md(grouped_pulls) diff --git a/setup.py b/setup.py index 34983e0b7..8aa7a43bb 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2023.08.10" +version = "2024.01.21" with open("README.md") as readme_file: long_description = readme_file.read() diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 87e52ef01..31d006bed 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -115,8 +115,8 @@ SUPPORTED_COMBINATIONS = [ {"frontend_pipeline": "Webpack"}, {"use_celery": "y"}, {"use_celery": "n"}, - {"use_mailhog": "y"}, - {"use_mailhog": "n"}, + {"use_mailpit": "y"}, + {"use_mailpit": "n"}, {"use_sentry": "y"}, {"use_sentry": "n"}, {"use_whitenoise": "y"}, diff --git a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json index 393408582..c4158dc10 100644 --- a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json +++ b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json @@ -11,11 +11,6 @@ "target": "/home/dev-user/.bash_history", "type": "bind" }, - { - "source": "/tmp", - "target": "/tmp", - "type": "bind" - }, { "source": "~/.ssh", "target": "/home/dev-user/.ssh", diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 3a863ccb9..e39933fe1 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 {%- if cookiecutter.use_docker == 'y' %} - name: Build the Stack diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 541f40846..0bb322186 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -329,8 +329,8 @@ tags dump.rdb ### Project template -{%- if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' %} -MailHog +{%- if cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'n' %} +mailpit {%- endif %} {{ cookiecutter.project_slug }}/media/ diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index dcf5ec209..c0e1db7ca 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -1,9 +1,12 @@ -exclude: '^docs/|/migrations/' +exclude: '^docs/|/migrations/|devcontainer.json' default_stages: [commit] +default_language_version: + python: python3.11 + repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -18,41 +21,41 @@ repos: - id: detect-private-key - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.1 + rev: v4.0.0-alpha.8 hooks: - id: prettier args: ['--tab-width', '2', '--single-quote'] exclude: '{{cookiecutter.project_slug}}/templates/' - repo: https://github.com/adamchainz/django-upgrade - rev: '1.14.0' + rev: '1.15.0' hooks: - id: django-upgrade args: ['--target-version', '4.2'] - repo: https://github.com/asottile/pyupgrade - rev: v3.10.1 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py311-plus] - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.12.1 hooks: - id: black - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/Riverside-Healthcare/djLint - rev: v1.32.1 + rev: v1.34.1 hooks: - id: djlint-reformat-django - id: djlint-django diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index 56853f8f7..ccf245a2f 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -78,37 +78,35 @@ celery -A config.celery_app worker -B -l info ``` {%- endif %} -{%- if cookiecutter.use_mailhog == "y" %} +{%- if cookiecutter.use_mailpit == "y" %} ### Email Server {%- if cookiecutter.use_docker == "y" %} -In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server [MailHog](https://github.com/mailhog/MailHog) with a web interface is available as docker container. +In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server [Mailpit](https://github.com/axllent/mailpit) with a web interface is available as docker container. -Container mailhog will start automatically when you will run all docker containers. +Container mailpit will start automatically when you will run all docker containers. Please check [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html) for more details how to start all containers. -With MailHog running, to view messages that are sent by your application, open your browser and go to `http://127.0.0.1:8025` +With Mailpit running, to view messages that are sent by your application, open your browser and go to `http://127.0.0.1:8025` {%- else %} -In development, it is often nice to be able to see emails that are being sent from your application. If you choose to use [MailHog](https://github.com/mailhog/MailHog) when generating the project a local SMTP server with a web interface will be available. +In development, it is often nice to be able to see emails that are being sent from your application. If you choose to use [Mailpit](https://github.com/axllent/mailpit) when generating the project a local SMTP server with a web interface will be available. -1. [Download the latest MailHog release](https://github.com/mailhog/MailHog/releases) for your OS. +1. [Download the latest Mailpit release](https://github.com/axllent/mailpit/releases) for your OS. -2. Rename the build to `MailHog`. +2. Copy the binary file to the project root. -3. Copy the file to the project root. +3. Make it executable: -4. Make it executable: + $ chmod +x mailpit - $ chmod +x MailHog +4. Spin up another terminal window and start it there: -5. Spin up another terminal window and start it there: + ./mailpit - ./MailHog - -6. Check out to see how it goes. +5. Check out to see how it goes. Now you have your own mail server running locally, ready to receive whatever you send it. diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index 3636ce1ef..703474a6f 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.7-slim-bookworm as python # Python build stage FROM python as python-build-stage diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index f9895a083..41ab15b9f 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.7-slim-bookworm as python # Python build stage diff --git a/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile index 707ed0c9d..41f42b625 100644 --- a/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-bullseye-slim +FROM node:20-bookworm-slim WORKDIR /app diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index a48cbc4af..e0da6063c 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -1,5 +1,5 @@ {% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%} -FROM node:18-bullseye-slim as client-builder +FROM node:20-bookworm-slim as client-builder ARG APP_HOME=/app WORKDIR ${APP_HOME} @@ -25,7 +25,7 @@ RUN npm run build {%- endif %} # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.7-slim-bookworm as python # Python build stage FROM python as python-build-stage @@ -103,7 +103,7 @@ RUN sed -i 's/\r$//g' /start-celerybeat RUN chmod +x /start-celerybeat -COPY ./compose/production/django/celery/flower/start /start-flower +COPY --chown=django:django ./compose/production/django/celery/flower/start /start-flower RUN sed -i 's/\r$//g' /start-flower RUN chmod +x /start-flower {%- endif %} diff --git a/{{cookiecutter.project_slug}}/compose/production/postgres/maintenance/rmbackup b/{{cookiecutter.project_slug}}/compose/production/postgres/maintenance/rmbackup new file mode 100644 index 000000000..fdfd20e14 --- /dev/null +++ b/{{cookiecutter.project_slug}}/compose/production/postgres/maintenance/rmbackup @@ -0,0 +1,36 @@ +#!/usr/bin/env bash + +### Remove a database backup. +### +### Parameters: +### <1> filename of a backup to remove. +### +### Usage: +### $ docker-compose -f .yml (exec |run --rm) postgres rmbackup <1> + + +set -o errexit +set -o pipefail +set -o nounset + + +working_dir="$(dirname ${0})" +source "${working_dir}/_sourced/constants.sh" +source "${working_dir}/_sourced/messages.sh" + + +if [[ -z ${1+x} ]]; then + message_error "Backup filename is not specified yet it is a required parameter. Make sure you provide one and try again." + exit 1 +fi +backup_filename="${BACKUP_DIR_PATH}/${1}" +if [[ ! -f "${backup_filename}" ]]; then + message_error "No backup with the specified filename found. Check out the 'backups' maintenance script output to see if there is one and try again." + exit 1 +fi + +message_welcome "Removing the '${backup_filename}' backup file..." + +rm -r "${backup_filename}" + +message_success "The '${backup_filename}' database backup has been removed." diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index e547dfbb8..321551ead 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,4 +1,4 @@ -FROM traefik:2.10.4 +FROM traefik:2.10.7 RUN mkdir -p /etc/traefik/acme \ && touch /etc/traefik/acme/acme.json \ && chmod 600 /etc/traefik/acme/acme.json diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml index 724c95cdf..f5d9e52fc 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/traefik.yml @@ -6,7 +6,7 @@ entryPoints: # http address: ':80' http: - # https://docs.traefik.io/routing/entrypoints/#entrypoint + # https://doc.traefik.io/traefik/routing/entrypoints/#entrypoint redirections: entryPoint: to: web-secure @@ -22,11 +22,11 @@ entryPoints: certificatesResolvers: letsencrypt: - # https://docs.traefik.io/master/https/acme/#lets-encrypt + # https://doc.traefik.io/traefik/https/acme/#lets-encrypt acme: email: '{{ cookiecutter.email }}' storage: /etc/traefik/acme/acme.json - # https://docs.traefik.io/master/https/acme/#httpchallenge + # https://doc.traefik.io/traefik/https/acme/#httpchallenge httpChallenge: entryPoint: web @@ -44,7 +44,7 @@ http: - csrf service: django tls: - # https://docs.traefik.io/master/routing/routers/#certresolver + # https://doc.traefik.io/traefik/routing/routers/#certresolver certResolver: letsencrypt {%- if cookiecutter.use_celery == 'y' %} @@ -54,7 +54,7 @@ http: - flower service: flower tls: - # https://docs.traefik.io/master/routing/routers/#certresolver + # https://doc.traefik.io/traefik/master/routing/routers/#certresolver certResolver: letsencrypt {%- endif %} {%- if cookiecutter.cloud_provider == 'None' %} @@ -76,7 +76,7 @@ http: middlewares: csrf: - # https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders + # https://doc.traefik.io/traefik/master/middlewares/http/headers/#hostsproxyheaders # https://docs.djangoproject.com/en/dev/ref/csrf/#ajax headers: hostsProxyHeaders: ['X-CSRFToken'] @@ -102,7 +102,7 @@ http: {%- endif %} providers: - # https://docs.traefik.io/master/providers/file/ + # https://doc.traefik.io/traefik/master/providers/file/ file: filename: /etc/traefik/traefik.yml watch: true diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index f02d476c1..ecc5a540d 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -30,7 +30,8 @@ LANGUAGE_CODE = "en-us" # from django.utils.translation import gettext_lazy as _ # LANGUAGES = [ # ('en', _('English')), -# ('pt-br', _('Português')), +# ('fr-fr', _('French')), +# ('pt-br', _('Portuguese')), # ] # https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 @@ -160,6 +161,7 @@ MIDDLEWARE = [ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", + "allauth.account.middleware.AccountMiddleware", ] # STATIC @@ -317,25 +319,25 @@ CELERY_TASK_SEND_SENT_EVENT = True # django-allauth # ------------------------------------------------------------------------------ ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True) -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_AUTHENTICATION_METHOD = "{{cookiecutter.username_type}}" -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_EMAIL_REQUIRED = True {%- if cookiecutter.username_type == "email" %} -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_USERNAME_REQUIRED = False -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_USER_MODEL_USERNAME_FIELD = None {%- endif %} -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_EMAIL_VERIFICATION = "mandatory" -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/account/configuration.html ACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.AccountAdapter" -# https://django-allauth.readthedocs.io/en/latest/forms.html +# https://docs.allauth.org/en/latest/account/forms.html ACCOUNT_FORMS = {"signup": "{{cookiecutter.project_slug}}.users.forms.UserSignupForm"} -# https://django-allauth.readthedocs.io/en/latest/configuration.html +# https://docs.allauth.org/en/latest/socialaccount/configuration.html SOCIALACCOUNT_ADAPTER = "{{cookiecutter.project_slug}}.users.adapters.SocialAccountAdapter" -# https://django-allauth.readthedocs.io/en/latest/forms.html +# https://docs.allauth.org/en/latest/socialaccount/configuration.html SOCIALACCOUNT_FORMS = {"signup": "{{cookiecutter.project_slug}}.users.forms.UserSocialSignupForm"} {% if cookiecutter.frontend_pipeline == 'Django Compressor' -%} # django-compressor diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index adab6087a..0304d6cd4 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -25,12 +25,12 @@ CACHES = { # EMAIL # ------------------------------------------------------------------------------ -{% if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'y' -%} +{% if cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'y' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = env("EMAIL_HOST", default="mailhog") +EMAIL_HOST = env("EMAIL_HOST", default="mailpit") # https://docs.djangoproject.com/en/dev/ref/settings/#email-port EMAIL_PORT = 1025 -{%- elif cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' -%} +{%- elif cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'n' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host EMAIL_HOST = "localhost" # https://docs.djangoproject.com/en/dev/ref/settings/#email-port diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 0ec29b3f0..70dc6d7dd 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -115,24 +115,24 @@ STORAGES = { }, {%- elif cookiecutter.cloud_provider == 'AWS' %} "default": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaRootS3Boto3Storage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaS3Storage", }, "staticfiles": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticRootS3Boto3Storage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticS3Storage", }, {%- elif cookiecutter.cloud_provider == 'GCP' %} "default": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaRootGoogleCloudStorage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaGoogleCloudStorage", }, "staticfiles": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticRootGoogleCloudStorage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticGoogleCloudStorage", }, {%- elif cookiecutter.cloud_provider == 'Azure' %} "default": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaRootAzureStorage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.MediaAzureStorage", }, "staticfiles": { - "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticRootAzureStorage", + "BACKEND": "{{cookiecutter.project_slug}}.utils.storages.StaticAzureStorage", }, {%- endif %} } diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index 92211ec76..68126182e 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -29,6 +29,11 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" # ------------------------------------------------------------------------------ TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa: F405 +# MEDIA +# ------------------------------------------------------------------------------ +# https://docs.djangoproject.com/en/dev/ref/settings/#media-url +MEDIA_URL = 'http://media.testserver' + {%- if cookiecutter.frontend_pipeline == 'Webpack' %} # django-webpack-loader # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index e55e18d32..6609f8053 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -16,8 +16,8 @@ services: {%- if cookiecutter.use_celery == 'y' %} - redis {%- endif %} - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} volumes: - .:/app:z @@ -55,11 +55,11 @@ services: ports: - '9000:9000' command: /start-docs - {%- if cookiecutter.use_mailhog == 'y' %} + {%- if cookiecutter.use_mailpit == 'y' %} - mailhog: - image: mailhog/mailhog:v1.0.0 - container_name: {{ cookiecutter.project_slug }}_local_mailhog + mailpit: + image: axllent/mailpit:latest + container_name: {{ cookiecutter.project_slug }}_local_mailpit ports: - "8025:8025" @@ -77,8 +77,8 @@ services: depends_on: - redis - postgres - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} ports: [] command: /start-celeryworker @@ -90,8 +90,8 @@ services: depends_on: - redis - postgres - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} ports: [] command: /start-celerybeat diff --git a/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po b/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po new file mode 100644 index 000000000..67434d505 --- /dev/null +++ b/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po @@ -0,0 +1,335 @@ +# Translations for the {{ cookiecutter.project_name }} project +# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }} +# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: {{ cookiecutter.version }}\n" +"Language: fr-FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:5 +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:8 +msgid "Account Inactive" +msgstr "Compte inactif" + +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:10 +msgid "This account is inactive." +msgstr "Ce compte est inactif." + +#: {{cookiecutter.project_slug}}/templates/account/email.html:7 +msgid "Account" +msgstr "Compte" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:10 +msgid "E-mail Addresses" +msgstr "Adresses e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:13 +msgid "The following e-mail addresses are associated with your account:" +msgstr "Les adresses e-mail suivantes sont associées à votre compte :" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:27 +msgid "Verified" +msgstr "Vérifié" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:29 +msgid "Unverified" +msgstr "Non vérifié" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:31 +msgid "Primary" +msgstr "Primaire" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:37 +msgid "Make Primary" +msgstr "Changer Primaire" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:38 +msgid "Re-send Verification" +msgstr "Renvoyer vérification" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:39 +msgid "Remove" +msgstr "Supprimer" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:46 +msgid "Warning:" +msgstr "Avertissement:" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:46 +msgid "" +"You currently do not have any e-mail address set up. You should really add " +"an e-mail address so you can receive notifications, reset your password, etc." +msgstr "" +"Vous n'avez actuellement aucune adresse e-mail configurée. Vous devriez ajouter " +"une adresse e-mail pour reçevoir des notifications, réinitialiser votre mot " +"de passe, etc." + +#: {{cookiecutter.project_slug}}/templates/account/email.html:51 +msgid "Add E-mail Address" +msgstr "Ajouter une adresse e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:56 +msgid "Add E-mail" +msgstr "Ajouter e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:66 +msgid "Do you really want to remove the selected e-mail address?" +msgstr "Voulez-vous vraiment supprimer l'adresse e-mail sélectionnée ?" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:6 +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:10 +msgid "Confirm E-mail Address" +msgstr "Confirmez votre adresse email" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:16 +#, python-format +msgid "" +"Please confirm that %(email)s is an e-mail " +"address for user %(user_display)s." +msgstr "" +"Veuillez confirmer que %(email)s est un e-mail " +"adresse de l'utilisateur %(user_display)s." + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:20 +msgid "Confirm" +msgstr "Confirm" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:27 +#, python-format +msgid "" +"This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." +msgstr "" +"Ce lien de confirmation par e-mail a expiré ou n'est pas valide. Veuillez" + "émettre une nouvelle demande de confirmation " +"par e-mail." + +#: {{cookiecutter.project_slug}}/templates/account/login.html:7 +#: {{cookiecutter.project_slug}}/templates/account/login.html:11 +#: {{cookiecutter.project_slug}}/templates/account/login.html:56 +#: {{cookiecutter.project_slug}}/templates/base.html:72 +msgid "Sign In" +msgstr "S'identifier" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:17 +msgid "Please sign in with one of your existing third party accounts:" +msgstr "Veuillez vous connecter avec l'un de vos comptes tiers existants :" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:19 +#, python-format +msgid "" +"Or, sign up for a %(site_name)s account and " +"sign in below:" +msgstr "" +"Ou, créez un compte %(site_name)s et " +"connectez-vous ci-dessous :" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:32 +msgid "or" +msgstr "ou" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:41 +#, python-format +msgid "" +"If you have not created an account yet, then please sign up first." +msgstr "" +"Si vous n'avez pas encore créé de compte, veuillez d'abord vous inscrire." + +#: {{cookiecutter.project_slug}}/templates/account/login.html:55 +msgid "Forgot Password?" +msgstr "Mot de passe oublié?" + +#: {{cookiecutter.project_slug}}/templates/account/logout.html:5 +#: {{cookiecutter.project_slug}}/templates/account/logout.html:8 +#: {{cookiecutter.project_slug}}/templates/account/logout.html:17 +#: {{cookiecutter.project_slug}}/templates/base.html:61 +msgid "Sign Out" +msgstr "Se déconnecter" + +#: {{cookiecutter.project_slug}}/templates/account/logout.html:10 +msgid "Are you sure you want to sign out?" +msgstr "Êtes-vous certain de vouloir vous déconnecter?" + +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:9 +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:14 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:5 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:4 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:7 +msgid "Change Password" +msgstr "Changer le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:7 +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:11 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:9 +msgid "Password Reset" +msgstr "Réinitialisation du mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:16 +msgid "" +"Forgotten your password? Enter your e-mail address below, and we'll send you " +"an e-mail allowing you to reset it." +msgstr "" +"Mot de passe oublié? Entrez votre adresse e-mail ci-dessous, et nous vous " +"enverrons un e-mail vous permettant de le réinitialiser." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:21 +msgid "Reset My Password" +msgstr "Réinitialiser mon mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:24 +msgid "Please contact us if you have any trouble resetting your password." +msgstr "" +"Veuillez nous contacter si vous rencontrez des difficultés pour réinitialiser" +"votre mot de passe." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:15 +msgid "" +"We have sent you an e-mail. Please contact us if you do not receive it " +"within a few minutes." +msgstr "" +"Nous vous avons envoyé un e-mail. Veuillez nous contacter si vous ne le " +"recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8 +msgid "Bad Token" +msgstr "Token Invalide" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:12 +#, python-format +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" +"Le lien de réinitialisation du mot de passe n'était pas valide, peut-être parce " +"qu'il a déjà été utilisé. Veuillez faire une " +"nouvelle demande de réinitialisation de mot de passe." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:18 +msgid "change password" +msgstr "changer le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:21 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:8 +msgid "Your password is now changed." +msgstr "Votre mot de passe est maintenant modifié." + +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:9 +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:14 +msgid "Set Password" +msgstr "Définir le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:6 +msgid "Signup" +msgstr "S'inscrire" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:9 +#: {{cookiecutter.project_slug}}/templates/account/signup.html:19 +#: {{cookiecutter.project_slug}}/templates/base.html:67 +msgid "Sign Up" +msgstr "S'inscrire" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:11 +#, python-format +msgid "" +"Already have an account? Then please sign in." +msgstr "" +"Vous avez déjà un compte? Alors veuillez vous connecter." + +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:5 +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:8 +msgid "Sign Up Closed" +msgstr "Inscriptions closes" + +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:10 +msgid "We are sorry, but the sign up is currently closed." +msgstr "Désolé, mais l'inscription est actuellement fermée." + +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:5 +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:8 +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:5 +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:8 +msgid "Verify Your E-mail Address" +msgstr "Vérifiez votre adresse e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:10 +msgid "" +"We have sent an e-mail to you for verification. Follow the link provided to " +"finalize the signup process. Please contact us if you do not receive it " +"within a few minutes." +msgstr "Nous vous avons envoyé un e-mail pour vérification. Suivez le lien fourni " +"pour finalisez le processus d'inscription. Veuillez nous contacter si vous ne le " +"recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:12 +msgid "" +"This part of the site requires us to verify that\n" +"you are who you claim to be. For this purpose, we require that you\n" +"verify ownership of your e-mail address. " +msgstr "" +"Cette partie du site nous oblige à vérifier que\n" +"vous êtes qui vous prétendez être. Nous vous demandons donc de\n" +"vérifier la propriété de votre adresse e-mail." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:16 +msgid "" +"We have sent an e-mail to you for\n" +"verification. Please click on the link inside this e-mail. Please\n" +"contact us if you do not receive it within a few minutes." +msgstr "" +"Nous vous avons envoyé un e-mail pour\n" +"vérification. Veuillez cliquer sur le lien contenu dans cet e-mail. Veuillez nous\n" +"contacter si vous ne le recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:20 +#, python-format +msgid "" +"Note: you can still change your e-" +"mail address." +msgstr "" +"Remarque : vous pouvez toujours changer votre e-" +"adresse e-mail." + +#: {{cookiecutter.project_slug}}/templates/base.html:57 +msgid "My Profile" +msgstr "Mon Profil" + +#: {{cookiecutter.project_slug}}/users/admin.py:17 +msgid "Personal info" +msgstr "Personal info" + +#: {{cookiecutter.project_slug}}/users/admin.py:19 +msgid "Permissions" +msgstr "Permissions" + +#: {{cookiecutter.project_slug}}/users/admin.py:30 +msgid "Important dates" +msgstr "Dates importantes" + +#: {{cookiecutter.project_slug}}/users/apps.py:7 +msgid "Users" +msgstr "Utilisateurs" + +#: {{cookiecutter.project_slug}}/users/forms.py:24 +#: {{cookiecutter.project_slug}}/users/tests/test_forms.py:36 +msgid "This username has already been taken." +msgstr "Ce nom d'utilisateur est déjà pris." + +#: {{cookiecutter.project_slug}}/users/models.py:15 +msgid "Name of User" +msgstr "Nom de l'utilisateur" + +#: {{cookiecutter.project_slug}}/users/views.py:23 +msgid "Information successfully updated" +msgstr "Informations mises à jour avec succès" diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json index 99b984da6..958b15ded 100644 --- a/{{cookiecutter.project_slug}}/package.json +++ b/{{cookiecutter.project_slug}}/package.json @@ -8,7 +8,7 @@ "autoprefixer": "^10.4.0", "babel-loader": "^9.1.2", "bootstrap": "^5.2.3", - "browser-sync": "^2.27.7", + "browser-sync": "^3.0.2", "css-loader": "^6.5.1", "gulp-concat": "^2.6.1", "concurrently": "^8.0.1", @@ -24,18 +24,18 @@ "node-sass-tilde-importer": "^1.0.2", "pixrem": "^5.0.0", "postcss": "^8.3.11", - "postcss-loader": "^7.0.2", + "postcss-loader": "^8.0.0", "postcss-preset-env": "^9.0.0", "sass": "^1.43.4", - "sass-loader": "^13.2.0", + "sass-loader": "^14.0.0", "webpack": "^5.65.0", - "webpack-bundle-tracker": "^2.0.0", + "webpack-bundle-tracker": "^3.0.1", "webpack-cli": "^5.0.1", "webpack-dev-server": "^4.6.0", "webpack-merge": "^5.8.0" }, "engines": { - "node": "18" + "node": "20" }, "browserslist": [ "last 2 versions" diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index c2ef23933..207306432 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ python-slugify==8.0.1 # https://github.com/un33k/python-slugify -Pillow==10.0.0 # https://github.com/python-pillow/Pillow +Pillow==10.2.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin @@ -7,44 +7,44 @@ rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/n rcssmin==1.1.1 # https://github.com/ndparker/rcssmin {%- endif %} {%- endif %} -argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi +argon2-cffi==23.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} -whitenoise==6.5.0 # https://github.com/evansd/whitenoise +whitenoise==6.6.0 # https://github.com/evansd/whitenoise {%- endif %} -redis==4.6.0 # https://github.com/redis/redis-py +redis==5.0.1 # https://github.com/redis/redis-py {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} -hiredis==2.2.3 # https://github.com/redis/hiredis-py +hiredis==2.3.2 # https://github.com/redis/hiredis-py {%- endif %} {%- if cookiecutter.use_celery == "y" %} -celery==5.3.1 # pyup: < 6.0 # https://github.com/celery/celery +celery==5.3.6 # pyup: < 6.0 # https://github.com/celery/celery django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat {%- if cookiecutter.use_docker == 'y' %} flower==2.0.1 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn[standard]==0.23.2 # https://github.com/encode/uvicorn +uvicorn[standard]==0.26.0 # https://github.com/encode/uvicorn {%- endif %} # Django # ------------------------------------------------------------------------------ -django==4.2.4 # pyup: < 5.0 # https://www.djangoproject.com/ -django-environ==0.10.0 # https://github.com/joke2k/django-environ +django==4.2.9 # pyup: < 5.0 # https://www.djangoproject.com/ +django-environ==0.11.2 # https://github.com/joke2k/django-environ django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils -django-allauth==0.54.0 # https://github.com/pennersr/django-allauth -django-crispy-forms==2.0 # https://github.com/django-crispy-forms/django-crispy-forms -crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5 +django-allauth==0.60.1 # https://github.com/pennersr/django-allauth +django-crispy-forms==2.1 # https://github.com/django-crispy-forms/django-crispy-forms +crispy-bootstrap5==2023.10 # https://github.com/django-crispy-forms/crispy-bootstrap5 {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} django-compressor==4.4 # https://github.com/django-compressor/django-compressor {%- endif %} -django-redis==5.3.0 # https://github.com/jazzband/django-redis +django-redis==5.4.0 # https://github.com/jazzband/django-redis {%- if cookiecutter.use_drf == 'y' %} # Django REST Framework djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework -django-cors-headers==4.2.0 # https://github.com/adamchainz/django-cors-headers +django-cors-headers==4.3.1 # https://github.com/adamchainz/django-cors-headers # DRF-spectacular for api documentation -drf-spectacular==0.26.4 # https://github.com/tfranzel/drf-spectacular +drf-spectacular==0.27.1 # https://github.com/tfranzel/drf-spectacular {%- endif %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %} -django-webpack-loader==2.0.1 # https://github.com/django-webpack/django-webpack-loader +django-webpack-loader==3.0.1 # https://github.com/django-webpack/django-webpack-loader {%- endif %} diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index ebcfe8457..2a80055c0 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,43 +1,43 @@ -r base.txt -Werkzeug[watchdog]==2.3.7 # https://github.com/pallets/werkzeug +Werkzeug[watchdog]==3.0.1 # https://github.com/pallets/werkzeug ipdb==0.13.13 # https://github.com/gotcha/ipdb {%- if cookiecutter.use_docker == 'y' %} -psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg +psycopg[c]==3.1.17 # https://github.com/psycopg/psycopg {%- else %} -psycopg[binary]==3.1.9 # https://github.com/psycopg/psycopg +psycopg[binary]==3.1.17 # https://github.com/psycopg/psycopg {%- endif %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} -watchfiles==0.19.0 # https://github.com/samuelcolvin/watchfiles +watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles {%- endif %} # Testing # ------------------------------------------------------------------------------ -mypy==1.4.1 # https://github.com/python/mypy -django-stubs[compatible-mypy]==4.2.3 # https://github.com/typeddjango/django-stubs -pytest==7.4.0 # https://github.com/pytest-dev/pytest +mypy==1.7.1 # https://github.com/python/mypy +django-stubs[compatible-mypy]==4.2.7 # https://github.com/typeddjango/django-stubs +pytest==7.4.4 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.7 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} -djangorestframework-stubs[compatible-mypy]==3.14.2 # https://github.com/typeddjango/djangorestframework-stubs +djangorestframework-stubs[compatible-mypy]==3.14.5 # https://github.com/typeddjango/djangorestframework-stubs {%- endif %} # Documentation # ------------------------------------------------------------------------------ -sphinx==6.2.1 # https://github.com/sphinx-doc/sphinx +sphinx==7.2.6 # https://github.com/sphinx-doc/sphinx sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8==6.1.0 # https://github.com/PyCQA/flake8 -flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort -coverage==7.3.0 # https://github.com/nedbat/coveragepy -black==23.7.0 # https://github.com/psf/black -djlint==1.32.1 # https://github.com/Riverside-Healthcare/djLint -pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django +flake8==7.0.0 # https://github.com/PyCQA/flake8 +flake8-isort==6.1.1 # https://github.com/gforcada/flake8-isort +coverage==7.4.0 # https://github.com/nedbat/coveragepy +black==23.12.1 # https://github.com/psf/black +djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint +pylint-django==2.5.5 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} -pre-commit==3.3.3 # https://github.com/pre-commit/pre-commit +pre-commit==3.6.0 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ @@ -46,4 +46,4 @@ factory-boy==3.3.0 # https://github.com/FactoryBoy/factory_boy django-debug-toolbar==4.2.0 # https://github.com/jazzband/django-debug-toolbar 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 -pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django +pytest-django==4.7.0 # https://github.com/pytest-dev/pytest-django diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index da827e7e0..80afd9e18 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -3,42 +3,42 @@ -r base.txt gunicorn==21.2.0 # https://github.com/benoitc/gunicorn -psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg +psycopg[c]==3.1.17 # https://github.com/psycopg/psycopg {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.29.2 # https://github.com/getsentry/sentry-python +sentry-sdk==1.39.2 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} -hiredis==2.2.3 # https://github.com/redis/hiredis-py +hiredis==2.3.2 # https://github.com/redis/hiredis-py {%- endif %} # Django # ------------------------------------------------------------------------------ {%- if cookiecutter.cloud_provider == 'AWS' %} -django-storages[boto3]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[s3]==1.14.2 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'GCP' %} -django-storages[google]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[google]==1.14.2 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'Azure' %} -django-storages[azure]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[azure]==1.14.2 # https://github.com/jschneier/django-storages {%- endif %} {%- if cookiecutter.mail_service == 'Mailgun' %} -django-anymail[mailgun]==10.1 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Amazon SES' %} -django-anymail[amazon-ses]==10.1 # https://github.com/anymail/django-anymail +django-anymail[amazon-ses]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mailjet' %} -django-anymail[mailjet]==10.1 # https://github.com/anymail/django-anymail +django-anymail[mailjet]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mandrill' %} -django-anymail[mandrill]==10.1 # https://github.com/anymail/django-anymail +django-anymail[mandrill]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Postmark' %} -django-anymail[postmark]==10.1 # https://github.com/anymail/django-anymail +django-anymail[postmark]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Sendgrid' %} -django-anymail[sendgrid]==10.1 # https://github.com/anymail/django-anymail +django-anymail[sendgrid]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SendinBlue' %} -django-anymail[sendinblue]==10.1 # https://github.com/anymail/django-anymail +django-anymail[sendinblue]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SparkPost' %} -django-anymail[sparkpost]==10.1 # https://github.com/anymail/django-anymail +django-anymail[sparkpost]==10.2 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Other SMTP' %} -django-anymail==10.1 # https://github.com/anymail/django-anymail +django-anymail==10.2 # https://github.com/anymail/django-anymail {%- endif %} diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 431fc7e8c..1f79d441f 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.11.4 +python-3.11.7 diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg index 829064213..2412f1746 100644 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ b/{{cookiecutter.project_slug}}/setup.cfg @@ -4,6 +4,7 @@ [flake8] max-line-length = 119 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv +extend-ignore = E203 [pycodestyle] max-line-length = 119 diff --git a/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt b/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt new file mode 100644 index 000000000..a4910eb6d --- /dev/null +++ b/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt @@ -0,0 +1,23 @@ +##basic build dependencies of various Django apps for Debian Bookworm 12.x +#build-essential metapackage install: make, gcc, g++, +build-essential +#required to translate +gettext +python3-dev + +##shared dependencies of: +##Pillow, pylibmc +zlib1g-dev + +##Postgresql and psycopg2 dependencies +libpq-dev + +##Pillow dependencies +libtiff5-dev +libjpeg62-turbo-dev +libfreetype6-dev +liblcms2-dev +libwebp-dev + +##django-extensions +libgraphviz-dev diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py index 080c734bb..e1822375b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py @@ -40,8 +40,8 @@ def update_site_forward(apps, schema_editor): _update_or_create_site_with_sequence( Site, schema_editor.connection, - "{{cookiecutter.domain_name}}", - "{{cookiecutter.project_name}}", + "{{ cookiecutter.domain_name }}", + "{{ cookiecutter.project_name[:50] }}", ) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py index c5c824bda..f9ae43a8e 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py @@ -25,13 +25,14 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter): """ Populates user information from social provider info. - See: https://django-allauth.readthedocs.io/en/latest/advanced.html?#creating-and-populating-user-instances + See: https://docs.allauth.org/en/latest/socialaccount/advanced.html#creating-and-populating-user-instances """ - user = sociallogin.user - if name := data.get("name"): - user.name = name - elif first_name := data.get("first_name"): - user.name = first_name - if last_name := data.get("last_name"): - user.name += f" {last_name}" - return super().populate_user(request, sociallogin, data) + user = super().populate_user(request, sociallogin, data) + if not user.name: + if name := data.get("name"): + user.name = name + elif first_name := data.get("first_name"): + user.name = first_name + if last_name := data.get("last_name"): + user.name += f" {last_name}" + return user diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py index a5f89dd67..7fd49fa92 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py @@ -10,7 +10,7 @@ User = get_user_model() if settings.DJANGO_ADMIN_FORCE_ALLAUTH: # Force the `admin` sign in process to go through the `django-allauth` workflow: - # https://django-allauth.readthedocs.io/en/stable/advanced.html#admin + # https://docs.allauth.org/en/latest/common/admin.html#admin admin.site.login = decorators.login_required(admin.site.login) # type: ignore[method-assign] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/__init__.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py index 4b86f7985..bebd8adcf 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -29,6 +29,13 @@ class UserFactory(DjangoModelFactory): ) self.set_password(password) + @classmethod + def _after_postgeneration(cls, instance, create, results=None): + """Save again the instance if creating and at least one hook ran.""" + if create and results and not cls._meta.skip_postgeneration_save: + # Some post-generation hooks ran, and may have modified us. + instance.save() + class Meta: model = get_user_model() django_get_or_create = ["{{cookiecutter.username_type}}"] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py index 2991d18a9..75917ab34 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py @@ -1,4 +1,10 @@ +from importlib import reload + +import pytest +from django.contrib import admin +from django.contrib.auth.models import AnonymousUser from django.urls import reverse +from pytest_django.asserts import assertRedirects from {{ cookiecutter.project_slug }}.users.models import User @@ -47,3 +53,25 @@ class TestUserAdmin: url = reverse("admin:users_user_change", kwargs={"object_id": user.pk}) response = admin_client.get(url) assert response.status_code == 200 + + @pytest.fixture + def force_allauth(self, settings): + settings.DJANGO_ADMIN_FORCE_ALLAUTH = True + # Reload the admin module to apply the setting change + import {{ cookiecutter.project_slug }}.users.admin as users_admin # pylint: disable=import-outside-toplevel + + try: + reload(users_admin) + except admin.sites.AlreadyRegistered: + pass + + @pytest.mark.django_db + @pytest.mark.usefixtures("force_allauth") + def test_allauth_login(self, rf, settings): + request = rf.get("/fake-url") + request.user = AnonymousUser() + response = admin.site.login(request) + + # The `admin` login view should redirect to the `allauth` login view + target_url = reverse(settings.LOGIN_URL) + "?next=" + request.path + assertRedirects(response, target_url, fetch_redirect_response=False) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py index 27595ad1a..cc055378a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py @@ -1,36 +1,36 @@ {% if cookiecutter.cloud_provider == 'AWS' -%} -from storages.backends.s3boto3 import S3Boto3Storage +from storages.backends.s3 import S3Storage -class StaticRootS3Boto3Storage(S3Boto3Storage): +class StaticS3Storage(S3Storage): location = "static" default_acl = "public-read" -class MediaRootS3Boto3Storage(S3Boto3Storage): +class MediaS3Storage(S3Storage): location = "media" file_overwrite = False {%- elif cookiecutter.cloud_provider == 'GCP' -%} from storages.backends.gcloud import GoogleCloudStorage -class StaticRootGoogleCloudStorage(GoogleCloudStorage): +class StaticGoogleCloudStorage(GoogleCloudStorage): location = "static" default_acl = "publicRead" -class MediaRootGoogleCloudStorage(GoogleCloudStorage): +class MediaGoogleCloudStorage(GoogleCloudStorage): location = "media" file_overwrite = False {%- elif cookiecutter.cloud_provider == 'Azure' -%} from storages.backends.azure_storage import AzureStorage -class StaticRootAzureStorage(AzureStorage): +class StaticAzureStorage(AzureStorage): location = "static" -class MediaRootAzureStorage(AzureStorage): +class MediaAzureStorage(AzureStorage): location = "media" file_overwrite = False {%- endif %}