From d5967ed3e9c454c4c88c0fd0473969054e5f0bdb Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 8 Feb 2024 02:09:26 +0000 Subject: [PATCH 01/47] Release 2024.02.07 --- CHANGELOG.md | 19 +++++++++++++++++++ setup.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f05a4c51..307d7257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.07 + + +### Changed + +- Extend docker test with deploy check ([#4838](https://github.com/cookiecutter/cookiecutter-django/pull/4838)) + +- Generic UserManager ([#4836](https://github.com/cookiecutter/cookiecutter-django/pull/4836)) + +### Updated + +- Update django-allauth to 0.61.0 ([#4839](https://github.com/cookiecutter/cookiecutter-django/pull/4839)) + +- Bump gulp-postcss to 10.0.0 ([#4835](https://github.com/cookiecutter/cookiecutter-django/pull/4835)) + +- Update sentry-sdk to 1.40.2 ([#4837](https://github.com/cookiecutter/cookiecutter-django/pull/4837)) + +- Update django to 4.2.10 ([#4833](https://github.com/cookiecutter/cookiecutter-django/pull/4833)) + ## 2024.02.05 diff --git a/setup.py b/setup.py index 554f649a..de9cd135 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.05" +version = "2024.02.07" with open("README.md") as readme_file: long_description = readme_file.read() From 300ccc6b57bd76322afc9e8874ae5c5e77c25da6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 05:10:33 +0000 Subject: [PATCH 02/47] Bump python in /{{cookiecutter.project_slug}}/compose/local/docs Bumps python from 3.11.7-slim-bookworm to 3.11.8-slim-bookworm. --- updated-dependencies: - dependency-name: python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- {{cookiecutter.project_slug}}/compose/local/docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index 2b68c84b..87a1b246 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 docker.io/python:3.11.7-slim-bookworm as python +FROM docker.io/python:3.11.8-slim-bookworm as python # Python build stage From f2c320527a3e3639c15eda85d7aa0af2a8451ffc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 05:23:12 +0000 Subject: [PATCH 03/47] Bump python in /{{cookiecutter.project_slug}}/compose/local/django Bumps python from 3.11.7-slim-bookworm to 3.11.8-slim-bookworm. --- updated-dependencies: - dependency-name: python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- {{cookiecutter.project_slug}}/compose/local/django/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index 575a4518..75d5cbb9 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 docker.io/python:3.11.7-slim-bookworm as python +FROM docker.io/python:3.11.8-slim-bookworm as python # Python build stage FROM docker.io/python as python-build-stage From 908697e5a3777150d4ade52d4c24da475d92f20c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 05:29:46 +0000 Subject: [PATCH 04/47] Bump python in /{{cookiecutter.project_slug}}/compose/production/django Bumps python from 3.11.7-slim-bookworm to 3.11.8-slim-bookworm. --- updated-dependencies: - dependency-name: python dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .../compose/production/django/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index 079f6bd7..fb7fec50 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -25,7 +25,7 @@ RUN npm run build {%- endif %} # define an alias for the specific python version used in this file. -FROM docker.io/python:3.11.7-slim-bookworm as python +FROM docker.io/python:3.11.8-slim-bookworm as python # Python build stage FROM docker.io/python as python-build-stage From d4ff2e4adfe0d2a481ab3d0049bab393a913b659 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 9 Feb 2024 02:09:41 +0000 Subject: [PATCH 05/47] Release 2024.02.08 --- CHANGELOG.md | 11 +++++++++++ setup.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 307d7257..9b4e3c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.08 + + +### Updated + +- Bump python to 3.11.8 in compose/local/docs ([#4840](https://github.com/cookiecutter/cookiecutter-django/pull/4840)) + +- Bump python to 3.11.8 in compose/local/django ([#4841](https://github.com/cookiecutter/cookiecutter-django/pull/4841)) + +- Bump python to 3.11.8 in compose/production/django ([#4842](https://github.com/cookiecutter/cookiecutter-django/pull/4842)) + ## 2024.02.07 diff --git a/setup.py b/setup.py index de9cd135..efdedee3 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.07" +version = "2024.02.08" with open("README.md") as readme_file: long_description = readme_file.read() From 519d07144c6edb0c83c39b3946d5a9065c93aec7 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Fri, 9 Feb 2024 02:46:52 -0800 Subject: [PATCH 06/47] Update python-slugify to 8.0.4 (#4844) --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 8658b0b2..9a61609d 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,4 +1,4 @@ -python-slugify==8.0.3 # https://github.com/un33k/python-slugify +python-slugify==8.0.4 # https://github.com/un33k/python-slugify Pillow==10.2.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} From 1e09d20ffcad44696fc7ddadd169afc1e65755e4 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Fri, 9 Feb 2024 02:48:31 -0800 Subject: [PATCH 07/47] Update django-allauth to 0.61.1 (#4846) --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 9a61609d..70588e23 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -31,7 +31,7 @@ uvicorn[standard]==0.27.0.post1 # https://github.com/encode/uvicorn django==4.2.10 # 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.61.0 # https://github.com/pennersr/django-allauth +django-allauth==0.61.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' %} From 474b82b5d3fa67accc3f927e7b1549eadbd2773f Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Fri, 9 Feb 2024 04:49:08 -0800 Subject: [PATCH 08/47] Update sentry-sdk to 1.40.3 (#4847) --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index ae9a2dd0..b6e793e1 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.40.2 # https://github.com/getsentry/sentry-python +sentry-sdk==1.40.3 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.3.2 # https://github.com/redis/hiredis-py From 9b0bc1cc5ccc9935be40bd472cd460e30707d1ae Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 10 Feb 2024 02:08:31 +0000 Subject: [PATCH 09/47] Release 2024.02.09 --- CHANGELOG.md | 11 +++++++++++ setup.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b4e3c6b..c5e20748 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.09 + + +### Updated + +- Update sentry-sdk to 1.40.3 ([#4847](https://github.com/cookiecutter/cookiecutter-django/pull/4847)) + +- Update django-allauth to 0.61.1 ([#4846](https://github.com/cookiecutter/cookiecutter-django/pull/4846)) + +- Update python-slugify to 8.0.4 ([#4844](https://github.com/cookiecutter/cookiecutter-django/pull/4844)) + ## 2024.02.08 diff --git a/setup.py b/setup.py index efdedee3..b5182fce 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.08" +version = "2024.02.09" with open("README.md") as readme_file: long_description = readme_file.read() From 128310262964fc4ff0147d34c6528dea6fb067ef Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Sat, 10 Feb 2024 13:43:55 +0000 Subject: [PATCH 10/47] Update uvicorn from 0.27.0.post1 to 0.27.1 --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 70588e23..442357fc 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -23,7 +23,7 @@ flower==2.0.1 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn[standard]==0.27.0.post1 # https://github.com/encode/uvicorn +uvicorn[standard]==0.27.1 # https://github.com/encode/uvicorn {%- endif %} # Django From e95c2733dd87cd48d10416230cd55fb4a138f658 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 09:24:54 +0000 Subject: [PATCH 11/47] Auto-update pre-commit hooks (#4852) Co-authored-by: browniebroke <861044+browniebroke@users.noreply.github.com> --- {{cookiecutter.project_slug}}/.pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 12a1f5e8..d32ac6b8 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: exclude: '{{cookiecutter.project_slug}}/templates/' - repo: https://github.com/adamchainz/django-upgrade - rev: '1.15.0' + rev: '1.16.0' hooks: - id: django-upgrade args: ['--target-version', '4.2'] From 1086d19af9f10b834cd9196a0b58642e064df8dc Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Mon, 12 Feb 2024 01:25:06 -0800 Subject: [PATCH 12/47] Update django-upgrade to 1.16.0 (#4851) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b9ddeac0..471a5d67 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ binaryornot==0.4.4 black==24.1.1 isort==5.13.2 flake8==7.0.0 -django-upgrade==1.15.0 +django-upgrade==1.16.0 djlint==1.34.1 pre-commit==3.6.0 From 6ac86a5b57a2a3dbc6f4f9c067a5c914e62993eb Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Mon, 12 Feb 2024 01:25:23 -0800 Subject: [PATCH 13/47] Update pre-commit to 3.6.1 (#4849) * Update pre-commit from 3.6.0 to 3.6.1 * Update pre-commit from 3.6.0 to 3.6.1 --- requirements.txt | 2 +- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 471a5d67..18ae8f05 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,7 +9,7 @@ isort==5.13.2 flake8==7.0.0 django-upgrade==1.16.0 djlint==1.34.1 -pre-commit==3.6.0 +pre-commit==3.6.1 # Testing # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 0c1ebca2..ef26dcc8 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -37,7 +37,7 @@ 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.6.0 # https://github.com/pre-commit/pre-commit +pre-commit==3.6.1 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ From 576bb1d452d225b7c93204d93582e94cc58fabb8 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Mon, 12 Feb 2024 01:25:47 -0800 Subject: [PATCH 14/47] Update django-model-utils to 4.4.0 (#4850) --- {{cookiecutter.project_slug}}/requirements/base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 70588e23..e260bc92 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -30,7 +30,7 @@ uvicorn[standard]==0.27.0.post1 # https://github.com/encode/uvicorn # ------------------------------------------------------------------------------ django==4.2.10 # 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-model-utils==4.4.0 # https://github.com/jazzband/django-model-utils django-allauth==0.61.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 From f12ac669f3d1a48d03363819f74e6d29ece0575c Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 13 Feb 2024 02:10:21 +0000 Subject: [PATCH 15/47] Release 2024.02.12 --- CHANGELOG.md | 13 +++++++++++++ setup.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5e20748..1ee7a589 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.12 + + +### Updated + +- Update django-model-utils to 4.4.0 ([#4850](https://github.com/cookiecutter/cookiecutter-django/pull/4850)) + +- Update pre-commit to 3.6.1 ([#4849](https://github.com/cookiecutter/cookiecutter-django/pull/4849)) + +- Update django-upgrade to 1.16.0 ([#4851](https://github.com/cookiecutter/cookiecutter-django/pull/4851)) + +- Auto-update pre-commit hooks ([#4852](https://github.com/cookiecutter/cookiecutter-django/pull/4852)) + ## 2024.02.09 diff --git a/setup.py b/setup.py index b5182fce..7c129824 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.09" +version = "2024.02.12" with open("README.md") as readme_file: long_description = readme_file.read() From 2e129bd65b9d59270de6351f3478b320f5294664 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Tue, 13 Feb 2024 02:25:10 -0800 Subject: [PATCH 16/47] Update black to 24.2.0 (#4853) * Update black from 24.1.1 to 24.2.0 * Update black from 24.1.1 to 24.2.0 --- requirements.txt | 2 +- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 18ae8f05..a84612d0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==24.1.1 +black==24.2.0 isort==5.13.2 flake8==7.0.0 django-upgrade==1.16.0 diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index ef26dcc8..cad007f4 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -31,7 +31,7 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild flake8==7.0.0 # https://github.com/PyCQA/flake8 flake8-isort==6.1.1 # https://github.com/gforcada/flake8-isort coverage==7.4.1 # https://github.com/nedbat/coveragepy -black==24.1.1 # https://github.com/psf/black +black==24.2.0 # 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' %} From 07376d8a7f3f60f9dc405466dfa83646bf615d10 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:25:25 +0000 Subject: [PATCH 17/47] Auto-update pre-commit hooks (#4855) Co-authored-by: browniebroke <861044+browniebroke@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- {{cookiecutter.project_slug}}/.pre-commit-config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index baafb694..7daf6ac7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,7 +33,7 @@ repos: exclude: hooks/ - repo: https://github.com/psf/black - rev: 24.1.1 + rev: 24.2.0 hooks: - id: black diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index d32ac6b8..466cfece 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -40,7 +40,7 @@ repos: args: [--py311-plus] - repo: https://github.com/psf/black - rev: 24.1.1 + rev: 24.2.0 hooks: - id: black From dd841c64780cdeb25f6ab89bdd47fa6c528f1edb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:28:24 +0000 Subject: [PATCH 18/47] Bump traefik to 2.11.0 (#4857) Bumps traefik from 2.10.7 to 2.11.0. --- updated-dependencies: - dependency-name: traefik dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../compose/production/traefik/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index c32b1587..ea918e91 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/traefik:2.10.7 +FROM docker.io/traefik:2.11.0 RUN mkdir -p /etc/traefik/acme \ && touch /etc/traefik/acme/acme.json \ && chmod 600 /etc/traefik/acme/acme.json From 6ba6104f09d4c4c9d56eb6b460e17748115ececb Mon Sep 17 00:00:00 2001 From: Jelmer Draaijer Date: Tue, 6 Feb 2024 19:56:31 +0100 Subject: [PATCH 19/47] Ruff as formatter & linter --- docs/linters.rst | 48 ++---- requirements.txt | 4 +- .../.devcontainer/devcontainer.json | 13 +- .../.pre-commit-config.yaml | 27 +-- {{cookiecutter.project_slug}}/.travis.yml | 8 +- {{cookiecutter.project_slug}}/README.md | 2 +- {{cookiecutter.project_slug}}/pyproject.toml | 162 ++++++++++++------ .../requirements/local.txt | 8 +- {{cookiecutter.project_slug}}/setup.cfg | 11 -- .../users/tests/test_admin.py | 2 +- 10 files changed, 145 insertions(+), 140 deletions(-) delete mode 100644 {{cookiecutter.project_slug}}/setup.cfg diff --git a/docs/linters.rst b/docs/linters.rst index a4f60cc8..1fc44f30 100644 --- a/docs/linters.rst +++ b/docs/linters.rst @@ -4,40 +4,30 @@ Linters .. index:: linters -flake8 +ruff ------ -To run flake8: :: +Ruff is a Python linter and code formatter, written in Rust. +It is a aggregation of flake8, pylint, pyupgrade and many more. - $ flake8 +Ruff comes with a linter (``ruff check``) and a formatter (``ruff format``). +The linter is a wrapper around flake8, pylint, and other linters, +and the formatter is a wrapper around black, isort, and other formatters. -The config for flake8 is located in setup.cfg. It specifies: +To run ruff without modifying your files: :: -* Set max line length to 120 chars -* Exclude ``.tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules`` + $ ruff format --diff . + $ ruff check . -pylint ------- +Ruff is capable of fixing most of the problems it encounters. +Be sure you commit first before running `ruff` so you can restore to a savepoint (and amend afterwards to prevent a double commit. : :: -To run pylint: :: + $ ruff format . + $ ruff check --fix . + # be careful with the --unsafe-fixes option, it can break your code + $ ruff check --fix --unsafe-fixes . - $ pylint - -The config for pylint is located in .pylintrc. It specifies: - -* Use the pylint_django plugin. If using Celery, also use pylint_celery. -* Set max line length to 120 chars -* Disable linting messages for missing docstring and invalid name -* max-parents=13 - -pycodestyle ------------ - -This is included in flake8's checks, but you can also run it separately to see a more detailed report: :: - - $ pycodestyle - -The config for pycodestyle is located in setup.cfg. It specifies: - -* Set max line length to 120 chars -* Exclude ``.tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules`` +The config for ruff is located in pyproject.toml. +On of the most important option is `tool.ruff.lint.select`. +`select` determines which linters are run. In example, `DJ `_ refers to flake8-django. +For a full list of available linters, see `https://docs.astral.sh/ruff/rules/ `_ diff --git a/requirements.txt b/requirements.txt index a84612d0..3de15dc6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,9 +4,7 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==24.2.0 -isort==5.13.2 -flake8==7.0.0 +ruff==0.2.1 django-upgrade==1.16.0 djlint==1.34.1 pre-commit==3.6.1 diff --git a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json index c4158dc1..7fcd6287 100644 --- a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json +++ b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json @@ -37,22 +37,11 @@ "editor.codeActionsOnSave": { "source.organizeImports": true }, - // Uncomment when fixed - // https://github.com/microsoft/vscode-remote-release/issues/8474 - // "editor.defaultFormatter": "ms-python.black-formatter", - "formatting.blackPath": "/usr/local/bin/black", - "formatting.provider": "black", + "editor.defaultFormatter": "charliermarsh.ruff", "languageServer": "Pylance", - // "linting.banditPath": "/usr/local/py-utils/bin/bandit", "linting.enabled": true, - "linting.flake8Enabled": true, - "linting.flake8Path": "/usr/local/bin/flake8", "linting.mypyEnabled": true, "linting.mypyPath": "/usr/local/bin/mypy", - "linting.pycodestylePath": "/usr/local/bin/pycodestyle", - // "linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle", - "linting.pylintEnabled": true, - "linting.pylintPath": "/usr/local/bin/pylint" } }, // https://code.visualstudio.com/docs/remote/devcontainerjson-reference#_vs-code-specific-properties diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 466cfece..7c9565e1 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -33,26 +33,15 @@ repos: - id: django-upgrade args: ['--target-version', '4.2'] - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + # Run the Ruff linter. + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.1 hooks: - - id: pyupgrade - args: [--py311-plus] - - - repo: https://github.com/psf/black - rev: 24.2.0 - hooks: - - id: black - - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/flake8 - rev: 7.0.0 - hooks: - - id: flake8 + # Linter + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + # Formatter + - id: ruff-format - repo: https://github.com/Riverside-Healthcare/djLint rev: v1.34.1 diff --git a/{{cookiecutter.project_slug}}/.travis.yml b/{{cookiecutter.project_slug}}/.travis.yml index cd703d3a..78709191 100644 --- a/{{cookiecutter.project_slug}}/.travis.yml +++ b/{{cookiecutter.project_slug}}/.travis.yml @@ -10,9 +10,9 @@ jobs: include: - name: "Linter" before_script: - - pip install -q flake8 + - pip install -q ruff script: - - "flake8" + - ruff check . - name: "Django Test" {%- if cookiecutter.use_docker == 'y' %} @@ -24,7 +24,7 @@ jobs: - docker compose -f local.yml run --rm django python manage.py migrate - docker compose -f local.yml up -d script: - - "docker compose -f local.yml run django pytest" + - docker compose -f local.yml run django pytest after_failure: - docker compose -f local.yml logs {%- else %} @@ -41,5 +41,5 @@ jobs: install: - pip install -r requirements/local.txt script: - - "pytest" + - pytest {%- endif %} diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index ccf245a2..cb757689 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -3,7 +3,7 @@ {{ cookiecutter.description }} [![Built with Cookiecutter Django](https://img.shields.io/badge/built%20with-Cookiecutter%20Django-ff69b4.svg?logo=cookiecutter)](https://github.com/cookiecutter/cookiecutter-django/) -[![Black code style](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) {%- if cookiecutter.open_source_license != "Not open source" %} diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 7e4c9aa9..a056c71c 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -16,25 +16,6 @@ include = ["{{cookiecutter.project_slug}}/**"] omit = ["*/migrations/*", "*/tests/*"] plugins = ["django_coverage_plugin"] - -# ==== black ==== -[tool.black] -line-length = 119 -target-version = ['py311'] - - -# ==== isort ==== -[tool.isort] -profile = "black" -line_length = 119 -known_first_party = [ - "{{cookiecutter.project_slug}}", - "config", -] -skip = ["venv/"] -skip_glob = ["**/migrations/*.py"] - - # ==== mypy ==== [tool.mypy] python_version = "3.11" @@ -58,40 +39,6 @@ ignore_errors = true [tool.django-stubs] django_settings_module = "config.settings.test" - -# ==== PyLint ==== -[tool.pylint.MASTER] -load-plugins = [ - "pylint_django", -{%- if cookiecutter.use_celery == "y" %} - "pylint_celery", -{%- endif %} -] -django-settings-module = "config.settings.local" - -[tool.pylint.FORMAT] -max-line-length = 119 - -[tool.pylint."MESSAGES CONTROL"] -disable = [ - "missing-docstring", - "invalid-name", -] - -[tool.pylint.DESIGN] -max-parents = 13 - -[tool.pylint.TYPECHECK] -generated-members = [ - "REQUEST", - "acl_users", - "aq_parent", - "[a-zA-Z]+_set{1,2}", - "save", - "delete", -] - - # ==== djLint ==== [tool.djlint] blank_line_after_tag = "load,extends" @@ -110,3 +57,112 @@ indent_size = 2 [tool.djlint.js] indent_size = 2 + +[tool.ruff] +# Exclude a variety of commonly ignored directories. +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "build", + "dist", + "node_modules", + "venv", + "*/migrations/*.py", + "staticfiles/*" +] +# Same as Django: https://github.com/cookiecutter/cookiecutter-django/issues/4792. +line-length = 88 +indent-width = 4 +target-version = "py311" + +[tool.ruff.lint] +select = [ + "F", + "E", + "W", + "C90", + "I", + "N", + "UP", + "YTT", + # "ANN", # flake8-annotations: we should support this in the future but 100+ errors atm + "ASYNC", + "S", + "BLE", + "FBT", + "B", + "A", + "COM", + "C4", + "DTZ", + "T10", + "DJ", + "EM", + "EXE", + "FA", + 'ISC', + "ICN", + "G", + 'INP', + 'PIE', + "T20", + 'PYI', + 'PT', + "Q", + "RSE", + "RET", + "SLF", + "SLOT", + "SIM", + "TID", + "TCH", + "INT", + # "ARG", # Unused function argument + "PTH", + "ERA", + "PD", + "PGH", + "PL", + "TRY", + "FLY", + # "NPY", + # "AIR", + "PERF", + # "FURB", + # "LOG", + "RUF" +] +ignore = [ + "S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/ + "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` + "SIM102" # sometimes it's better to nest +] +# Allow fix for all enabled rules (when `--fix`) is provided. +fixable = ["ALL"] +unfixable = [] +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[tool.ruff.lint.isort] +force-single-line = true diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index cad007f4..da0e0494 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -28,15 +28,9 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8==7.0.0 # https://github.com/PyCQA/flake8 -flake8-isort==6.1.1 # https://github.com/gforcada/flake8-isort +ruff==0.2.1 coverage==7.4.1 # https://github.com/nedbat/coveragepy -black==24.2.0 # 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.6.1 # https://github.com/pre-commit/pre-commit # Django diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg deleted file mode 100644 index 2412f174..00000000 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ /dev/null @@ -1,11 +0,0 @@ -# flake8 and pycodestyle don't support pyproject.toml -# https://github.com/PyCQA/flake8/issues/234 -# https://github.com/PyCQA/pycodestyle/issues/813 -[flake8] -max-line-length = 119 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv -extend-ignore = E203 - -[pycodestyle] -max-line-length = 119 -exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv 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 75917ab3..095b2cbb 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 @@ -58,7 +58,7 @@ class TestUserAdmin: 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 + import {{ cookiecutter.project_slug }}.users.admin as users_admin try: reload(users_admin) From 0fc4ea6165ad98a99648e815ef615fbf85482260 Mon Sep 17 00:00:00 2001 From: Jelmer Draaijer Date: Tue, 13 Feb 2024 11:57:53 +0100 Subject: [PATCH 20/47] Apply ruff to codebase --- tests/test_cookiecutter_generation.py | 19 +++++------ .../config/api_router.py | 8 ++--- {{cookiecutter.project_slug}}/config/asgi.py | 6 ++-- .../config/settings/base.py | 11 +++--- .../config/settings/local.py | 26 +++++++++----- .../config/settings/production.py | 34 +++++++++++++------ .../config/settings/test.py | 5 +-- {{cookiecutter.project_slug}}/config/urls.py | 18 +++++++--- {{cookiecutter.project_slug}}/config/wsgi.py | 1 + {{cookiecutter.project_slug}}/docs/conf.py | 1 + {{cookiecutter.project_slug}}/manage.py | 3 +- .../merge_production_dotenvs_in_dotenv.py | 1 + .../tests/__init__.py | 0 .../{{cookiecutter.project_slug}}/__init__.py | 5 ++- .../{{cookiecutter.project_slug}}/conftest.py | 4 +-- .../contrib/sites/migrations/0001_initial.py | 5 +-- .../migrations/0002_alter_domain_unique.py | 3 +- .../0003_set_site_domain_and_name.py | 2 +- .../users/adapters.py | 16 +++++++-- .../users/admin.py | 6 ++-- .../users/api/serializers.py | 1 - .../users/api/views.py | 4 ++- .../users/apps.py | 6 ++-- .../users/managers.py | 9 +++-- .../users/migrations/0001_initial.py | 13 +++---- .../users/models.py | 13 ++++--- .../users/tests/factories.py | 5 +-- .../users/tests/test_admin.py | 24 ++++++------- .../users/tests/test_drf_urls.py | 12 +++++-- .../users/tests/test_drf_views.py | 4 +-- .../users/tests/test_forms.py | 2 +- .../users/tests/test_managers.py | 10 +++--- .../users/tests/test_swagger.py | 10 +++--- .../users/tests/test_tasks.py | 5 +-- .../users/tests/test_urls.py | 8 +++-- .../users/tests/test_views.py | 17 +++++----- .../users/urls.py | 8 ++--- .../users/views.py | 7 ++-- 38 files changed, 204 insertions(+), 128 deletions(-) create mode 100644 {{cookiecutter.project_slug}}/tests/__init__.py diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 31d006be..b744a986 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -180,28 +180,25 @@ def test_project_generation(cookies, context, context_override): @pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) -def test_flake8_passes(cookies, context_override): - """Generated project should pass flake8.""" +def test_ruff_check_passes(cookies, context_override): + """Generated project should pass ruff check.""" result = cookies.bake(extra_context=context_override) try: - sh.flake8(_cwd=str(result.project_path)) + sh.ruff("check", ".", _cwd=str(result.project_path)) except sh.ErrorReturnCode as e: pytest.fail(e.stdout.decode()) @auto_fixable @pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id) -def test_black_passes(cookies, context_override): - """Check whether generated project passes black style.""" +def test_ruff_format_passes(cookies, context_override): + """Check whether generated project passes ruff format.""" result = cookies.bake(extra_context=context_override) try: - sh.black( - "--check", - "--diff", - "--exclude", - "migrations", + sh.ruff( + "format", ".", _cwd=str(result.project_path), ) @@ -287,7 +284,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip with open(f"{result.project_path}/.travis.yml") as travis_yml: try: yml = yaml.safe_load(travis_yml)["jobs"]["include"] - assert yml[0]["script"] == ["flake8"] + assert yml[0]["script"] == ["ruff check ."] assert yml[1]["script"] == [expected_test_script] except yaml.YAMLError as e: pytest.fail(str(e)) diff --git a/{{cookiecutter.project_slug}}/config/api_router.py b/{{cookiecutter.project_slug}}/config/api_router.py index 743069b2..d4de098f 100644 --- a/{{cookiecutter.project_slug}}/config/api_router.py +++ b/{{cookiecutter.project_slug}}/config/api_router.py @@ -1,12 +1,10 @@ from django.conf import settings -from rest_framework.routers import DefaultRouter, SimpleRouter +from rest_framework.routers import DefaultRouter +from rest_framework.routers import SimpleRouter from {{ cookiecutter.project_slug }}.users.api.views import UserViewSet -if settings.DEBUG: - router = DefaultRouter() -else: - router = SimpleRouter() +router = DefaultRouter() if settings.DEBUG else SimpleRouter() router.register("users", UserViewSet) diff --git a/{{cookiecutter.project_slug}}/config/asgi.py b/{{cookiecutter.project_slug}}/config/asgi.py index c391bf87..edfffbbc 100644 --- a/{{cookiecutter.project_slug}}/config/asgi.py +++ b/{{cookiecutter.project_slug}}/config/asgi.py @@ -1,3 +1,4 @@ +# ruff: noqa """ ASGI config for {{ cookiecutter.project_name }} project. @@ -29,7 +30,7 @@ django_application = get_asgi_application() # application = HelloWorldApplication(application) # Import websocket application here, so apps from django_application are loaded first -from config.websocket import websocket_application # noqa isort:skip +from config.websocket import websocket_application async def application(scope, receive, send): @@ -38,4 +39,5 @@ async def application(scope, receive, send): elif scope["type"] == "websocket": await websocket_application(scope, receive, send) else: - raise NotImplementedError(f"Unknown scope type {scope['type']}") + msg = f"Unknown scope type {scope['type']}" + raise NotImplementedError(msg) diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index 3bf3a73c..55a064e7 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -1,3 +1,4 @@ +# ruff: noqa: ERA001, E501 """Base settings to build other settings files upon.""" from pathlib import Path @@ -136,7 +137,9 @@ PASSWORD_HASHERS = [ ] # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ - {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, @@ -209,7 +212,7 @@ TEMPLATES = [ "{{cookiecutter.project_slug}}.users.context_processors.allauth_settings", ], }, - } + }, ] # https://docs.djangoproject.com/en/dev/ref/settings/#form-renderer @@ -273,7 +276,7 @@ LOGGING = { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose", - } + }, }, "root": {"level": "INFO", "handlers": ["console"]}, } @@ -379,7 +382,7 @@ WEBPACK_LOADER = { "STATS_FILE": BASE_DIR / "webpack-stats.json", "POLL_INTERVAL": 0.1, "IGNORE": [r".+\.hot-update.js", r".+\.map"], - } + }, } {%- endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index 0304d6cd..f1edb514 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -1,4 +1,10 @@ -from .base import * # noqa +# ruff: noqa: E501 +from .base import * # noqa: F403 +from .base import INSTALLED_APPS +from .base import MIDDLEWARE +{%- if cookiecutter.frontend_pipeline == 'Webpack' %} +from .base import WEBPACK_LOADER +{%- endif %} from .base import env # GENERAL @@ -11,7 +17,7 @@ SECRET_KEY = env( default="!!!SET DJANGO_SECRET_KEY!!!", ) # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] +ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] # noqa: S104 # CACHES # ------------------------------------------------------------------------------ @@ -20,7 +26,7 @@ CACHES = { "default": { "BACKEND": "django.core.cache.backends.locmem.LocMemCache", "LOCATION": "", - } + }, } # EMAIL @@ -37,7 +43,9 @@ EMAIL_HOST = "localhost" EMAIL_PORT = 1025 {%- else -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend -EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend") +EMAIL_BACKEND = env( + "DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend", +) {%- endif %} {%- if cookiecutter.use_whitenoise == 'y' %} @@ -45,15 +53,15 @@ EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.c # WhiteNoise # ------------------------------------------------------------------------------ # http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development -INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa: F405 +INSTALLED_APPS = ["whitenoise.runserver_nostatic", *INSTALLED_APPS] {% endif %} # django-debug-toolbar # ------------------------------------------------------------------------------ # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites -INSTALLED_APPS += ["debug_toolbar"] # noqa: F405 +INSTALLED_APPS += ["debug_toolbar"] # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware -MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa: F405 +MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config DEBUG_TOOLBAR_CONFIG = { "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], @@ -80,7 +88,7 @@ if env("USE_DOCKER") == "yes": # django-extensions # ------------------------------------------------------------------------------ # https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration -INSTALLED_APPS += ["django_extensions"] # noqa: F405 +INSTALLED_APPS += ["django_extensions"] {% if cookiecutter.use_celery == 'y' -%} # Celery @@ -96,7 +104,7 @@ CELERY_TASK_EAGER_PROPAGATES = True {%- if cookiecutter.frontend_pipeline == 'Webpack' %} # django-webpack-loader # ------------------------------------------------------------------------------ -WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG # noqa: F405 +WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG {%- endif %} # Your stuff... diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 7f629357..0cebe1d9 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -1,3 +1,4 @@ +# ruff: noqa: E501 {% if cookiecutter.use_sentry == 'y' -%} import logging @@ -12,7 +13,12 @@ from sentry_sdk.integrations.logging import LoggingIntegration from sentry_sdk.integrations.redis import RedisIntegration {% endif -%} -from .base import * # noqa +from .base import * # noqa: F403 +from .base import DATABASES +from .base import INSTALLED_APPS +{%- if cookiecutter.use_drf == "y" %} +from .base import SPECTACULAR_SETTINGS +{%- endif %} from .base import env # GENERAL @@ -24,7 +30,7 @@ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["{{ cookiecutter.domai # DATABASES # ------------------------------------------------------------------------------ -DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa: F405 +DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # CACHES # ------------------------------------------------------------------------------ @@ -38,7 +44,7 @@ CACHES = { # https://github.com/jazzband/django-redis#memcached-exceptions-behavior "IGNORE_EXCEPTIONS": True, }, - } + }, } # SECURITY @@ -56,17 +62,23 @@ CSRF_COOKIE_SECURE = True # TODO: set this to 60 seconds first and then to 518400 once you prove the former works SECURE_HSTS_SECONDS = 60 # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains -SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool("DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True) +SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool( + "DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", + default=True, +) # https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True) # https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff -SECURE_CONTENT_TYPE_NOSNIFF = env.bool("DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True) +SECURE_CONTENT_TYPE_NOSNIFF = env.bool( + "DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", + default=True, +) {% if cookiecutter.cloud_provider != 'None' -%} # STORAGES # ------------------------------------------------------------------------------ # https://django-storages.readthedocs.io/en/latest/#installation -INSTALLED_APPS += ["storages"] # noqa: F405 +INSTALLED_APPS += ["storages"] {%- endif -%} {% if cookiecutter.cloud_provider == 'AWS' %} # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings @@ -197,7 +209,7 @@ ADMIN_URL = env("DJANGO_ADMIN_URL") # Anymail # ------------------------------------------------------------------------------ # https://anymail.readthedocs.io/en/stable/installation/#installing-anymail -INSTALLED_APPS += ["anymail"] # noqa: F405 +INSTALLED_APPS += ["anymail"] # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend # https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference {%- if cookiecutter.mail_service == 'Mailgun' %} @@ -273,7 +285,7 @@ COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage" COMPRESS_STORAGE = STORAGES["staticfiles"]["BACKEND"] {%- endif %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL -COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa: F405{% endif %} +COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %}{% endif %} {%- if cookiecutter.use_whitenoise == 'y' %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise @@ -291,7 +303,7 @@ COMPRESS_FILTERS = { # Collectfast # ------------------------------------------------------------------------------ # https://github.com/antonagestam/collectfast#installation -INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa: F405 +INSTALLED_APPS = ["collectfast", *INSTALLED_APPS] {% endif %} # LOGGING # ------------------------------------------------------------------------------ @@ -351,7 +363,7 @@ LOGGING = { "level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose", - } + }, }, "root": {"level": "INFO", "handlers": ["console"]}, "loggers": { @@ -403,7 +415,7 @@ sentry_sdk.init( # django-rest-framework # ------------------------------------------------------------------------------- # Tools that generate code samples can use SERVERS to point to the correct domain -SPECTACULAR_SETTINGS["SERVERS"] = [ # noqa: F405 +SPECTACULAR_SETTINGS["SERVERS"] = [ {"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"}, ] diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index 7c54e021..696b4871 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -2,7 +2,8 @@ With these settings, tests run faster. """ -from .base import * # noqa +from .base import * # noqa: F403 +from .base import TEMPLATES from .base import env # GENERAL @@ -27,7 +28,7 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" # DEBUGGING FOR TEMPLATES # ------------------------------------------------------------------------------ -TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa: F405 +TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore[index] # MEDIA # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/config/urls.py b/{{cookiecutter.project_slug}}/config/urls.py index 7c5ad1a7..5d9301b6 100644 --- a/{{cookiecutter.project_slug}}/config/urls.py +++ b/{{cookiecutter.project_slug}}/config/urls.py @@ -1,27 +1,37 @@ +# ruff: noqa from django.conf import settings from django.conf.urls.static import static from django.contrib import admin {%- if cookiecutter.use_async == 'y' %} from django.contrib.staticfiles.urls import staticfiles_urlpatterns {%- endif %} -from django.urls import include, path +from django.urls import include +from django.urls import path from django.views import defaults as default_views from django.views.generic import TemplateView {%- if cookiecutter.use_drf == 'y' %} -from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView +from drf_spectacular.views import SpectacularAPIView +from drf_spectacular.views import SpectacularSwaggerView from rest_framework.authtoken.views import obtain_auth_token {%- endif %} urlpatterns = [ path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), - path("about/", TemplateView.as_view(template_name="pages/about.html"), name="about"), + path( + "about/", + TemplateView.as_view(template_name="pages/about.html"), + name="about", + ), # Django Admin, use {% raw %}{% url 'admin:index' %}{% endraw %} path(settings.ADMIN_URL, admin.site.urls), # User management path("users/", include("{{ cookiecutter.project_slug }}.users.urls", namespace="users")), path("accounts/", include("allauth.urls")), # Your stuff: custom urls includes go here -] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + # ... + # Media files + *static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT), +] {%- if cookiecutter.use_async == 'y' %} if settings.DEBUG: # Static file serving when using Gunicorn + Uvicorn for local web socket development diff --git a/{{cookiecutter.project_slug}}/config/wsgi.py b/{{cookiecutter.project_slug}}/config/wsgi.py index 1dbd8a8d..73a6cddc 100644 --- a/{{cookiecutter.project_slug}}/config/wsgi.py +++ b/{{cookiecutter.project_slug}}/config/wsgi.py @@ -1,3 +1,4 @@ +# ruff: noqa """ WSGI config for {{ cookiecutter.project_name }} project. diff --git a/{{cookiecutter.project_slug}}/docs/conf.py b/{{cookiecutter.project_slug}}/docs/conf.py index c640e1c6..40d59dbb 100644 --- a/{{cookiecutter.project_slug}}/docs/conf.py +++ b/{{cookiecutter.project_slug}}/docs/conf.py @@ -1,3 +1,4 @@ +# ruff: noqa # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full diff --git a/{{cookiecutter.project_slug}}/manage.py b/{{cookiecutter.project_slug}}/manage.py index c44cc826..a3987181 100755 --- a/{{cookiecutter.project_slug}}/manage.py +++ b/{{cookiecutter.project_slug}}/manage.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# ruff: noqa import os import sys from pathlib import Path @@ -13,7 +14,7 @@ if __name__ == "__main__": # issue is really that Django is missing to avoid masking other # exceptions on Python 2. try: - import django # noqa + import django except ImportError: raise ImportError( "Couldn't import Django. Are you sure it's installed and " diff --git a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py index 35139fb2..c83ed716 100644 --- a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py +++ b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py @@ -1,3 +1,4 @@ +# ruff: noqa import os from collections.abc import Sequence from pathlib import Path diff --git a/{{cookiecutter.project_slug}}/tests/__init__.py b/{{cookiecutter.project_slug}}/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py index 150a914e..fb653270 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py @@ -1,2 +1,5 @@ __version__ = "{{ cookiecutter.version }}" -__version_info__ = tuple(int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split(".")) +__version_info__ = tuple( + int(num) if num.isdigit() else num + for num in __version__.replace("-", ".", 1).split(".") +) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py index 7095a471..98efcd75 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py @@ -5,10 +5,10 @@ from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory @pytest.fixture(autouse=True) -def media_storage(settings, tmpdir): +def _media_storage(settings, tmpdir) -> None: settings.MEDIA_ROOT = tmpdir.strpath -@pytest.fixture +@pytest.fixture() def user(db) -> User: return UserFactory() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py index 304cd6d7..fd76afb2 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0001_initial.py @@ -1,6 +1,7 @@ import django.contrib.sites.models from django.contrib.sites.models import _simple_domain_name_validator -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): @@ -38,5 +39,5 @@ class Migration(migrations.Migration): }, bases=(models.Model,), managers=[("objects", django.contrib.sites.models.SiteManager())], - ) + ), ] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py index 2c8d6dac..4a44a6a9 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0002_alter_domain_unique.py @@ -1,5 +1,6 @@ import django.contrib.sites.models -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): 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 e1822375..85ee2d9c 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 @@ -23,7 +23,7 @@ def _update_or_create_site_with_sequence(site_model, connection, domain, name): # site is created. # To avoid this, we need to manually update DB sequence and make sure it's # greater than the maximum value. - max_id = site_model.objects.order_by('-id').first().id + max_id = site_model.objects.order_by("-id").first().id with connection.cursor() as cursor: cursor.execute("SELECT last_value from django_site_id_seq") (current_id,) = cursor.fetchone() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py index f9ae43a8..484f686a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py @@ -5,10 +5,11 @@ import typing from allauth.account.adapter import DefaultAccountAdapter from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from django.conf import settings -from django.http import HttpRequest if typing.TYPE_CHECKING: from allauth.socialaccount.models import SocialLogin + from django.http import HttpRequest + from {{cookiecutter.project_slug}}.users.models import User @@ -18,10 +19,19 @@ class AccountAdapter(DefaultAccountAdapter): class SocialAccountAdapter(DefaultSocialAccountAdapter): - def is_open_for_signup(self, request: HttpRequest, sociallogin: SocialLogin) -> bool: + def is_open_for_signup( + self, + request: HttpRequest, + sociallogin: SocialLogin, + ) -> bool: return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) - def populate_user(self, request: HttpRequest, sociallogin: SocialLogin, data: dict[str, typing.Any]) -> User: + def populate_user( + self, + request: HttpRequest, + sociallogin: SocialLogin, + data: dict[str, typing.Any], + ) -> User: """ Populates user information from social provider info. diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py index 7fd49fa9..9d6c7562 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py @@ -1,10 +1,12 @@ from django.conf import settings from django.contrib import admin from django.contrib.auth import admin as auth_admin -from django.contrib.auth import get_user_model, decorators +from django.contrib.auth import decorators +from django.contrib.auth import get_user_model from django.utils.translation import gettext_lazy as _ -from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm, UserAdminCreationForm +from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm +from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm User = get_user_model() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py index 0872d06f..ef2adb91 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py @@ -3,7 +3,6 @@ from rest_framework import serializers from {{ cookiecutter.project_slug }}.users.models import User as UserType - User = get_user_model() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py index 508431e4..8bdf24b0 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py @@ -1,7 +1,9 @@ from django.contrib.auth import get_user_model from rest_framework import status from rest_framework.decorators import action -from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, UpdateModelMixin +from rest_framework.mixins import ListModelMixin +from rest_framework.mixins import RetrieveModelMixin +from rest_framework.mixins import UpdateModelMixin from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py index 92e7a74e..5c3d4fe0 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/apps.py @@ -1,3 +1,5 @@ +import contextlib + from django.apps import AppConfig from django.utils.translation import gettext_lazy as _ @@ -7,7 +9,5 @@ class UsersConfig(AppConfig): verbose_name = _("Users") def ready(self): - try: + with contextlib.suppress(ImportError): import {{ cookiecutter.project_slug }}.users.signals # noqa: F401 - except ImportError: - pass diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py index 03ac2954..c75c0e97 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py @@ -15,7 +15,8 @@ class UserManager(DjangoUserManager["User"]): Create and save a user with the given email and password. """ if not email: - raise ValueError("The given email must be set") + msg = "The given email must be set" + raise ValueError(msg) email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.password = make_password(password) @@ -32,8 +33,10 @@ class UserManager(DjangoUserManager["User"]): extra_fields.setdefault("is_superuser", True) if extra_fields.get("is_staff") is not True: - raise ValueError("Superuser must have is_staff=True.") + msg = "Superuser must have is_staff=True." + raise ValueError(msg) if extra_fields.get("is_superuser") is not True: - raise ValueError("Superuser must have is_superuser=True.") + msg = "Superuser must have is_superuser=True." + raise ValueError(msg) return self._create_user(email, password, **extra_fields) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py index 58a439c5..cee6676b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py @@ -1,7 +1,8 @@ import django.contrib.auth.models import django.contrib.auth.validators -from django.db import migrations, models import django.utils.timezone +from django.db import migrations +from django.db import models import {{cookiecutter.project_slug}}.users.models @@ -31,7 +32,7 @@ class Migration(migrations.Migration): ( "last_login", models.DateTimeField( - blank=True, null=True, verbose_name="last login" + blank=True, null=True, verbose_name="last login", ), ), ( @@ -61,14 +62,14 @@ class Migration(migrations.Migration): ( "email", models.EmailField( - blank=True, max_length=254, verbose_name="email address" + blank=True, max_length=254, verbose_name="email address", ), ), {%- else %} ( "email", models.EmailField( - unique=True, max_length=254, verbose_name="email address" + unique=True, max_length=254, verbose_name="email address", ), ), {%- endif %} @@ -91,13 +92,13 @@ class Migration(migrations.Migration): ( "date_joined", models.DateTimeField( - default=django.utils.timezone.now, verbose_name="date joined" + default=django.utils.timezone.now, verbose_name="date joined", ), ), ( "name", models.CharField( - blank=True, max_length=255, verbose_name="Name of User" + blank=True, max_length=255, verbose_name="Name of User", ), ), ( diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py index ccb6b78a..fd78c26a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py @@ -1,9 +1,12 @@ {%- if cookiecutter.username_type == "email" %} from typing import ClassVar -{%- endif %} +{% endif -%} from django.contrib.auth.models import AbstractUser -from django.db.models import CharField{% if cookiecutter.username_type == "email" %}, EmailField{% endif %} +from django.db.models import CharField +{%- if cookiecutter.username_type == "email" %} +from django.db.models import EmailField +{%- endif %} from django.urls import reverse from django.utils.translation import gettext_lazy as _ {%- if cookiecutter.username_type == "email" %} @@ -21,11 +24,11 @@ class User(AbstractUser): # First and last name do not cover name patterns around the globe name = CharField(_("Name of User"), blank=True, max_length=255) - first_name = None # type: ignore - last_name = None # type: ignore + first_name = None # type: ignore[assignment] + last_name = None # type: ignore[assignment] {%- if cookiecutter.username_type == "email" %} email = EmailField(_("email address"), unique=True) - username = None # type: ignore + username = None # type: ignore[assignment] USERNAME_FIELD = "email" REQUIRED_FIELDS = [] 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 bebd8adc..f614681b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -2,7 +2,8 @@ from collections.abc import Sequence from typing import Any from django.contrib.auth import get_user_model -from factory import Faker, post_generation +from factory import Faker +from factory import post_generation from factory.django import DjangoModelFactory @@ -14,7 +15,7 @@ class UserFactory(DjangoModelFactory): name = Faker("name") @post_generation - def password(self, create: bool, extracted: Sequence[Any], **kwargs): + def password(self, create: bool, extracted: Sequence[Any], **kwargs): # noqa: FBT001 password = ( extracted if extracted 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 095b2cbb..f802b8ba 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,3 +1,5 @@ +import contextlib +from http import HTTPStatus from importlib import reload import pytest @@ -13,17 +15,17 @@ class TestUserAdmin: def test_changelist(self, admin_client): url = reverse("admin:users_user_changelist") response = admin_client.get(url) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK def test_search(self, admin_client): url = reverse("admin:users_user_changelist") response = admin_client.get(url, data={"q": "test"}) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK def test_add(self, admin_client): url = reverse("admin:users_user_add") response = admin_client.get(url) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK response = admin_client.post( url, @@ -37,7 +39,7 @@ class TestUserAdmin: "password2": "My_R@ndom-P@ssw0rd", }, ) - assert response.status_code == 302 + assert response.status_code == HTTPStatus.FOUND {%- if cookiecutter.username_type == "email" %} assert User.objects.filter(email="new-admin@example.com").exists() {%- else %} @@ -52,21 +54,19 @@ class TestUserAdmin: {%- endif %} url = reverse("admin:users_user_change", kwargs={"object_id": user.pk}) response = admin_client.get(url) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK - @pytest.fixture - def force_allauth(self, settings): + @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 - try: + with contextlib.suppress(admin.sites.AlreadyRegistered): reload(users_admin) - except admin.sites.AlreadyRegistered: - pass - @pytest.mark.django_db - @pytest.mark.usefixtures("force_allauth") + @pytest.mark.django_db() + @pytest.mark.usefixtures("_force_allauth") def test_allauth_login(self, rf, settings): request = rf.get("/fake-url") request.user = AnonymousUser() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py index 334ab118..b445b611 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py @@ -1,14 +1,20 @@ -from django.urls import resolve, reverse +from django.urls import resolve +from django.urls import reverse from {{ cookiecutter.project_slug }}.users.models import User def test_user_detail(user: User): {%- if cookiecutter.username_type == "email" %} - assert reverse("api:user-detail", kwargs={"pk": user.pk}) == f"/api/users/{user.pk}/" + assert ( + reverse("api:user-detail", kwargs={"pk": user.pk}) == f"/api/users/{user.pk}/" + ) assert resolve(f"/api/users/{user.pk}/").view_name == "api:user-detail" {%- else %} - assert reverse("api:user-detail", kwargs={"username": user.username}) == f"/api/users/{user.username}/" + assert ( + reverse("api:user-detail", kwargs={"username": user.username}) + == f"/api/users/{user.username}/" + ) assert resolve(f"/api/users/{user.username}/").view_name == "api:user-detail" {%- endif %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py index 90e84dc7..955ebe4e 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py @@ -6,7 +6,7 @@ from {{ cookiecutter.project_slug }}.users.models import User class TestUserViewSet: - @pytest.fixture + @pytest.fixture() def api_rf(self) -> APIRequestFactory: return APIRequestFactory() @@ -26,7 +26,7 @@ class TestUserViewSet: view.request = request - response = view.me(request) # type: ignore + response = view.me(request) # type: ignore[call-arg, arg-type, misc] assert response.data == { {%- if cookiecutter.username_type == "email" %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py index ca624c89..17d0d72a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py @@ -30,7 +30,7 @@ class TestUserAdminCreationForm: {%- endif %} "password1": user.password, "password2": user.password, - } + }, ) assert not form.is_valid() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_managers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_managers.py index f25af4ee..e5e5f5a4 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_managers.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_managers.py @@ -6,12 +6,12 @@ from django.core.management import call_command from {{ cookiecutter.project_slug }}.users.models import User -@pytest.mark.django_db +@pytest.mark.django_db() class TestUserManager: def test_create_user(self): user = User.objects.create_user( email="john@example.com", - password="something-r@nd0m!", + password="something-r@nd0m!", # noqa: S106 ) assert user.email == "john@example.com" assert not user.is_staff @@ -22,7 +22,7 @@ class TestUserManager: def test_create_superuser(self): user = User.objects.create_superuser( email="admin@example.com", - password="something-r@nd0m!", + password="something-r@nd0m!", # noqa: S106 ) assert user.email == "admin@example.com" assert user.is_staff @@ -32,12 +32,12 @@ class TestUserManager: def test_create_superuser_username_ignored(self): user = User.objects.create_superuser( email="test@example.com", - password="something-r@nd0m!", + password="something-r@nd0m!", # noqa: S106 ) assert user.username is None -@pytest.mark.django_db +@pytest.mark.django_db() def test_createsuperuser_command(): """Ensure createsuperuser command works with our custom manager.""" out = StringIO() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py index f97658b5..3081d1f6 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py @@ -1,3 +1,5 @@ +from http import HTTPStatus + import pytest from django.urls import reverse @@ -5,17 +7,17 @@ from django.urls import reverse def test_swagger_accessible_by_admin(admin_client): url = reverse("api-docs") response = admin_client.get(url) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK -@pytest.mark.django_db +@pytest.mark.django_db() def test_swagger_ui_not_accessible_by_normal_user(client): url = reverse("api-docs") response = client.get(url) - assert response.status_code == 403 + assert response.status_code == HTTPStatus.FORBIDDEN def test_api_schema_generated_successfully(admin_client): url = reverse("api-schema") response = admin_client.get(url) - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_tasks.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_tasks.py index 41d5af29..d3f61013 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_tasks.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_tasks.py @@ -9,8 +9,9 @@ pytestmark = pytest.mark.django_db def test_user_count(settings): """A basic test to execute the get_users_count Celery task.""" - UserFactory.create_batch(3) + batch_size = 3 + UserFactory.create_batch(batch_size) settings.CELERY_TASK_ALWAYS_EAGER = True task_result = get_users_count.delay() assert isinstance(task_result, EagerResult) - assert task_result.result == 3 + assert task_result.result == batch_size diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py index a0d06889..aaacb05a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py @@ -1,4 +1,5 @@ -from django.urls import resolve, reverse +from django.urls import resolve +from django.urls import reverse from {{ cookiecutter.project_slug }}.users.models import User @@ -8,7 +9,10 @@ def test_detail(user: User): assert reverse("users:detail", kwargs={"pk": user.pk}) == f"/users/{user.pk}/" assert resolve(f"/users/{user.pk}/").view_name == "users:detail" {%- else %} - assert reverse("users:detail", kwargs={"username": user.username}) == f"/users/{user.username}/" + assert ( + reverse("users:detail", kwargs={"username": user.username}) + == f"/users/{user.username}/" + ) assert resolve(f"/users/{user.username}/").view_name == "users:detail" {%- endif %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py index 2c102703..136daa40 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py @@ -1,10 +1,13 @@ +from http import HTTPStatus + import pytest from django.conf import settings from django.contrib import messages from django.contrib.auth.models import AnonymousUser from django.contrib.messages.middleware import MessageMiddleware from django.contrib.sessions.middleware import SessionMiddleware -from django.http import HttpRequest, HttpResponseRedirect +from django.http import HttpRequest +from django.http import HttpResponseRedirect from django.test import RequestFactory from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -12,11 +15,9 @@ from django.utils.translation import gettext_lazy as _ from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm from {{ cookiecutter.project_slug }}.users.models import User from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory -from {{ cookiecutter.project_slug }}.users.views import ( - UserRedirectView, - UserUpdateView, - user_detail_view, -) +from {{ cookiecutter.project_slug }}.users.views import UserRedirectView +from {{ cookiecutter.project_slug }}.users.views import UserUpdateView +from {{ cookiecutter.project_slug }}.users.views import user_detail_view pytestmark = pytest.mark.django_db @@ -102,7 +103,7 @@ class TestUserDetailView: response = user_detail_view(request, username=user.username) {%- endif %} - assert response.status_code == 200 + assert response.status_code == HTTPStatus.OK def test_not_authenticated(self, user: User, rf: RequestFactory): request = rf.get("/fake-url/") @@ -116,5 +117,5 @@ class TestUserDetailView: login_url = reverse(settings.LOGIN_URL) assert isinstance(response, HttpResponseRedirect) - assert response.status_code == 302 + assert response.status_code == HTTPStatus.FOUND assert response.url == f"{login_url}?next=/fake-url/" diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py index 0ffca17a..40719ed2 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py @@ -1,10 +1,8 @@ from django.urls import path -from {{ cookiecutter.project_slug }}.users.views import ( - user_detail_view, - user_redirect_view, - user_update_view, -) +from {{ cookiecutter.project_slug }}.users.views import user_detail_view +from {{ cookiecutter.project_slug }}.users.views import user_redirect_view +from {{ cookiecutter.project_slug }}.users.views import user_update_view app_name = "users" urlpatterns = [ diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index 82498e63..6d26e9c7 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -3,7 +3,9 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse from django.utils.translation import gettext_lazy as _ -from django.views.generic import DetailView, RedirectView, UpdateView +from django.views.generic import DetailView +from django.views.generic import RedirectView +from django.views.generic import UpdateView User = get_user_model() @@ -28,7 +30,8 @@ class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): success_message = _("Information successfully updated") def get_success_url(self): - assert self.request.user.is_authenticated # for mypy to know that the user is authenticated + # for mypy to know that the user is authenticated + assert self.request.user.is_authenticated return self.request.user.get_absolute_url() def get_object(self): From 9a5b9c2f53e8b5f685bb04592354778c07b170e9 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Tue, 13 Feb 2024 12:05:49 +0000 Subject: [PATCH 21/47] Update sentry-sdk from 1.40.3 to 1.40.4 --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index b6e793e1..90865d0b 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.40.3 # https://github.com/getsentry/sentry-python +sentry-sdk==1.40.4 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.3.2 # https://github.com/redis/hiredis-py From bf9a861ddc34d1b746c8e4a3850389c80cccde64 Mon Sep 17 00:00:00 2001 From: github-actions Date: Wed, 14 Feb 2024 02:10:20 +0000 Subject: [PATCH 22/47] Release 2024.02.13 --- CHANGELOG.md | 19 +++++++++++++++++++ setup.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ee7a589..bf6cbe02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,25 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.13 + + +### Changed + +- Ruff linting & formatting ([#4834](https://github.com/cookiecutter/cookiecutter-django/pull/4834)) + +### Updated + +- Update uvicorn to 0.27.1 ([#4848](https://github.com/cookiecutter/cookiecutter-django/pull/4848)) + +- Update sentry-sdk to 1.40.4 ([#4858](https://github.com/cookiecutter/cookiecutter-django/pull/4858)) + +- Bump traefik to 2.11.0 ([#4857](https://github.com/cookiecutter/cookiecutter-django/pull/4857)) + +- Auto-update pre-commit hooks ([#4855](https://github.com/cookiecutter/cookiecutter-django/pull/4855)) + +- Update black to 24.2.0 ([#4853](https://github.com/cookiecutter/cookiecutter-django/pull/4853)) + ## 2024.02.12 diff --git a/setup.py b/setup.py index 7c129824..bb08c3b4 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.12" +version = "2024.02.13" with open("README.md") as readme_file: long_description = readme_file.read() From fd959eedd93b95e6200c51e226edaf7773182857 Mon Sep 17 00:00:00 2001 From: mpsantos Date: Fri, 16 Feb 2024 06:52:55 -0300 Subject: [PATCH 23/47] Added link to the ruff repository (#4866) --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index da0e0494..fb0eda72 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -28,7 +28,7 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -ruff==0.2.1 +ruff==0.2.1 # https://github.com/astral-sh/ruff coverage==7.4.1 # https://github.com/nedbat/coveragepy djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint pre-commit==3.6.1 # https://github.com/pre-commit/pre-commit From 6237573637d09406bdd93d564e6999d4ec3d3f89 Mon Sep 17 00:00:00 2001 From: Paul Wulff <121822604+mtmpaulwulff@users.noreply.github.com> Date: Fri, 16 Feb 2024 10:55:24 +0100 Subject: [PATCH 24/47] Speed up CI pytest by 30%: Change ci.yml to only build images relevant for running pytest (#4863) In order to run pytest we can constrain the build command to only build the images related to the django service. This mainly prevents the docs image from being built unnecessarily. This cuts run time of the Github Actions workflow from approx. 4min 30s to below 3min. --- {{cookiecutter.project_slug}}/.github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index e39933fe..414ee1e6 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: - name: Run pre-commit uses: pre-commit/action@v3.0.0 - # With no caching at all the entire ci process takes 4m 30s to complete! + # With no caching at all the entire ci process takes 3m to complete! pytest: runs-on: ubuntu-latest {%- if cookiecutter.use_docker == 'n' %} @@ -69,7 +69,7 @@ jobs: {%- if cookiecutter.use_docker == 'y' %} - name: Build the Stack - run: docker compose -f local.yml build + run: docker compose -f local.yml build django - name: Run DB Migrations run: docker compose -f local.yml run --rm django python manage.py migrate From 80147bd3404d0938983b62c7031a89e6a0765f6e Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 16 Feb 2024 09:55:59 +0000 Subject: [PATCH 25/47] Update Contributors --- .github/contributors.json | 5 +++++ CONTRIBUTORS.md | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/.github/contributors.json b/.github/contributors.json index c95797b1..596f2af8 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1518,5 +1518,10 @@ "name": "henningbra", "github_login": "henningbra", "twitter_username": "" + }, + { + "name": "Paul Wulff", + "github_login": "mtmpaulwulff", + "twitter_username": "" } ] \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7b778f43..9a59b657 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1650,6 +1650,13 @@ Listed in alphabetical order. + + Paul Wulff + + mtmpaulwulff + + + Pawan Chaurasia From f77233d7c0940208eda61fc680d642e745175076 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Fri, 16 Feb 2024 02:14:57 -0800 Subject: [PATCH 26/47] Update gitpython to 3.1.42 (#4864) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3de15dc6..c0385c69 100644 --- a/requirements.txt +++ b/requirements.txt @@ -21,6 +21,6 @@ pyyaml==6.0.1 # Scripting # ------------------------------------------------------------------------------ PyGithub==2.2.0 -gitpython==3.1.41 +gitpython==3.1.42 jinja2==3.1.3 requests==2.31.0 From cb0e06dcbdc72f2e5e6c5a39e16601e2721b806a Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 17 Feb 2024 02:09:39 +0000 Subject: [PATCH 27/47] Release 2024.02.16 --- CHANGELOG.md | 11 +++++++++++ setup.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf6cbe02..f0ef0783 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.16 + + +### Changed + +- Speed up GitHub CI for Docker setup ([#4863](https://github.com/cookiecutter/cookiecutter-django/pull/4863)) + +### Documentation + +- Add link to the ruff repository in requirements ([#4866](https://github.com/cookiecutter/cookiecutter-django/pull/4866)) + ## 2024.02.13 diff --git a/setup.py b/setup.py index bb08c3b4..b5b99977 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.13" +version = "2024.02.16" with open("README.md") as readme_file: long_description = readme_file.read() From dea7316a629c18ac235e3ce26178fe48eb74cd4e Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Sat, 17 Feb 2024 02:25:34 -0800 Subject: [PATCH 28/47] Update tox to 4.13.0 (#4868) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c0385c69..17a01d59 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ pre-commit==3.6.1 # Testing # ------------------------------------------------------------------------------ -tox==4.12.1 +tox==4.13.0 pytest==8.0.0 pytest-xdist==3.5.0 pytest-cookies==0.7.0 From 7db193d9fac5f862f546c13444b1e676a25c3783 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Sat, 17 Feb 2024 02:39:05 -0800 Subject: [PATCH 29/47] Update pytest to 8.0.1 (#4870) * Update pytest from 8.0.0 to 8.0.1 * Update pytest from 8.0.0 to 8.0.1 --- requirements.txt | 2 +- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 17a01d59..077ce3f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,7 +12,7 @@ pre-commit==3.6.1 # Testing # ------------------------------------------------------------------------------ tox==4.13.0 -pytest==8.0.0 +pytest==8.0.1 pytest-xdist==3.5.0 pytest-cookies==0.7.0 pytest-instafail==0.5.0 diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index fb0eda72..4c142ff6 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -15,7 +15,7 @@ watchfiles==0.21.0 # https://github.com/samuelcolvin/watchfiles # ------------------------------------------------------------------------------ mypy==1.7.1 # https://github.com/python/mypy django-stubs[compatible-mypy]==4.2.7 # https://github.com/typeddjango/django-stubs -pytest==8.0.0 # https://github.com/pytest-dev/pytest +pytest==8.0.1 # https://github.com/pytest-dev/pytest pytest-sugar==1.0.0 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} djangorestframework-stubs[compatible-mypy]==3.14.5 # https://github.com/typeddjango/djangorestframework-stubs From 2ac513e0c1bc6c9e66fee619fe5db8a304daf307 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 18 Feb 2024 02:11:43 +0000 Subject: [PATCH 30/47] Release 2024.02.17 --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0ef0783..8d7e382e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.17 + + +### Updated + +- Update pytest to 8.0.1 ([#4870](https://github.com/cookiecutter/cookiecutter-django/pull/4870)) + ## 2024.02.16 diff --git a/setup.py b/setup.py index b5b99977..6637e9e7 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.16" +version = "2024.02.17" with open("README.md") as readme_file: long_description = readme_file.read() From adebac5b88c337e1558ba7e90764db729b111edf Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Mon, 19 Feb 2024 08:30:11 -0800 Subject: [PATCH 31/47] Update sentry-sdk from 1.40.4 to 1.40.5 (#4876) --- {{cookiecutter.project_slug}}/requirements/production.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 90865d0b..4d96e86e 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.40.4 # https://github.com/getsentry/sentry-python +sentry-sdk==1.40.5 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.3.2 # https://github.com/redis/hiredis-py From 8c60674654fd6ce4a217e3adb86d915eee3fbc5e Mon Sep 17 00:00:00 2001 From: github-actions Date: Tue, 20 Feb 2024 02:09:27 +0000 Subject: [PATCH 32/47] Release 2024.02.19 --- CHANGELOG.md | 7 +++++++ setup.py | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d7e382e..1f9b0785 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,13 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.19 + + +### Updated + +- Update sentry-sdk to 1.40.5 ([#4876](https://github.com/cookiecutter/cookiecutter-django/pull/4876)) + ## 2024.02.17 diff --git a/setup.py b/setup.py index 6637e9e7..b29fc417 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.17" +version = "2024.02.19" with open("README.md") as readme_file: long_description = readme_file.read() From b756d904d77e992242caeba4fbd188bccfa0c782 Mon Sep 17 00:00:00 2001 From: Matthew Foster Walsh <15671892+mfosterw@users.noreply.github.com> Date: Wed, 21 Feb 2024 05:01:56 -0500 Subject: [PATCH 33/47] You probably don't need `get_user_model` (#4879) * You probably don't need `get_user_model` Fixes #4872 * Fix Flake8 (add space after import) * (try to) fix ruff * Fix import format --- .github/contributors.json | 2 +- .../{{cookiecutter.project_slug}}/users/admin.py | 8 +++----- .../users/api/serializers.py | 7 ++----- .../{{cookiecutter.project_slug}}/users/api/views.py | 5 ++--- .../{{cookiecutter.project_slug}}/users/forms.py | 3 +-- .../{{cookiecutter.project_slug}}/users/tasks.py | 5 +---- .../users/tests/factories.py | 5 +++-- .../{{cookiecutter.project_slug}}/users/views.py | 3 +-- 8 files changed, 14 insertions(+), 24 deletions(-) diff --git a/.github/contributors.json b/.github/contributors.json index 596f2af8..057309a5 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1115,7 +1115,7 @@ "twitter_username": "Qoyyuum" }, { - "name": "mfosterw", + "name": "Matthew Foster Walsh", "github_login": "mfosterw", "twitter_username": "" }, diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py index 9d6c7562..d0d1488f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py @@ -1,19 +1,17 @@ from django.conf import settings from django.contrib import admin from django.contrib.auth import admin as auth_admin -from django.contrib.auth import decorators -from django.contrib.auth import get_user_model +from django.contrib.auth.decorators import login_required from django.utils.translation import gettext_lazy as _ from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm - -User = get_user_model() +from {{ cookiecutter.project_slug }}.users.models import User if settings.DJANGO_ADMIN_FORCE_ALLAUTH: # Force the `admin` sign in process to go through the `django-allauth` workflow: # https://docs.allauth.org/en/latest/common/admin.html#admin - admin.site.login = decorators.login_required(admin.site.login) # type: ignore[method-assign] + admin.site.login = login_required(admin.site.login) # type: ignore[method-assign] @admin.register(User) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py index ef2adb91..51e0859f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py @@ -1,12 +1,9 @@ -from django.contrib.auth import get_user_model from rest_framework import serializers -from {{ cookiecutter.project_slug }}.users.models import User as UserType - -User = get_user_model() +from {{ cookiecutter.project_slug }}.users.models import User -class UserSerializer(serializers.ModelSerializer[UserType]): +class UserSerializer(serializers.ModelSerializer[User]): class Meta: model = User {%- if cookiecutter.username_type == "email" %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py index 8bdf24b0..7a521cdf 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py @@ -1,4 +1,3 @@ -from django.contrib.auth import get_user_model from rest_framework import status from rest_framework.decorators import action from rest_framework.mixins import ListModelMixin @@ -7,9 +6,9 @@ from rest_framework.mixins import UpdateModelMixin from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet -from .serializers import UserSerializer +from {{ cookiecutter.project_slug }}.users.models import User -User = get_user_model() +from .serializers import UserSerializer class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py index ac5b647d..2d18de20 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py @@ -1,13 +1,12 @@ from allauth.account.forms import SignupForm from allauth.socialaccount.forms import SignupForm as SocialSignupForm from django.contrib.auth import forms as admin_forms -from django.contrib.auth import get_user_model {%- if cookiecutter.username_type == "email" %} from django.forms import EmailField {%- endif %} from django.utils.translation import gettext_lazy as _ -User = get_user_model() +from {{ cookiecutter.project_slug }}.users.models import User class UserAdminChangeForm(admin_forms.UserChangeForm): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py index c99341c5..ecd14d2a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py @@ -1,8 +1,5 @@ -from django.contrib.auth import get_user_model - from config import celery_app - -User = get_user_model() +from {{ cookiecutter.project_slug }}.users.models import User @celery_app.task() 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 f614681b..136d0b1d 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -1,11 +1,12 @@ from collections.abc import Sequence from typing import Any -from django.contrib.auth import get_user_model from factory import Faker from factory import post_generation from factory.django import DjangoModelFactory +from {{ cookiecutter.project_slug }}.users.models import User + class UserFactory(DjangoModelFactory): {%- if cookiecutter.username_type == "username" %} @@ -38,5 +39,5 @@ class UserFactory(DjangoModelFactory): instance.save() class Meta: - model = get_user_model() + model = User django_get_or_create = ["{{cookiecutter.username_type}}"] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py index 6d26e9c7..3f20f268 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py @@ -1,4 +1,3 @@ -from django.contrib.auth import get_user_model from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.urls import reverse @@ -7,7 +6,7 @@ from django.views.generic import DetailView from django.views.generic import RedirectView from django.views.generic import UpdateView -User = get_user_model() +from {{ cookiecutter.project_slug }}.users.models import User class UserDetailView(LoginRequiredMixin, DetailView): From 4391f1da5cc44a7eec0245281716ee52c6f72938 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Wed, 21 Feb 2024 10:02:45 +0000 Subject: [PATCH 34/47] Update Contributors --- CONTRIBUTORS.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9a59b657..73490036 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1454,6 +1454,13 @@ Listed in alphabetical order. + + Matthew Foster Walsh + + mfosterw + + + Matthew Sisley @@ -1489,13 +1496,6 @@ Listed in alphabetical order. - - mfosterw - - mfosterw - - - Michael Gecht From 8031a2a51a1558a9266701d618fba18b80a6c4fb Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Wed, 21 Feb 2024 05:37:47 -0800 Subject: [PATCH 35/47] Update ruff to 0.2.2 (#4871) * Update ruff from 0.2.1 to 0.2.2 * Update ruff from 0.2.1 to 0.2.2 --- requirements.txt | 2 +- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 077ce3f7..2a29b915 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -ruff==0.2.1 +ruff==0.2.2 django-upgrade==1.16.0 djlint==1.34.1 pre-commit==3.6.1 diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 4c142ff6..b91e431b 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -28,7 +28,7 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -ruff==0.2.1 # https://github.com/astral-sh/ruff +ruff==0.2.2 # https://github.com/astral-sh/ruff coverage==7.4.1 # https://github.com/nedbat/coveragepy djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint pre-commit==3.6.1 # https://github.com/pre-commit/pre-commit From c6bd47a1bf36126628db4e855a84bc0214ff6a65 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Wed, 21 Feb 2024 05:38:02 -0800 Subject: [PATCH 36/47] Update pre-commit to 3.6.2 (#4874) * Update pre-commit from 3.6.1 to 3.6.2 * Update pre-commit from 3.6.1 to 3.6.2 --- requirements.txt | 2 +- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2a29b915..3635390f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ binaryornot==0.4.4 ruff==0.2.2 django-upgrade==1.16.0 djlint==1.34.1 -pre-commit==3.6.1 +pre-commit==3.6.2 # Testing # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index b91e431b..8225dab0 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -31,7 +31,7 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild ruff==0.2.2 # https://github.com/astral-sh/ruff coverage==7.4.1 # https://github.com/nedbat/coveragepy djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint -pre-commit==3.6.1 # https://github.com/pre-commit/pre-commit +pre-commit==3.6.2 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ From 70cde064d431bbb6bf1b8fa82bb70503bb80a1d3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:18:53 +0000 Subject: [PATCH 37/47] Auto-update pre-commit hooks (#4873) Co-authored-by: browniebroke <861044+browniebroke@users.noreply.github.com> Co-authored-by: Bruno Alla --- .pre-commit-config.yaml | 2 +- {{cookiecutter.project_slug}}/.pre-commit-config.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7daf6ac7..6355c5ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,7 +26,7 @@ repos: args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + rev: v3.15.1 hooks: - id: pyupgrade args: [--py311-plus] diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 7c9565e1..1d06c042 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -35,7 +35,7 @@ repos: # Run the Ruff linter. - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.2.1 + rev: v0.2.2 hooks: # Linter - id: ruff From a247d8f8a20344dd3388e5d81f758b5fe4cefa65 Mon Sep 17 00:00:00 2001 From: Matthew Foster Walsh <15671892+mfosterw@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:07:25 -0500 Subject: [PATCH 38/47] Switch to celery.shared_task (#4881) * Switch to celery.shared_task * Sort impots --------- Co-authored-by: Bruno Alla --- .../{{cookiecutter.project_slug}}/users/tasks.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py index ecd14d2a..2afd4d4b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py @@ -1,8 +1,9 @@ -from config import celery_app +from celery import shared_task + from {{ cookiecutter.project_slug }}.users.models import User -@celery_app.task() +@shared_task() def get_users_count(): """A pointless Celery task to demonstrate usage.""" return User.objects.count() From ee55aa29b48ff994d0cb8c0872b2d929e2c23c32 Mon Sep 17 00:00:00 2001 From: github-actions Date: Thu, 22 Feb 2024 02:10:02 +0000 Subject: [PATCH 39/47] Release 2024.02.21 --- CHANGELOG.md | 17 +++++++++++++++++ setup.py | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f9b0785..b8ad3f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,23 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.21 + + +### Changed + +- Switch to `celery.shared_task` to define tasks ([#4881](https://github.com/cookiecutter/cookiecutter-django/pull/4881)) + +- Replace usages of `get_user_model` by importing model directly ([#4879](https://github.com/cookiecutter/cookiecutter-django/pull/4879)) + +### Updated + +- Auto-update pre-commit hooks ([#4873](https://github.com/cookiecutter/cookiecutter-django/pull/4873)) + +- Update pre-commit to 3.6.2 ([#4874](https://github.com/cookiecutter/cookiecutter-django/pull/4874)) + +- Update ruff to 0.2.2 ([#4871](https://github.com/cookiecutter/cookiecutter-django/pull/4871)) + ## 2024.02.19 diff --git a/setup.py b/setup.py index b29fc417..62b38573 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.19" +version = "2024.02.21" with open("README.md") as readme_file: long_description = readme_file.read() From 49a66b3583c2f15ee816efa84fee64c76f93d35e Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Thu, 22 Feb 2024 00:36:44 -0800 Subject: [PATCH 40/47] Update cookiecutter to 2.6.0 (#4882) --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3635390f..138744a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -cookiecutter==2.5.0 +cookiecutter==2.6.0 sh==2.0.6; sys_platform != "win32" binaryornot==0.4.4 From 357604f37b0137e49e08e0e043c75cbf4457c366 Mon Sep 17 00:00:00 2001 From: Mounir Date: Fri, 23 Feb 2024 15:35:52 +0100 Subject: [PATCH 41/47] Install ruff extension in devcontainer.json (#4887) organizeImports is expecting a string. --- .../.devcontainer/devcontainer.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json index 7fcd6287..e16d06a2 100644 --- a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json +++ b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json @@ -35,7 +35,7 @@ "analysis.typeCheckingMode": "basic", "defaultInterpreterPath": "/usr/local/bin/python", "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "always" }, "editor.defaultFormatter": "charliermarsh.ruff", "languageServer": "Pylance", @@ -54,8 +54,7 @@ // python "ms-python.python", "ms-python.vscode-pylance", - "ms-python.isort", - "ms-python.black-formatter", + "charliermarsh.ruff", // django "batisteo.vscode-django" ] From 916f6666372bf5b1a61e2abe2b24f4e62294d5d3 Mon Sep 17 00:00:00 2001 From: browniebroke Date: Fri, 23 Feb 2024 14:36:31 +0000 Subject: [PATCH 42/47] Update Contributors --- .github/contributors.json | 5 +++++ CONTRIBUTORS.md | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/.github/contributors.json b/.github/contributors.json index 057309a5..785ee4b3 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1523,5 +1523,10 @@ "name": "Paul Wulff", "github_login": "mtmpaulwulff", "twitter_username": "" + }, + { + "name": "Mounir", + "github_login": "mounirmesselmeni", + "twitter_username": "" } ] \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 73490036..30064acb 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1552,6 +1552,13 @@ Listed in alphabetical order. + + Mounir + + mounirmesselmeni + + + mozillazg From 4db3ea1e581be7d5792ea77326aa7cfb42d0548c Mon Sep 17 00:00:00 2001 From: Matthew Foster Walsh <15671892+mfosterw@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:37:34 -0500 Subject: [PATCH 43/47] Switch to local imports within app (#4883) --- .../{{cookiecutter.project_slug}}/users/admin.py | 6 +++--- .../{{cookiecutter.project_slug}}/users/forms.py | 2 +- .../{{cookiecutter.project_slug}}/users/managers.py | 2 +- .../{{cookiecutter.project_slug}}/users/models.py | 2 +- .../{{cookiecutter.project_slug}}/users/tasks.py | 2 +- .../{{cookiecutter.project_slug}}/users/urls.py | 6 +++--- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py index d0d1488f..70f82925 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py @@ -4,9 +4,9 @@ from django.contrib.auth import admin as auth_admin from django.contrib.auth.decorators import login_required from django.utils.translation import gettext_lazy as _ -from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm -from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm -from {{ cookiecutter.project_slug }}.users.models import User +from .forms import UserAdminChangeForm +from .forms import UserAdminCreationForm +from .models import User if settings.DJANGO_ADMIN_FORCE_ALLAUTH: # Force the `admin` sign in process to go through the `django-allauth` workflow: diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py index 2d18de20..830fca60 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py @@ -6,7 +6,7 @@ from django.forms import EmailField {%- endif %} from django.utils.translation import gettext_lazy as _ -from {{ cookiecutter.project_slug }}.users.models import User +from .models import User class UserAdminChangeForm(admin_forms.UserChangeForm): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py index c75c0e97..d8beaa48 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/managers.py @@ -4,7 +4,7 @@ from django.contrib.auth.hashers import make_password from django.contrib.auth.models import UserManager as DjangoUserManager if TYPE_CHECKING: - from {{ cookiecutter.project_slug }}.users.models import User # noqa: F401 + from .models import User # noqa: F401 class UserManager(DjangoUserManager["User"]): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py index fd78c26a..4a870cc2 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py @@ -11,7 +11,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ {%- if cookiecutter.username_type == "email" %} -from {{ cookiecutter.project_slug }}.users.managers import UserManager +from .managers import UserManager {%- endif %} diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py index 2afd4d4b..ca51cd74 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py @@ -1,6 +1,6 @@ from celery import shared_task -from {{ cookiecutter.project_slug }}.users.models import User +from .models import User @shared_task() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py index 40719ed2..74d65da1 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/urls.py @@ -1,8 +1,8 @@ from django.urls import path -from {{ cookiecutter.project_slug }}.users.views import user_detail_view -from {{ cookiecutter.project_slug }}.users.views import user_redirect_view -from {{ cookiecutter.project_slug }}.users.views import user_update_view +from .views import user_detail_view +from .views import user_redirect_view +from .views import user_update_view app_name = "users" urlpatterns = [ From 0ca9be321ad3e3d67c65efcfad1521cab32f274a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:38:40 +0000 Subject: [PATCH 44/47] Bump webpack-dev-server to 5.0.2 (#4875) * Bump webpack-dev-server in /{{cookiecutter.project_slug}} Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.15.1 to 5.0.2. - [Release notes](https://github.com/webpack/webpack-dev-server/releases) - [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.15.1...v5.0.2) --- updated-dependencies: - dependency-name: webpack-dev-server dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update server proxy syntax for webpack-dev-server@v5 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Bruno Alla --- {{cookiecutter.project_slug}}/package.json | 2 +- .../webpack/dev.config.js | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json index efa2136e..9ca72820 100644 --- a/{{cookiecutter.project_slug}}/package.json +++ b/{{cookiecutter.project_slug}}/package.json @@ -31,7 +31,7 @@ "webpack": "^5.65.0", "webpack-bundle-tracker": "^3.0.1", "webpack-cli": "^5.0.1", - "webpack-dev-server": "^4.6.0", + "webpack-dev-server": "^5.0.2", "webpack-merge": "^5.8.0" }, "engines": { diff --git a/{{cookiecutter.project_slug}}/webpack/dev.config.js b/{{cookiecutter.project_slug}}/webpack/dev.config.js index 8276c348..7c774185 100644 --- a/{{cookiecutter.project_slug}}/webpack/dev.config.js +++ b/{{cookiecutter.project_slug}}/webpack/dev.config.js @@ -6,13 +6,16 @@ module.exports = merge(commonConfig, { devtool: 'inline-source-map', devServer: { port: 3000, - proxy: { - {%- if cookiecutter.use_docker == 'n' %} - '/': 'http://0.0.0.0:8000', - {%- else %} - '/': 'http://django:8000', - {%- endif %} - }, + proxy: [ + { + context: ['/'], + {%- if cookiecutter.use_docker == 'n' %} + target: 'http://0.0.0.0:8000', + {%- else %} + target: 'http://django:8000', + {%- endif %} + }, + ], client: { overlay: { errors: true, From 37f974157bc5a8b59585c99c62de35e03b9e0358 Mon Sep 17 00:00:00 2001 From: Bruno Alla Date: Fri, 23 Feb 2024 15:43:30 +0100 Subject: [PATCH 45/47] Switch to dependabot for template & docs deps updates This enables us to use a separate label --- .github/dependabot.yml | 16 ++++++++++++++++ .pyup.yml | 2 -- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e6590469..3582a212 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,6 +3,22 @@ version: 2 updates: + # Update Python deps for the template (not the generated project) + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "daily" + labels: + - "project infrastructure" + + # Update Python deps for the documentation + - package-ecosystem: "pip" + directory: "docs/" + schedule: + interval: "daily" + labels: + - "project infrastructure" + # Update GitHub actions in workflows - package-ecosystem: "github-actions" directory: "/" diff --git a/.pyup.yml b/.pyup.yml index e5d4752e..13d336d5 100644 --- a/.pyup.yml +++ b/.pyup.yml @@ -14,8 +14,6 @@ pin: True label_prs: update requirements: - - "requirements.txt" - - "docs/requirements.txt" - "{{cookiecutter.project_slug}}/requirements/base.txt" - "{{cookiecutter.project_slug}}/requirements/local.txt" - "{{cookiecutter.project_slug}}/requirements/production.txt" From 91ebf6f95b02ea0dba7603d14066bdfe877c7925 Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 24 Feb 2024 02:08:16 +0000 Subject: [PATCH 46/47] Release 2024.02.23 --- CHANGELOG.md | 13 +++++++++++++ setup.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ad3f6b..088e814c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2024.02.23 + + +### Changed + +- Switch to local imports within app ([#4883](https://github.com/cookiecutter/cookiecutter-django/pull/4883)) + +- Install ruff extension in `devcontainer.json` ([#4887](https://github.com/cookiecutter/cookiecutter-django/pull/4887)) + +### Updated + +- Bump webpack-dev-server to 5.0.2 ([#4875](https://github.com/cookiecutter/cookiecutter-django/pull/4875)) + ## 2024.02.21 diff --git a/setup.py b/setup.py index 62b38573..f7947b0e 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.02.21" +version = "2024.02.23" with open("README.md") as readme_file: long_description = readme_file.read() From ddf18527687f7d9fca0731d197f8feee3d3d8618 Mon Sep 17 00:00:00 2001 From: "pyup.io bot" Date: Sat, 24 Feb 2024 04:50:30 -0800 Subject: [PATCH 47/47] Update coverage from 7.4.1 to 7.4.3 (#4888) --- {{cookiecutter.project_slug}}/requirements/local.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 8225dab0..618226f6 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -29,7 +29,7 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ ruff==0.2.2 # https://github.com/astral-sh/ruff -coverage==7.4.1 # https://github.com/nedbat/coveragepy +coverage==7.4.3 # https://github.com/nedbat/coveragepy djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint pre-commit==3.6.2 # https://github.com/pre-commit/pre-commit