diff --git a/.github/contributors.json b/.github/contributors.json index ad83662dd..49ebfe4d8 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1257,5 +1257,70 @@ "name": "innicoder", "github_login": "innicoder", "twitter_username": "" + }, + { + "name": "Naveen", + "github_login": "naveensrinivasan", + "twitter_username": "snaveen" + }, + { + "name": "Nikita Sobolev", + "github_login": "sobolevn", + "twitter_username": "" + }, + { + "name": "Sebastian Reyes Espinosa", + "github_login": "sebastian-code", + "twitter_username": "sebastianreyese" + }, + { + "name": "jugglinmike", + "github_login": "jugglinmike", + "twitter_username": "" + }, + { + "name": "monosans", + "github_login": "monosans", + "twitter_username": "" + }, + { + "name": "Marcio Mazza", + "github_login": "marciomazza", + "twitter_username": "marciomazza" + }, + { + "name": "Brandon Rumiser", + "github_login": "brumiser1550", + "twitter_username": "" + }, + { + "name": "krati yadav", + "github_login": "krati5", + "twitter_username": "" + }, + { + "name": "Abe Hanoka", + "github_login": "abe-101", + "twitter_username": "abe__101" + }, + { + "name": "Adin Hodovic", + "github_login": "adinhodovic", + "twitter_username": "" + }, + { + "name": "Leifur Halldor Asgeirsson", + "github_login": "leifurhauks", + "twitter_username": "" + }, + { + "name": "David", + "github_login": "buckldav", + "twitter_username": "" + }, + { + "name": "rguptar", + "github_login": "rguptar", + "twitter_username": "" } ] \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb9105e49..7f4c5ba17 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,12 +13,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: pip - name: Run pre-commit - uses: pre-commit/action@v2.0.3 + uses: pre-commit/action@v3.0.0 tests: strategy: @@ -33,9 +33,9 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: pip - name: Install dependencies run: pip install -r requirements.txt @@ -64,9 +64,9 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: pip - name: Install dependencies run: pip install -r requirements.txt @@ -106,9 +106,9 @@ jobs: steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" cache: pip cache-dependency-path: | requirements.txt diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml index 5ea023fdd..fd250604f 100644 --- a/.github/workflows/django-issue-checker.yml +++ b/.github/workflows/django-issue-checker.yml @@ -17,9 +17,9 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index df4ea1f9a..1708e8b82 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -8,17 +8,23 @@ on: - cron: "15 2 * * *" workflow_dispatch: # to trigger manually +permissions: + contents: read + jobs: auto-update: # Disables this workflow from running in a repository that is not part of the indicated organization/user if: github.repository_owner == 'cookiecutter' + permissions: + contents: write # for peter-evans/create-pull-request to create branch + pull-requests: write # for peter-evans/create-pull-request to create a PR runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-python@v3 + - uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" - name: Install pre-commit run: pip install pre-commit diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 2b73498dc..27113a89f 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -17,9 +17,9 @@ jobs: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml index 16c5c6226..952486c1b 100644 --- a/.github/workflows/update-contributors.yml +++ b/.github/workflows/update-contributors.yml @@ -5,19 +5,24 @@ on: branches: - master +permissions: + contents: read + jobs: build: # Disables this workflow from running in a repository that is not part of the indicated organization/user if: github.repository_owner == 'cookiecutter' + permissions: + contents: write # for stefanzweifel/git-auto-commit-action to push code in repo runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Set up Python - uses: actions/setup-python@v3 + uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip @@ -26,7 +31,7 @@ jobs: run: python scripts/update_contributors.py - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4.14.1 + uses: stefanzweifel/git-auto-commit-action@v4.16.0 with: commit_message: Update Contributors file_pattern: CONTRIBUTORS.md .github/contributors.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index da839860e..e8d055772 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,13 +3,20 @@ default_stages: [commit] repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: check-yaml + - repo: https://github.com/asottile/pyupgrade + rev: v3.3.0 + hooks: + - id: pyupgrade + args: [--py310-plus] + exclude: hooks/ + - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black @@ -19,7 +26,7 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 6.0.0 hooks: - id: flake8 diff --git a/CHANGELOG.md b/CHANGELOG.md index a616f9469..b0e1e6690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,488 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2022.12.04 + +### Updated +- Update redis to 4.4.0 ([#3977](https://github.com/cookiecutter/cookiecutter-django/pull/3977)) +- Update django-debug-toolbar to 3.8.1 ([#3976](https://github.com/cookiecutter/cookiecutter-django/pull/3976)) + +## 2022.12.03 + +### Updated +- Auto-update pre-commit hooks ([#3975](https://github.com/cookiecutter/cookiecutter-django/pull/3975)) + +## 2022.12.02 + +### Updated +- Update flake8 to 6.0.0 ([#3974](https://github.com/cookiecutter/cookiecutter-django/pull/3974)) + +## 2022.11.30 + +### Changed +- Add Azure Storage as an option to serve static and media files ([#3967](https://github.com/cookiecutter/cookiecutter-django/pull/3967)) +### Updated +- Auto-update pre-commit hooks ([#3970](https://github.com/cookiecutter/cookiecutter-django/pull/3970)) + +## 2022.11.26 + +### Changed +- Fix typo in flower start for watching celery ([#3966](https://github.com/cookiecutter/cookiecutter-django/pull/3966)) + +## 2022.11.24 + +### Updated +- Auto-update pre-commit hooks ([#3963](https://github.com/cookiecutter/cookiecutter-django/pull/3963)) + +## 2022.11.23 + +### Changed +- Fix graceful shutdown of local dev containers and use watchfiles for beat + flower ([#3925](https://github.com/cookiecutter/cookiecutter-django/pull/3925)) +- feat(celery): Enable sending the sent task event by default ([#3961](https://github.com/cookiecutter/cookiecutter-django/pull/3961)) +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.15.3 to 4.15.4 ([#3940](https://github.com/cookiecutter/cookiecutter-django/pull/3940)) +- Update django-model-utils to 4.3.1 ([#3948](https://github.com/cookiecutter/cookiecutter-django/pull/3948)) +- Update flake8-isort to 5.0.3 ([#3952](https://github.com/cookiecutter/cookiecutter-django/pull/3952)) + +## 2022.11.22 + +### Changed +- Remove USE_L10N due to deprecation ([#3960](https://github.com/cookiecutter/cookiecutter-django/pull/3960)) +- Remove platform from compose file ([#3957](https://github.com/cookiecutter/cookiecutter-django/pull/3957)) +- feat(celery): Send task events for Celery by default ([#3959](https://github.com/cookiecutter/cookiecutter-django/pull/3959)) +### Updated +- Update python-slugify to 7.0.0 ([#3950](https://github.com/cookiecutter/cookiecutter-django/pull/3950)) +- Update redis to 4.3.5 ([#3954](https://github.com/cookiecutter/cookiecutter-django/pull/3954)) +- Update sentry-sdk to 1.11.1 ([#3955](https://github.com/cookiecutter/cookiecutter-django/pull/3955)) +- Update uvicorn to 0.20.0 ([#3953](https://github.com/cookiecutter/cookiecutter-django/pull/3953)) +- Update tox to 3.27.1 ([#3945](https://github.com/cookiecutter/cookiecutter-django/pull/3945)) + +## 2022.11.11 + +### Updated +- Auto-update pre-commit hooks ([#3942](https://github.com/cookiecutter/cookiecutter-django/pull/3942)) + +## 2022.11.07 + +### Updated +- Update watchfiles to 0.18.1 ([#3938](https://github.com/cookiecutter/cookiecutter-django/pull/3938)) + +## 2022.11.06 + +### Changed +- Store extended Celery task attributes in backend ([#3855](https://github.com/cookiecutter/cookiecutter-django/pull/3855)) +- add os requirements for Ubuntu 22.04 (Jammy) ([#3930](https://github.com/cookiecutter/cookiecutter-django/pull/3930)) +### Updated +- Update pytest-sugar to 0.9.6 ([#3937](https://github.com/cookiecutter/cookiecutter-django/pull/3937)) +- Update pygithub to 1.57 ([#3936](https://github.com/cookiecutter/cookiecutter-django/pull/3936)) +- Update sphinx-rtd-theme to 1.1.1 ([#3935](https://github.com/cookiecutter/cookiecutter-django/pull/3935)) + +## 2022.11.02 + +### Changed +- fix typo in CONTRIBUTING.md ([#3932](https://github.com/cookiecutter/cookiecutter-django/pull/3932)) +### Updated +- Update crispy-bootstrap5 to 0.7 ([#3886](https://github.com/cookiecutter/cookiecutter-django/pull/3886)) +- Update django-coverage-plugin to 2.0.4 ([#3927](https://github.com/cookiecutter/cookiecutter-django/pull/3927)) +- Update pytz to 2022.6 ([#3928](https://github.com/cookiecutter/cookiecutter-django/pull/3928)) +- Update sphinx-rtd-theme to 1.1.0 ([#3929](https://github.com/cookiecutter/cookiecutter-django/pull/3929)) +- Update pillow to 9.3.0 ([#3922](https://github.com/cookiecutter/cookiecutter-django/pull/3922)) + +## 2022.10.30 + +### Updated +- Auto-update pre-commit hooks ([#3924](https://github.com/cookiecutter/cookiecutter-django/pull/3924)) + +## 2022.10.28 + +### Updated +- Bump stefanzweifel/git-auto-commit-action from 4.15.2 to 4.15.3 ([#3921](https://github.com/cookiecutter/cookiecutter-django/pull/3921)) + +## 2022.10.26 + +### Updated +- Update uvicorn to 0.19.0 ([#3920](https://github.com/cookiecutter/cookiecutter-django/pull/3920)) +- Update pytest to 7.2.0 ([#3919](https://github.com/cookiecutter/cookiecutter-django/pull/3919)) +- Update tox to 3.27.0 ([#3917](https://github.com/cookiecutter/cookiecutter-django/pull/3917)) +- Update psycopg2 to 2.9.5 ([#3918](https://github.com/cookiecutter/cookiecutter-django/pull/3918)) + +## 2022.10.24 + +### Changed +- Upgrade Python version from 3.9 to 3.10 ([#3913](https://github.com/cookiecutter/cookiecutter-django/pull/3913)) +### Updated +- Update sentry-sdk to 1.10.1 ([#3911](https://github.com/cookiecutter/cookiecutter-django/pull/3911)) +- Bump stefanzweifel/git-auto-commit-action from 4.15.1 to 4.15.2 ([#3914](https://github.com/cookiecutter/cookiecutter-django/pull/3914)) + +## 2022.10.19 + +### Changed +- Set AWS_S3_MAX_MEMORY_SIZE ([#3810](https://github.com/cookiecutter/cookiecutter-django/pull/3810)) +- Upgrade to Django 4.0 ([#3848](https://github.com/cookiecutter/cookiecutter-django/pull/3848)) +### Updated +- Update pytz to 2022.5 ([#3906](https://github.com/cookiecutter/cookiecutter-django/pull/3906)) +- Update sphinx to 5.3.0 ([#3905](https://github.com/cookiecutter/cookiecutter-django/pull/3905)) +- Update django-celery-beat to 2.4.0 ([#3908](https://github.com/cookiecutter/cookiecutter-django/pull/3908)) +- Update watchfiles to 0.18.0 ([#3907](https://github.com/cookiecutter/cookiecutter-django/pull/3907)) + +## 2022.10.13 + +### Updated +- Update pygithub to 1.56 ([#3904](https://github.com/cookiecutter/cookiecutter-django/pull/3904)) + +## 2022.10.11 + +### Updated +- Auto-update pre-commit hooks ([#3899](https://github.com/cookiecutter/cookiecutter-django/pull/3899)) +- Update flake8-isort to 5.0.0 ([#3901](https://github.com/cookiecutter/cookiecutter-django/pull/3901)) +- Update gitpython to 3.1.29 ([#3902](https://github.com/cookiecutter/cookiecutter-django/pull/3902)) +- Update psycopg2 to 2.9.4 ([#3896](https://github.com/cookiecutter/cookiecutter-django/pull/3896)) +- Bump stefanzweifel/git-auto-commit-action from 4.15.0 to 4.15.1 ([#3903](https://github.com/cookiecutter/cookiecutter-django/pull/3903)) +- Update black to 22.10.0 ([#3898](https://github.com/cookiecutter/cookiecutter-django/pull/3898)) + +## 2022.10.04 + +### Updated +- Update django to 3.2.16 ([#3895](https://github.com/cookiecutter/cookiecutter-django/pull/3895)) +- Update mypy to 0.982 ([#3893](https://github.com/cookiecutter/cookiecutter-django/pull/3893)) +- Auto-update pre-commit hooks ([#3894](https://github.com/cookiecutter/cookiecutter-django/pull/3894)) + +## 2022.10.03 + +### Updated +- Update sentry-sdk to 1.9.10 ([#3892](https://github.com/cookiecutter/cookiecutter-django/pull/3892)) + +## 2022.10.02 + +### Updated +- Update pytz to 2022.4 ([#3891](https://github.com/cookiecutter/cookiecutter-django/pull/3891)) + +## 2022.09.30 + +### Updated +- Update coverage to 6.5.0 ([#3890](https://github.com/cookiecutter/cookiecutter-django/pull/3890)) +- Update mypy to 0.981 ([#3889](https://github.com/cookiecutter/cookiecutter-django/pull/3889)) +- Update sentry-sdk to 1.9.9 ([#3888](https://github.com/cookiecutter/cookiecutter-django/pull/3888)) +- Update sphinx to 5.2.3 ([#3887](https://github.com/cookiecutter/cookiecutter-django/pull/3887)) + +## 2022.09.29 + +### Changed +- Remove outdated & optional Sendgrid settings from production config ([#3885](https://github.com/cookiecutter/cookiecutter-django/pull/3885)) + +## 2022.09.27 + +### Updated +- Update sphinx to 5.2.2 ([#3884](https://github.com/cookiecutter/cookiecutter-django/pull/3884)) + +## 2022.09.26 + +### Updated +- Update drf-spectacular to 0.24.2 ([#3882](https://github.com/cookiecutter/cookiecutter-django/pull/3882)) +- Update djangorestframework to 3.14.0 ([#3881](https://github.com/cookiecutter/cookiecutter-django/pull/3881)) +- Update django-debug-toolbar to 3.7.0 ([#3878](https://github.com/cookiecutter/cookiecutter-django/pull/3878)) +- Auto-update pre-commit hooks ([#3877](https://github.com/cookiecutter/cookiecutter-django/pull/3877)) +- Bump stefanzweifel/git-auto-commit-action from 4.14.1 to 4.15.0 ([#3880](https://github.com/cookiecutter/cookiecutter-django/pull/3880)) +- Update sphinx to 5.2.1 ([#3879](https://github.com/cookiecutter/cookiecutter-django/pull/3879)) + +## 2022.09.24 + +### Fixed +- Remove `--no-deps` in pip wheels command of docs Dockerfile ([#3875](https://github.com/cookiecutter/cookiecutter-django/pull/3875)) + +## 2022.09.23 + +### Changed +- Reload uvicorn on html file change ([#3866](https://github.com/cookiecutter/cookiecutter-django/pull/3866)) +- Mailjet default api url does not work out of the box ([#3871](https://github.com/cookiecutter/cookiecutter-django/pull/3871)) +### Updated +- Auto-update pre-commit hooks ([#3872](https://github.com/cookiecutter/cookiecutter-django/pull/3872)) +- Update django-extensions to 3.2.1 ([#3867](https://github.com/cookiecutter/cookiecutter-django/pull/3867)) +- Update tox to 3.26.0 ([#3864](https://github.com/cookiecutter/cookiecutter-django/pull/3864)) +- Update drf-spectacular to 0.24.1 ([#3874](https://github.com/cookiecutter/cookiecutter-django/pull/3874)) + +## 2022.09.15 + +### Updated +- Update watchfiles to 0.17.0 ([#3869](https://github.com/cookiecutter/cookiecutter-django/pull/3869)) +- Update drf-spectacular to 0.24.0 ([#3870](https://github.com/cookiecutter/cookiecutter-django/pull/3870)) + +## 2022.09.05 + +### Updated +- Update sentry-sdk to 1.9.8 ([#3861](https://github.com/cookiecutter/cookiecutter-django/pull/3861)) + +## 2022.09.02 + +### Updated +- Update pytest to 7.1.3 ([#3860](https://github.com/cookiecutter/cookiecutter-django/pull/3860)) +- Update sentry-sdk to 1.9.7 ([#3859](https://github.com/cookiecutter/cookiecutter-django/pull/3859)) + +## 2022.09.01 + +### Changed +- Add article to README about how to use a hosted DB ([#3844](https://github.com/cookiecutter/cookiecutter-django/pull/3844)) +### Updated +- Update sentry-sdk to 1.9.6 ([#3856](https://github.com/cookiecutter/cookiecutter-django/pull/3856)) +- Auto-update pre-commit hooks ([#3858](https://github.com/cookiecutter/cookiecutter-django/pull/3858)) +- Update black to 22.8.0 ([#3857](https://github.com/cookiecutter/cookiecutter-django/pull/3857)) + +## 2022.08.26 + +### Changed +- Fix formatting in docs ([#3850](https://github.com/cookiecutter/cookiecutter-django/pull/3850)) + +## 2022.08.24 + +### Updated +- Update django-debug-toolbar to 3.6.0 ([#3847](https://github.com/cookiecutter/cookiecutter-django/pull/3847)) +- Update werkzeug to 2.2.2 ([#3846](https://github.com/cookiecutter/cookiecutter-django/pull/3846)) +- Update coverage to 6.4.4 ([#3842](https://github.com/cookiecutter/cookiecutter-django/pull/3842)) +- Update uvicorn to 0.18.3 ([#3845](https://github.com/cookiecutter/cookiecutter-django/pull/3845)) +- Update sentry-sdk to 1.9.5 ([#3841](https://github.com/cookiecutter/cookiecutter-django/pull/3841)) +- Update flower to 1.2.0 ([#3836](https://github.com/cookiecutter/cookiecutter-django/pull/3836)) +- Update django-storages to 1.13.1 ([#3833](https://github.com/cookiecutter/cookiecutter-django/pull/3833)) + +## 2022.08.15 + +### Updated +- Update coverage to 6.4.3 ([#3835](https://github.com/cookiecutter/cookiecutter-django/pull/3835)) +- Update pytz to 2022.2.1 ([#3840](https://github.com/cookiecutter/cookiecutter-django/pull/3840)) +- Update sentry-sdk to 1.9.4 ([#3838](https://github.com/cookiecutter/cookiecutter-django/pull/3838)) + +## 2022.08.09 + +### Updated +- Update sentry-sdk to 1.9.3 ([#3837](https://github.com/cookiecutter/cookiecutter-django/pull/3837)) + +## 2022.08.05 + +### Updated +- Update sentry-sdk to 1.9.2 ([#3832](https://github.com/cookiecutter/cookiecutter-django/pull/3832)) + +## 2022.08.04 + +### Updated +- Auto-update pre-commit hooks ([#3816](https://github.com/cookiecutter/cookiecutter-django/pull/3816)) +- Update flake8 to 5.0.4 ([#3829](https://github.com/cookiecutter/cookiecutter-django/pull/3829)) +- Update django-compressor to 4.1 ([#3823](https://github.com/cookiecutter/cookiecutter-django/pull/3823)) +- Update flake8-isort to 4.2.0 ([#3828](https://github.com/cookiecutter/cookiecutter-django/pull/3828)) + +## 2022.08.03 + +### Updated +- Update django to 3.2.15 ([#3822](https://github.com/cookiecutter/cookiecutter-django/pull/3822)) + +## 2022.07.29 + +### Updated +- Update sentry-sdk to 1.9.0 ([#3815](https://github.com/cookiecutter/cookiecutter-django/pull/3815)) + +## 2022.07.28 + +### Updated +- Update werkzeug to 2.2.1 ([#3814](https://github.com/cookiecutter/cookiecutter-django/pull/3814)) + +## 2022.07.27 + +### Updated +- Update werkzeug to 2.2.0 ([#3813](https://github.com/cookiecutter/cookiecutter-django/pull/3813)) +- Update sphinx to 5.1.1 ([#3811](https://github.com/cookiecutter/cookiecutter-django/pull/3811)) +- Update drf-spectacular to 0.23.1 ([#3812](https://github.com/cookiecutter/cookiecutter-django/pull/3812)) + +## 2022.07.26 + +### Changed +- Switch from `watchgod` to `watchfiles` ([#3791](https://github.com/cookiecutter/cookiecutter-django/pull/3791)) +- Change Django settings file used by pylint ([#3806](https://github.com/cookiecutter/cookiecutter-django/pull/3806)) +- Simplify database access in tests ([#3807](https://github.com/cookiecutter/cookiecutter-django/pull/3807)) +- Provide more context when wating for PostgreSQL takes too long ([#3782](https://github.com/cookiecutter/cookiecutter-django/pull/3782)) +### Updated +- Update django-compressor to 4.0 ([#3802](https://github.com/cookiecutter/cookiecutter-django/pull/3802)) +- Update flake8-isort to 4.1.2.post0 ([#3809](https://github.com/cookiecutter/cookiecutter-django/pull/3809)) +- Update sphinx to 5.1.0 ([#3808](https://github.com/cookiecutter/cookiecutter-django/pull/3808)) +- Update sh to 1.14.3 ([#3798](https://github.com/cookiecutter/cookiecutter-django/pull/3798)) +- Auto-update pre-commit hooks ([#3780](https://github.com/cookiecutter/cookiecutter-django/pull/3780)) + +## 2022.07.22 + +### Updated +- Update pytest-sugar to 0.9.5 ([#3800](https://github.com/cookiecutter/cookiecutter-django/pull/3800)) +- Update sphinx to 5.0.2 ([#3801](https://github.com/cookiecutter/cookiecutter-django/pull/3801)) +- Update pillow to 9.2.0 ([#3799](https://github.com/cookiecutter/cookiecutter-django/pull/3799)) +- Update werkzeug to 2.1.2 ([#3797](https://github.com/cookiecutter/cookiecutter-django/pull/3797)) + +## 2022.07.21 + +### Changed +- Set user to form instance in update user view test ([#3776](https://github.com/cookiecutter/cookiecutter-django/pull/3776)) +- Fix warning from django-coverage-plugin in tests ([#3790](https://github.com/cookiecutter/cookiecutter-django/pull/3790)) +- Always use `const` instead of `var` in `gulpfile.js` ([#3786](https://github.com/cookiecutter/cookiecutter-django/pull/3786)) +### Updated +- Update flower to 1.1.0 ([#3796](https://github.com/cookiecutter/cookiecutter-django/pull/3796)) +- Update coverage to 6.4.2 ([#3783](https://github.com/cookiecutter/cookiecutter-django/pull/3783)) +- Update mypy to 0.971 ([#3788](https://github.com/cookiecutter/cookiecutter-django/pull/3788)) +- Update sentry-sdk to 1.8.0 ([#3792](https://github.com/cookiecutter/cookiecutter-django/pull/3792)) +- Update pre-commit to 2.20.0 ([#3779](https://github.com/cookiecutter/cookiecutter-django/pull/3779)) +- Update django-extensions to 3.2.0 ([#3774](https://github.com/cookiecutter/cookiecutter-django/pull/3774)) +- Update tox to 3.25.1 ([#3767](https://github.com/cookiecutter/cookiecutter-django/pull/3767)) +- Update uvicorn to 0.18.2 ([#3762](https://github.com/cookiecutter/cookiecutter-django/pull/3762)) +- Update redis to 4.3.4 ([#3763](https://github.com/cookiecutter/cookiecutter-django/pull/3763)) +- Update requests to 2.28.1 ([#3766](https://github.com/cookiecutter/cookiecutter-django/pull/3766)) + +## 2022.07.10 + +### Changed +- Revert auto-update pre-commit hooks ([#3778](https://github.com/cookiecutter/cookiecutter-django/pull/3778)) +### Updated +- Auto-update pre-commit hooks ([#3775](https://github.com/cookiecutter/cookiecutter-django/pull/3775)) + +## 2022.07.06 + +### Updated +- Update django to 3.2.14 ([#3768](https://github.com/cookiecutter/cookiecutter-django/pull/3768)) + +## 2022.06.28 + +### Updated +- Auto-update pre-commit hooks ([#3765](https://github.com/cookiecutter/cookiecutter-django/pull/3765)) +- Update black to 22.6.0 ([#3764](https://github.com/cookiecutter/cookiecutter-django/pull/3764)) + +## 2022.06.23 + +### Updated +- Update django-debug-toolbar to 3.5.0 ([#3760](https://github.com/cookiecutter/cookiecutter-django/pull/3760)) + +## 2022.06.22 + +### Updated +- Update django-stubs to 1.12.0 ([#3757](https://github.com/cookiecutter/cookiecutter-django/pull/3757)) +- Update sentry-sdk to 1.6.0 ([#3756](https://github.com/cookiecutter/cookiecutter-django/pull/3756)) +- Update djangorestframework-stubs to 1.7.0 ([#3754](https://github.com/cookiecutter/cookiecutter-django/pull/3754)) + +## 2022.06.15 + +### Updated +- Update django-environ to 0.9.0 ([#3751](https://github.com/cookiecutter/cookiecutter-django/pull/3751)) + +## 2022.06.13 + +### Updated +- Update cookiecutter to 2.1.1 ([#3727](https://github.com/cookiecutter/cookiecutter-django/pull/3727)) + +## 2022.06.11 + +### Updated +- Update requests to 2.28.0 ([#3748](https://github.com/cookiecutter/cookiecutter-django/pull/3748)) + +## 2022.06.09 + +### Updated +- Bump actions/setup-python from 3 to 4 ([#3746](https://github.com/cookiecutter/cookiecutter-django/pull/3746)) + +## 2022.06.08 + +### Updated +- Auto-update pre-commit hooks ([#3744](https://github.com/cookiecutter/cookiecutter-django/pull/3744)) + +## 2022.06.07 + +### Updated +- Update django-allauth to 0.51.0 ([#3743](https://github.com/cookiecutter/cookiecutter-django/pull/3743)) +- Auto-update pre-commit hooks ([#3742](https://github.com/cookiecutter/cookiecutter-django/pull/3742)) + +## 2022.06.06 + +### Updated +- Bump pre-commit/action from 2.0.3 to 3.0.0 ([#3739](https://github.com/cookiecutter/cookiecutter-django/pull/3739)) + +## 2022.06.05 + +### Updated +- Update whitenoise to 6.2.0 ([#3737](https://github.com/cookiecutter/cookiecutter-django/pull/3737)) +- Update django-cors-headers to 3.13.0 ([#3738](https://github.com/cookiecutter/cookiecutter-django/pull/3738)) + +## 2022.06.04 + +### Updated +- Update django-cors-headers to 3.12.0 ([#3736](https://github.com/cookiecutter/cookiecutter-django/pull/3736)) +- Update djangorestframework-stubs to 1.6.0 ([#3718](https://github.com/cookiecutter/cookiecutter-django/pull/3718)) +- Update django-stubs to 1.11.0 ([#3734](https://github.com/cookiecutter/cookiecutter-django/pull/3734)) +- Update sphinx to 5.0.1 ([#3733](https://github.com/cookiecutter/cookiecutter-django/pull/3733)) +- Update sphinx to 5.0.0 ([#3724](https://github.com/cookiecutter/cookiecutter-django/pull/3724)) +- Update celery to 5.2.7 ([#3732](https://github.com/cookiecutter/cookiecutter-django/pull/3732)) +- Update django-celery-beat to 2.3.0 ([#3731](https://github.com/cookiecutter/cookiecutter-django/pull/3731)) + +## 2022.06.02 + +### Updated +- Update coverage to 6.4.1 ([#3729](https://github.com/cookiecutter/cookiecutter-django/pull/3729)) +- Update redis to 4.3.3 ([#3728](https://github.com/cookiecutter/cookiecutter-django/pull/3728)) + +## 2022.06.01 + +### Updated +- Update redis to 4.3.2 ([#3726](https://github.com/cookiecutter/cookiecutter-django/pull/3726)) + +## 2022.05.24 + +### Updated +- Update coverage to 6.4 ([#3716](https://github.com/cookiecutter/cookiecutter-django/pull/3716)) + +## 2022.05.18 + +### Updated +- Update pillow to 9.1.1 ([#3714](https://github.com/cookiecutter/cookiecutter-django/pull/3714)) + +## 2022.05.16 + +### Changed +- Update postgres versions ([#3712](https://github.com/cookiecutter/cookiecutter-django/pull/3712)) +### Updated +- Update django-anymail to 8.6 ([#3713](https://github.com/cookiecutter/cookiecutter-django/pull/3713)) + +## 2022.05.14 + +### Updated +- Update coverage to 6.3.3 ([#3709](https://github.com/cookiecutter/cookiecutter-django/pull/3709)) +- Update whitenoise to 6.1.0 ([#3707](https://github.com/cookiecutter/cookiecutter-django/pull/3707)) +- Update sentry-sdk to 1.5.12 ([#3706](https://github.com/cookiecutter/cookiecutter-django/pull/3706)) +- Update redis to 4.3.1 ([#3704](https://github.com/cookiecutter/cookiecutter-django/pull/3704)) + +## 2022.05.07 + +### Changed +- Add pyupgrade to pre-commit config ([#3702](https://github.com/cookiecutter/cookiecutter-django/pull/3702)) +- Set permissions for GitHub actions ([#3698](https://github.com/cookiecutter/cookiecutter-django/pull/3698)) +### Updated +- Update jinja2 to 3.1.2 ([#3700](https://github.com/cookiecutter/cookiecutter-django/pull/3700)) + +## 2022.05.06 + +### Updated +- Update pre-commit to 2.19.0 ([#3697](https://github.com/cookiecutter/cookiecutter-django/pull/3697)) + +## 2022.05.04 + +### Updated +- Update django-coverage-plugin to 2.0.3 ([#3695](https://github.com/cookiecutter/cookiecutter-django/pull/3695)) + +## 2022.05.03 + +### Updated +- Update django-debug-toolbar to 3.4.0 ([#3692](https://github.com/cookiecutter/cookiecutter-django/pull/3692)) +- Update sentry-sdk to 1.5.11 ([#3693](https://github.com/cookiecutter/cookiecutter-django/pull/3693)) + +## 2022.05.01 + +### Updated +- Update django-debug-toolbar to 3.3.0 ([#3690](https://github.com/cookiecutter/cookiecutter-django/pull/3690)) + +## 2022.04.28 + +### Changed +- Add the possibility to set a max django version on create_django_issue script ([#3680](https://github.com/cookiecutter/cookiecutter-django/pull/3680)) + ## 2022.04.27 ### Updated diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a9d5b088f..69bce6f2e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,9 +33,9 @@ To run all tests using various versions of python in virtualenvs defined in tox. It is possible to test with a specific version of python. To do this, the command is: - $ tox -e py39 + $ tox -e py310 -This will run pytest with the python3.9 interpreter, for example. +This will run pytest with the python3.10 interpreter, for example. To run a particular test with tox for against your current Python version: diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c33bf9e12..d97324708 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -138,6 +138,13 @@ Listed in alphabetical order. abdadeel_ + + Abe Hanoka + + abe-101 + + abe__101 + Adam Bogdał @@ -159,6 +166,13 @@ Listed in alphabetical order. + + Adin Hodovic + + adinhodovic + + + Agam Dua @@ -376,6 +390,13 @@ Listed in alphabetical order. + + Brandon Rumiser + + brumiser1550 + + + Brent Payne @@ -586,6 +607,13 @@ Listed in alphabetical order. + + David + + buckldav + + + David Díaz @@ -1006,6 +1034,13 @@ Listed in alphabetical order. + + jugglinmike + + jugglinmike + + + Jules Cheron @@ -1090,6 +1125,13 @@ Listed in alphabetical order. + + krati yadav + + krati5 + + + Krzysztof Szumny @@ -1125,6 +1167,13 @@ Listed in alphabetical order. + + Leifur Halldor Asgeirsson + + leifurhauks + + + Leo won @@ -1202,6 +1251,13 @@ Listed in alphabetical order. + + Marcio Mazza + + marciomazza + + marciomazza + Martin Blech @@ -1335,6 +1391,13 @@ Listed in alphabetical order. + + monosans + + monosans + + + mozillazg @@ -1349,6 +1412,13 @@ Listed in alphabetical order. + + Naveen + + naveensrinivasan + + snaveen + Nico Stefani @@ -1356,6 +1426,13 @@ Listed in alphabetical order. moby_dick91 + + Nikita Sobolev + + sobolevn + + + Noah H @@ -1468,6 +1545,13 @@ Listed in alphabetical order. + + rguptar + + rguptar + + + Richard Hajdu @@ -1517,6 +1601,13 @@ Listed in alphabetical order. saschalalala + + Sebastian Reyes Espinosa + + sebastian-code + + sebastianreyese + Simon Rey diff --git a/README.md b/README.md index 9e0c6f550..7fa46a777 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ production-ready Django projects quickly. ## Features -- For Django 3.2 -- Works with Python 3.9 +- For Django 4.0 +- Works with Python 3.10 - Renders Django projects with 100% starting test coverage - Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5 - [12-Factor](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ) @@ -29,7 +29,7 @@ production-ready Django projects quickly. - Optional basic ASGI setup for Websockets - Optional custom static build using Gulp or Webpack - Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable) -- Media storage using Amazon S3 or Google Cloud Storage +- Media storage using Amazon S3, Google Cloud Storage or Azure Storage - Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support) - [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku - Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/) @@ -41,7 +41,7 @@ production-ready Django projects quickly. *These features can be enabled during initial project setup.* -- Serve static files from Amazon S3, Google Cloud Storage or [Whitenoise](https://whitenoise.readthedocs.io/) +- Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) - Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) - Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing - Integration with [Sentry](https://sentry.io/welcome/) for error logging @@ -121,11 +121,11 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re use_pycharm [n]: y use_docker [n]: n Select postgresql_version: - 1 - 14.1 - 2 - 13.5 - 3 - 12.9 - 4 - 11.14 - 5 - 10.19 + 1 - 14 + 2 - 13 + 3 - 12 + 4 - 11 + 5 - 10 Choose from 1, 2, 3, 4, 5 [1]: 1 Select cloud_provider: 1 - AWS @@ -233,6 +233,7 @@ experience better. ## Articles +- [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021 - [Using cookiecutter-django with Google Cloud Storage](https://ahhda.github.io/cloud/gce/django/2019/03/12/using-django-cookiecutter-cloud-storage.html) - Mar. 12, 2019 - [cookiecutter-django with Nginx, Route 53 and ELB](https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/) - Feb. 12, 2018 - [cookiecutter-django and Amazon RDS](https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/) - Feb. 7, 2018 diff --git a/cookiecutter.json b/cookiecutter.json index e3ee3f03c..cf4da9a45 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -18,15 +18,16 @@ "use_pycharm": "n", "use_docker": "n", "postgresql_version": [ - "14.1", - "13.5", - "12.9", - "11.14", - "10.19" + "14", + "13", + "12", + "11", + "10" ], "cloud_provider": [ "AWS", "GCP", + "Azure", "None" ], "mail_service": [ diff --git a/docs/conf.py b/docs/conf.py index f55bcb819..b53e6a7e7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -39,7 +39,7 @@ master_doc = "index" # General information about the project. project = "Cookiecutter Django" -copyright = "2013-{}, Daniel Roy Greenfeld".format(now.year) +copyright = f"2013-{now.year}, Daniel Roy Greenfeld" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the diff --git a/docs/deployment-on-pythonanywhere.rst b/docs/deployment-on-pythonanywhere.rst index f7bff12a4..7984d7b5e 100644 --- a/docs/deployment-on-pythonanywhere.rst +++ b/docs/deployment-on-pythonanywhere.rst @@ -34,7 +34,7 @@ Make sure your project is fully committed and pushed up to Bitbucket or Github o git clone # you can also use hg cd my-project-name - mkvirtualenv --python=/usr/bin/python3.9 my-project-name + mkvirtualenv --python=/usr/bin/python3.10 my-project-name pip install -r requirements/production.txt # may take a few minutes diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst index 20f2492e3..4bf49488d 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -9,7 +9,7 @@ Setting Up Development Environment Make sure to have the following on your host: -* Python 3.9 +* Python 3.10 * PostgreSQL_. * Redis_, if using Celery * Cookiecutter_ @@ -18,7 +18,7 @@ First things first. #. Create a virtualenv: :: - $ python3.9 -m venv + $ python3.10 -m venv #. Activate the virtualenv you have just created: :: @@ -82,7 +82,7 @@ First things first. or if you're running asynchronously: :: - $ uvicorn config.asgi:application --host 0.0.0.0 --reload + $ uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html' .. _PostgreSQL: https://www.postgresql.org/download/ .. _Redis: https://redis.io/download diff --git a/docs/faq.rst b/docs/faq.rst index 820fb60fa..52a99467c 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -6,7 +6,7 @@ FAQ Why is there a django.contrib.sites directory in Cookiecutter Django? --------------------------------------------------------------------- -It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and {{cookiecutter.project_name}} value is placed by **Cookiecutter** in the domain and name fields respectively. +It is there to add a migration so you don't have to manually change the ``sites.Site`` record from ``example.com`` to whatever your domain is. Instead, your ``{{cookiecutter.domain_name}}`` and ``{{cookiecutter.project_name}}`` value is placed by **Cookiecutter** in the domain and name fields respectively. See `0003_set_site_domain_and_name.py`_. diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index d65c6d640..d4ad8a9aa 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -55,18 +55,19 @@ use_docker: postgresql_version: Select a PostgreSQL_ version to use. The choices are: - 1. 14.1 - 2. 13.5 - 3. 12.9 - 4. 11.14 - 5. 10.19 + 1. 14 + 2. 13 + 3. 12 + 4. 11 + 5. 10 cloud_provider: Select a cloud provider for static & media files. The choices are: 1. AWS_ 2. GCP_ - 3. None + 3. Azure_ + 4. None Note that if you choose no cloud provider, media files won't work. @@ -151,6 +152,7 @@ debug: .. _AWS: https://aws.amazon.com/s3/ .. _GCP: https://cloud.google.com/storage/ +.. _Azure: https://azure.microsoft.com/en-us/products/storage/blobs/ .. _Amazon SES: https://aws.amazon.com/ses/ .. _Mailgun: https://www.mailgun.com diff --git a/docs/requirements.txt b/docs/requirements.txt index ba0b67c5f..2cc8302a2 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,2 @@ -sphinx==4.5.0 -sphinx-rtd-theme==1.0.0 +sphinx==5.3.0 +sphinx-rtd-theme==1.1.1 diff --git a/docs/settings.rst b/docs/settings.rst index 7563f50d2..4691adbbd 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -46,8 +46,12 @@ DJANGO_AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY n/a DJANGO_AWS_STORAGE_BUCKET_NAME AWS_STORAGE_BUCKET_NAME n/a raises error DJANGO_AWS_S3_REGION_NAME AWS_S3_REGION_NAME n/a None DJANGO_AWS_S3_CUSTOM_DOMAIN AWS_S3_CUSTOM_DOMAIN n/a None +DJANGO_AWS_S3_MAX_MEMORY_SIZE AWS_S3_MAX_MEMORY_SIZE n/a 100_000_000 DJANGO_GCP_STORAGE_BUCKET_NAME GS_BUCKET_NAME n/a raises error GOOGLE_APPLICATION_CREDENTIALS n/a n/a raises error +DJANGO_AZURE_ACCOUNT_KEY AZURE_ACCOUNT_KEY n/a raises error +DJANGO_AZURE_ACCOUNT_NAME AZURE_ACCOUNT_NAME n/a raises error +DJANGO_AZURE_CONTAINER_NAME AZURE_CONTAINER n/a raises error SENTRY_DSN SENTRY_DSN n/a raises error SENTRY_ENVIRONMENT n/a n/a production SENTRY_TRACES_SAMPLE_RATE n/a n/a 0.0 diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py index 3fd4131c8..c3eef1e43 100644 --- a/hooks/pre_gen_project.py +++ b/hooks/pre_gen_project.py @@ -36,7 +36,7 @@ if "{{ cookiecutter.use_docker }}".lower() == "n": if python_major_version == 2: print( WARNING + "You're running cookiecutter under Python 2, but the generated " - "project requires Python 3.9+. Do you want to proceed (y/n)? " + TERMINATOR + "project requires Python 3.10+. Do you want to proceed (y/n)? " + TERMINATOR ) yes_options, no_options = frozenset(["y"]), frozenset(["n"]) while True: @@ -72,11 +72,8 @@ if ( sys.exit(1) if ( - "{{ cookiecutter.cloud_provider }}" == "GCP" - and "{{ cookiecutter.mail_service }}" == "Amazon SES" -) or ( - "{{ cookiecutter.cloud_provider }}" == "None" - and "{{ cookiecutter.mail_service }}" == "Amazon SES" + "{{ cookiecutter.mail_service }}" == "Amazon SES" + and "{{ cookiecutter.cloud_provider }}" != "AWS" ): print( "You should either use AWS or select a different " diff --git a/requirements.txt b/requirements.txt index 3f480418c..684ec91e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,26 +1,26 @@ -cookiecutter==1.7.3 -sh==1.14.2 +cookiecutter==2.1.1 +sh==1.14.3; sys_platform != "win32" binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==22.3.0 +black==22.10.0 isort==5.10.1 -flake8==4.0.1 -flake8-isort==4.1.1 -pre-commit==2.18.1 +flake8==6.0.0 +flake8-isort==5.0.3 +pre-commit==2.20.0 # Testing # ------------------------------------------------------------------------------ -tox==3.25.0 -pytest==7.1.2 +tox==3.27.1 +pytest==7.2.0 pytest-cookies==0.6.1 pytest-instafail==0.4.2 pyyaml==6.0 # Scripting # ------------------------------------------------------------------------------ -PyGithub==1.55 -gitpython==3.1.27 -jinja2==3.1.1 -requests==2.27.1 +PyGithub==1.57 +gitpython==3.1.29 +jinja2==3.1.2 +requests==2.28.1 diff --git a/scripts/create_django_issue.py b/scripts/create_django_issue.py index f1ff51a06..5809f393d 100644 --- a/scripts/create_django_issue.py +++ b/scripts/create_django_issue.py @@ -11,8 +11,9 @@ from __future__ import annotations import os import re import sys +from collections.abc import Iterable from pathlib import Path -from typing import TYPE_CHECKING, Any, Iterable, NamedTuple +from typing import TYPE_CHECKING, Any, NamedTuple import requests from github import Github @@ -107,7 +108,7 @@ def get_all_latest_django_versions( current_minor_version = DjVersion.parse(current_version_str) newer_versions: set[DjVersion] = set() for django_version in get_django_versions(): - if _django_max_version >= django_version >= current_minor_version: + if current_minor_version < django_version <= _django_max_version: newer_versions.add(django_version) return current_minor_version, sorted(newer_versions, reverse=True) diff --git a/scripts/update_changelog.py b/scripts/update_changelog.py index c3c834eef..b50d25066 100644 --- a/scripts/update_changelog.py +++ b/scripts/update_changelog.py @@ -1,8 +1,8 @@ import datetime as dt import os import re +from collections.abc import Iterable from pathlib import Path -from typing import Iterable import git import github.PullRequest diff --git a/setup.py b/setup.py index 3b3bf6b2f..e187601c3 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2022.04.27" +version = "2022.12.04" with open("README.rst") as readme_file: long_description = readme_file.read() @@ -27,13 +27,13 @@ setup( classifiers=[ "Development Status :: 4 - Beta", "Environment :: Console", - "Framework :: Django :: 3.2", + "Framework :: Django :: 4.0", "Intended Audience :: Developers", "Natural Language :: English", "License :: OSI Approved :: BSD License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development", ], diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 147e4e98e..6e14f880c 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -47,15 +47,17 @@ SUPPORTED_COMBINATIONS = [ {"use_pycharm": "n"}, {"use_docker": "y"}, {"use_docker": "n"}, - {"postgresql_version": "14.1"}, - {"postgresql_version": "13.5"}, - {"postgresql_version": "12.9"}, - {"postgresql_version": "11.14"}, - {"postgresql_version": "10.19"}, + {"postgresql_version": "14"}, + {"postgresql_version": "13"}, + {"postgresql_version": "12"}, + {"postgresql_version": "11"}, + {"postgresql_version": "10"}, {"cloud_provider": "AWS", "use_whitenoise": "y"}, {"cloud_provider": "AWS", "use_whitenoise": "n"}, {"cloud_provider": "GCP", "use_whitenoise": "y"}, {"cloud_provider": "GCP", "use_whitenoise": "n"}, + {"cloud_provider": "Azure", "use_whitenoise": "y"}, + {"cloud_provider": "Azure", "use_whitenoise": "n"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailgun"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mailjet"}, {"cloud_provider": "None", "use_whitenoise": "y", "mail_service": "Mandrill"}, @@ -82,13 +84,22 @@ SUPPORTED_COMBINATIONS = [ {"cloud_provider": "GCP", "mail_service": "SendinBlue"}, {"cloud_provider": "GCP", "mail_service": "SparkPost"}, {"cloud_provider": "GCP", "mail_service": "Other SMTP"}, - # Note: cloud_providers GCP and None with mail_service Amazon SES is not supported + {"cloud_provider": "Azure", "mail_service": "Mailgun"}, + {"cloud_provider": "Azure", "mail_service": "Mailjet"}, + {"cloud_provider": "Azure", "mail_service": "Mandrill"}, + {"cloud_provider": "Azure", "mail_service": "Postmark"}, + {"cloud_provider": "Azure", "mail_service": "Sendgrid"}, + {"cloud_provider": "Azure", "mail_service": "SendinBlue"}, + {"cloud_provider": "Azure", "mail_service": "SparkPost"}, + {"cloud_provider": "Azure", "mail_service": "Other SMTP"}, + # Note: cloud_providers GCP, Azure, and None + # with mail_service Amazon SES is not supported {"use_async": "y"}, {"use_async": "n"}, {"use_drf": "y"}, {"use_drf": "n"}, {"frontend_pipeline": "None"}, - {"frontend_pipeline": "django-compressor"}, + {"frontend_pipeline": "Django Compressor"}, {"frontend_pipeline": "Gulp"}, {"frontend_pipeline": "Webpack"}, {"use_celery": "y"}, @@ -114,6 +125,7 @@ SUPPORTED_COMBINATIONS = [ UNSUPPORTED_COMBINATIONS = [ {"cloud_provider": "None", "use_whitenoise": "n"}, {"cloud_provider": "GCP", "mail_service": "Amazon SES"}, + {"cloud_provider": "Azure", "mail_service": "Amazon SES"}, {"cloud_provider": "None", "mail_service": "Amazon SES"}, ] @@ -139,7 +151,7 @@ def check_paths(paths): if is_binary(path): continue - for line in open(path, "r"): + for line in open(path): match = RE_OBJ.search(line) assert match is None, f"cookiecutter variable not replaced in {path}" @@ -204,7 +216,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip assert result.project_path.name == context["project_slug"] assert result.project_path.is_dir() - with open(f"{result.project_path}/.travis.yml", "r") as travis_yml: + with open(f"{result.project_path}/.travis.yml") as travis_yml: try: yml = yaml.safe_load(travis_yml)["jobs"]["include"] assert yml[0]["script"] == ["flake8"] @@ -231,7 +243,7 @@ def test_gitlab_invokes_flake8_and_pytest( assert result.project_path.name == context["project_slug"] assert result.project_path.is_dir() - with open(f"{result.project_path}/.gitlab-ci.yml", "r") as gitlab_yml: + with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml: try: gitlab_config = yaml.safe_load(gitlab_yml) assert gitlab_config["flake8"]["script"] == ["flake8"] @@ -258,7 +270,7 @@ def test_github_invokes_linter_and_pytest( assert result.project_path.name == context["project_slug"] assert result.project_path.is_dir() - with open(f"{result.project_path}/.github/workflows/ci.yml", "r") as github_yml: + with open(f"{result.project_path}/.github/workflows/ci.yml") as github_yml: try: github_config = yaml.safe_load(github_yml) linter_present = False @@ -309,6 +321,6 @@ def test_pycharm_docs_removed(cookies, context, use_pycharm, pycharm_docs_exist) context.update({"use_pycharm": use_pycharm}) result = cookies.bake(extra_context=context) - with open(f"{result.project_path}/docs/index.rst", "r") as f: + with open(f"{result.project_path}/docs/index.rst") as f: has_pycharm_docs = "pycharm/configuration" in f.read() assert has_pycharm_docs is pycharm_docs_exist diff --git a/tox.ini b/tox.ini index 0afe3931d..0400e4f91 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] skipsdist = true -envlist = py39,black-template +envlist = py310,black-template [testenv] deps = -rrequirements.txt diff --git a/{{cookiecutter.project_slug}}/.envs/.production/.django b/{{cookiecutter.project_slug}}/.envs/.production/.django index e7e8461c9..ad652c9ad 100644 --- a/{{cookiecutter.project_slug}}/.envs/.production/.django +++ b/{{cookiecutter.project_slug}}/.envs/.production/.django @@ -44,6 +44,12 @@ DJANGO_AWS_STORAGE_BUCKET_NAME= # ------------------------------------------------------------------------------ GOOGLE_APPLICATION_CREDENTIALS= DJANGO_GCP_STORAGE_BUCKET_NAME= +{% elif cookiecutter.cloud_provider == 'Azure' %} +# Azure +# ------------------------------------------------------------------------------ +DJANGO_AZURE_ACCOUNT_KEY= +DJANGO_AZURE_ACCOUNT_NAME= +DJANGO_AZURE_CONTAINER_NAME= {% endif %} # django-allauth # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 20dd0d2f3..0790187bd 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v3 with: - python-version: "3.9" + python-version: "3.10" cache: pip cache-dependency-path: | requirements/base.txt @@ -87,7 +87,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v3 with: - python-version: "3.9" + python-version: "3.10" cache: pip cache-dependency-path: | requirements/base.txt diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index fb82ec5d5..dbb65fb73 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -13,7 +13,7 @@ variables: flake8: stage: lint - image: python:3.9-alpine + image: python:3.10-alpine before_script: - pip install -q flake8 script: @@ -35,7 +35,7 @@ pytest: script: - docker-compose -f local.yml run django pytest {%- else -%} - image: python:3.9 + image: python:3.10 tags: - python services: diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index dd663231e..516323b42 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -3,14 +3,20 @@ default_stages: [commit] repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v4.4.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + - repo: https://github.com/asottile/pyupgrade + rev: v3.3.0 + hooks: + - id: pyupgrade + args: [--py310-plus] + - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 22.10.0 hooks: - id: black @@ -20,7 +26,7 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 6.0.0 hooks: - id: flake8 args: ["--config=setup.cfg"] diff --git a/{{cookiecutter.project_slug}}/.pylintrc b/{{cookiecutter.project_slug}}/.pylintrc index 6f195c6ef..9d604334b 100644 --- a/{{cookiecutter.project_slug}}/.pylintrc +++ b/{{cookiecutter.project_slug}}/.pylintrc @@ -1,6 +1,6 @@ [MASTER] load-plugins=pylint_django{% if cookiecutter.use_celery == "y" %}, pylint_celery{% endif %} -django-settings-module=config.settings.base +django-settings-module=config.settings.local [FORMAT] max-line-length=120 diff --git a/{{cookiecutter.project_slug}}/.readthedocs.yml b/{{cookiecutter.project_slug}}/.readthedocs.yml index b4cf0c080..e943a5fa9 100644 --- a/{{cookiecutter.project_slug}}/.readthedocs.yml +++ b/{{cookiecutter.project_slug}}/.readthedocs.yml @@ -7,6 +7,6 @@ build: image: testing python: - version: 3.9 + version: 3.10 install: - requirements: requirements/local.txt diff --git a/{{cookiecutter.project_slug}}/.travis.yml b/{{cookiecutter.project_slug}}/.travis.yml index a684da225..326d78392 100644 --- a/{{cookiecutter.project_slug}}/.travis.yml +++ b/{{cookiecutter.project_slug}}/.travis.yml @@ -2,7 +2,7 @@ dist: focal language: python python: - - "3.9" + - "3.10" services: - {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %} @@ -37,7 +37,7 @@ jobs: - sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm language: python python: - - "3.9" + - "3.10" install: - pip install -r requirements/local.txt script: diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index 044ef4a74..3ea6b2d4c 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye +ARG PYTHON_VERSION=3.10-slim-bullseye # define an alias for the specfic python version used in this file. FROM python:${PYTHON_VERSION} as python diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start index c04a7365e..61f83968b 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start +++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start @@ -5,4 +5,4 @@ set -o nounset rm -f './celerybeat.pid' -celery -A config.celery_app beat -l INFO +exec watchfiles celery.__main__.main --args '-A config.celery_app beat -l INFO' diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start index bd3c9f2fd..ac3cc6b36 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start +++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start @@ -3,9 +3,6 @@ set -o errexit set -o nounset - -celery \ - -A config.celery_app \ - -b "${CELERY_BROKER_URL}" \ - flower \ - --basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}" +exec watchfiles celery.__main__.main \ + --args \ + "-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\"" diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start index d7b63cd41..16341fdd1 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start +++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/worker/start @@ -4,4 +4,4 @@ set -o errexit set -o nounset -watchgod celery.__main__.main --args -A config.celery_app worker -l INFO +exec watchfiles celery.__main__.main --args '-A config.celery_app worker -l INFO' diff --git a/{{cookiecutter.project_slug}}/compose/local/django/start b/{{cookiecutter.project_slug}}/compose/local/django/start index 9cbb6c897..ec57dc8e4 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/start +++ b/{{cookiecutter.project_slug}}/compose/local/django/start @@ -7,7 +7,7 @@ set -o nounset python manage.py migrate {%- if cookiecutter.use_async == 'y' %} -uvicorn config.asgi:application --host 0.0.0.0 --reload +exec uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html' {%- else %} -python manage.py runserver_plus 0.0.0.0:8000 +exec python manage.py runserver_plus 0.0.0.0:8000 {%- endif %} diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index 6f1bb8b5e..c45d18c95 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye +ARG PYTHON_VERSION=3.10-slim-bullseye # define an alias for the specfic python version used in this file. FROM python:${PYTHON_VERSION} as python @@ -22,7 +22,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ COPY ./requirements /requirements # create python dependency wheels -RUN pip wheel --no-cache-dir --no-deps --wheel-dir /usr/src/app/wheels \ +RUN pip wheel --no-cache-dir --wheel-dir /usr/src/app/wheels \ -r /requirements/local.txt -r /requirements/production.txt \ && rm -rf /requirements diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/start b/{{cookiecutter.project_slug}}/compose/local/docs/start index fd2e0de6a..96a94f566 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/start +++ b/{{cookiecutter.project_slug}}/compose/local/docs/start @@ -4,4 +4,4 @@ set -o errexit set -o pipefail set -o nounset -make livehtml +exec make livehtml diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index fa495023b..891495750 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -1,4 +1,4 @@ -ARG PYTHON_VERSION=3.9-slim-bullseye +ARG PYTHON_VERSION=3.10-slim-bullseye {% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%} FROM node:16-bullseye-slim as client-builder diff --git a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint index 95ab8297a..2fbcad955 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/entrypoint +++ b/{{cookiecutter.project_slug}}/compose/production/django/entrypoint @@ -16,30 +16,34 @@ if [ -z "${POSTGRES_USER}" ]; then fi export DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}" -postgres_ready() { python << END import sys +import time import psycopg2 -try: - psycopg2.connect( - dbname="${POSTGRES_DB}", - user="${POSTGRES_USER}", - password="${POSTGRES_PASSWORD}", - host="${POSTGRES_HOST}", - port="${POSTGRES_PORT}", - ) -except psycopg2.OperationalError: - sys.exit(-1) -sys.exit(0) +suggest_unrecoverable_after = 30 +start = time.time() +while True: + try: + psycopg2.connect( + dbname="${POSTGRES_DB}", + user="${POSTGRES_USER}", + password="${POSTGRES_PASSWORD}", + host="${POSTGRES_HOST}", + port="${POSTGRES_PORT}", + ) + break + except psycopg2.OperationalError as error: + sys.stderr.write("Waiting for PostgreSQL to become available...\n") + + if time.time() - start > suggest_unrecoverable_after: + sys.stderr.write(" This is taking longer than expected. The following exception may be indicative of an unrecoverable error: '{}'\n".format(error)) + + time.sleep(1) END -} -until postgres_ready; do - >&2 echo 'Waiting for PostgreSQL to become available...' - sleep 1 -done + >&2 echo 'PostgreSQL is available' exec "$@" diff --git a/{{cookiecutter.project_slug}}/compose/production/django/start b/{{cookiecutter.project_slug}}/compose/production/django/start index 2ba79501c..73f686bd7 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/start +++ b/{{cookiecutter.project_slug}}/compose/production/django/start @@ -28,7 +28,7 @@ if compress_enabled; then fi {%- endif %} {%- if cookiecutter.use_async == 'y' %} -/usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker +exec /usr/local/bin/gunicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app -k uvicorn.workers.UvicornWorker {%- else %} -/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app +exec /usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app {%- endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index fd94d34b5..26aa5f76a 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -30,8 +30,6 @@ LANGUAGE_CODE = "en-us" SITE_ID = 1 # https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n USE_I18N = True -# https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n -USE_L10N = True # https://docs.djangoproject.com/en/dev/ref/settings/#use-tz USE_TZ = True # https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths @@ -286,6 +284,8 @@ if USE_TZ: CELERY_BROKER_URL = env("CELERY_BROKER_URL") # https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-result_backend CELERY_RESULT_BACKEND = CELERY_BROKER_URL +# https://docs.celeryq.dev/en/stable/userguide/configuration.html#result-extended +CELERY_RESULT_EXTENDED = True # https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-accept_content CELERY_ACCEPT_CONTENT = ["json"] # https://docs.celeryq.dev/en/stable/userguide/configuration.html#std:setting-task_serializer @@ -300,6 +300,10 @@ CELERY_TASK_TIME_LIMIT = 5 * 60 CELERY_TASK_SOFT_TIME_LIMIT = 60 # https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-scheduler CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" +# https://docs.celeryq.dev/en/stable/userguide/configuration.html#worker-send-task-events +CELERY_WORKER_SEND_TASK_EVENTS = True +# https://docs.celeryq.dev/en/stable/userguide/configuration.html#std-setting-task_send_sent_event +CELERY_TASK_SEND_SENT_EVENT = True {%- endif %} # django-allauth diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index b792e5448..40d3f19cc 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -88,6 +88,11 @@ AWS_S3_OBJECT_PARAMETERS = { "CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate" } # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings +AWS_S3_MAX_MEMORY_SIZE = env.int( + "DJANGO_AWS_S3_MAX_MEMORY_SIZE", + default=100_000_000, # 100MB +) +# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#cloudfront AWS_S3_CUSTOM_DOMAIN = env("DJANGO_AWS_S3_CUSTOM_DOMAIN", default=None) @@ -95,6 +100,10 @@ aws_s3_domain = AWS_S3_CUSTOM_DOMAIN or f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws {% elif cookiecutter.cloud_provider == 'GCP' %} GS_BUCKET_NAME = env("DJANGO_GCP_STORAGE_BUCKET_NAME") GS_DEFAULT_ACL = "publicRead" +{% elif cookiecutter.cloud_provider == 'Azure' %} +AZURE_ACCOUNT_KEY = env("DJANGO_AZURE_ACCOUNT_KEY") +AZURE_ACCOUNT_NAME = env("DJANGO_AZURE_ACCOUNT_NAME") +AZURE_CONTAINER = env("DJANGO_AZURE_CONTAINER_NAME") {% endif -%} {% if cookiecutter.cloud_provider != 'None' or cookiecutter.use_whitenoise == 'y' -%} @@ -111,6 +120,9 @@ STATIC_URL = f"https://{aws_s3_domain}/static/" STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootGoogleCloudStorage" COLLECTFAST_STRATEGY = "collectfast.strategies.gcloud.GoogleCloudStrategy" STATIC_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/static/" +{% elif cookiecutter.cloud_provider == 'Azure' -%} +STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootAzureStorage" +STATIC_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/" {% endif -%} # MEDIA @@ -121,6 +133,9 @@ MEDIA_URL = f"https://{aws_s3_domain}/media/" {%- elif cookiecutter.cloud_provider == 'GCP' %} DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootGoogleCloudStorage" MEDIA_URL = f"https://storage.googleapis.com/{GS_BUCKET_NAME}/media/" +{%- elif cookiecutter.cloud_provider == 'Azure' %} +DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootAzureStorage" +MEDIA_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/media/" {%- endif %} # EMAIL @@ -167,7 +182,6 @@ EMAIL_BACKEND = "anymail.backends.mailjet.EmailBackend" ANYMAIL = { "MAILJET_API_KEY": env("MAILJET_API_KEY"), "MAILJET_SECRET_KEY": env("MAILJET_SECRET_KEY"), - "MAILJET_API_URL": env("MAILJET_API_URL", default="https://api.mailjet.com/v3"), } {%- elif cookiecutter.mail_service == 'Mandrill' %} # https://anymail.readthedocs.io/en/stable/esps/mandrill/ @@ -190,8 +204,6 @@ ANYMAIL = { EMAIL_BACKEND = "anymail.backends.sendgrid.EmailBackend" ANYMAIL = { "SENDGRID_API_KEY": env("SENDGRID_API_KEY"), - "SENDGRID_GENERATE_MESSAGE_ID": env("SENDGRID_GENERATE_MESSAGE_ID"), - "SENDGRID_MERGE_FIELD_FORMAT": env("SENDGRID_MERGE_FIELD_FORMAT"), "SENDGRID_API_URL": env("SENDGRID_API_URL", default="https://api.sendgrid.com/v3/"), } {%- elif cookiecutter.mail_service == 'SendinBlue' %} @@ -226,7 +238,7 @@ COMPRESS_ENABLED = env.bool("COMPRESS_ENABLED", default=True) {%- if cookiecutter.cloud_provider == 'None' %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage" -{%- elif cookiecutter.cloud_provider in ('AWS', 'GCP') and cookiecutter.use_whitenoise == 'n' %} +{%- elif cookiecutter.cloud_provider in ('AWS', 'GCP', 'Azure') and cookiecutter.use_whitenoise == 'n' %} # https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_STORAGE COMPRESS_STORAGE = STATICFILES_STORAGE {%- endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index 78fb6cc66..f103eb10b 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -25,5 +25,9 @@ PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"] # https://docs.djangoproject.com/en/dev/ref/settings/#email-backend EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" +# DEBUGING FOR TEMPLATES +# ------------------------------------------------------------------------------ +TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa F405 + # Your stuff... # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/gulpfile.js b/{{cookiecutter.project_slug}}/gulpfile.js index 7056b10ac..afc2b0abd 100644 --- a/{{cookiecutter.project_slug}}/gulpfile.js +++ b/{{cookiecutter.project_slug}}/gulpfile.js @@ -42,7 +42,7 @@ function pathsConfig(appName) { } } -var paths = pathsConfig() +const paths = pathsConfig() //////////////////////////////// // Tasks @@ -50,12 +50,12 @@ var paths = pathsConfig() // Styles autoprefixing and minification function styles() { - var processCss = [ + const processCss = [ autoprefixer(), // adds vendor prefixes pixrem(), // add fallbacks for rem units ] - var minifyCss = [ + const minifyCss = [ cssnano({ preset: 'default' }) // minify result ] @@ -104,15 +104,18 @@ function imgCompression() { {%- if cookiecutter.use_async == 'y' -%} // Run django server function asyncRunServer() { - var cmd = spawn('uvicorn', ['config.asgi:application', '--reload'], {stdio: 'inherit'}) + const cmd = spawn('gunicorn', [ + 'config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload' + ], {stdio: 'inherit'} + ) cmd.on('close', function(code) { - console.log('uvicorn exited with code ' + code) + console.log('gunicorn exited with code ' + code) }) } {%- else %} // Run django server function runServer(cb) { - var cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'}) + const cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'}) cmd.on('close', function(code) { console.log('runServer exited with code ' + code) cb(code) diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index 3ffd63298..798fa0897 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -11,7 +11,6 @@ services: dockerfile: ./compose/local/django/Dockerfile image: {{ cookiecutter.project_slug }}_local_django container_name: {{ cookiecutter.project_slug }}_local_django - platform: linux/x86_64 depends_on: - postgres {%- if cookiecutter.use_celery == 'y' %} @@ -44,7 +43,6 @@ services: docs: image: {{ cookiecutter.project_slug }}_local_docs container_name: {{ cookiecutter.project_slug }}_local_docs - platform: linux/x86_64 build: context: . dockerfile: ./compose/local/docs/Dockerfile diff --git a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py index d1170eff6..d702a5f67 100644 --- a/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py +++ b/{{cookiecutter.project_slug}}/merge_production_dotenvs_in_dotenv.py @@ -1,6 +1,6 @@ import os +from collections.abc import Sequence from pathlib import Path -from typing import Sequence import pytest @@ -18,7 +18,7 @@ def merge( ) -> None: with open(output_file_path, "w") as output_file: for merged_file_path in merged_file_paths: - with open(merged_file_path, "r") as merged_file: + with open(merged_file_path) as merged_file: merged_file_content = merged_file.read() output_file.write(merged_file_content) if append_linesep: @@ -41,7 +41,7 @@ def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool): for i in range(merged_file_count): merged_file_ord = i + 1 - merged_filename = ".service{}".format(merged_file_ord) + merged_filename = f".service{merged_file_ord}" merged_file_path = tmp_dir_path / merged_filename merged_file_content = merged_filename * merged_file_ord @@ -57,7 +57,7 @@ def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool): merge(output_file_path, merged_file_paths, append_linesep) - with open(output_file_path, "r") as output_file: + with open(output_file_path) as output_file: actual_output_file_content = output_file.read() assert actual_output_file_content == expected_output_file_content diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml index ee1c161e1..5c609ce12 100644 --- a/{{cookiecutter.project_slug}}/production.yml +++ b/{{cookiecutter.project_slug}}/production.yml @@ -22,7 +22,6 @@ services: {%- endif %} image: {{ cookiecutter.project_slug }}_production_django - platform: linux/x86_64 depends_on: - postgres - redis diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index 7aac5faf1..f6ca7c9af 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,6 +1,6 @@ -pytz==2022.1 # https://github.com/stub42/pytz -python-slugify==6.1.2 # https://github.com/un33k/python-slugify -Pillow==9.1.0 # https://github.com/python-pillow/Pillow +pytz==2022.6 # https://github.com/stub42/pytz +python-slugify==7.0.0 # https://github.com/un33k/python-slugify +Pillow==9.3.0 # https://github.com/python-pillow/Pillow {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin @@ -10,41 +10,41 @@ rcssmin==1.1.0 # https://github.com/ndparker/rcssmin {%- endif %} argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} -whitenoise==6.0.0 # https://github.com/evansd/whitenoise +whitenoise==6.2.0 # https://github.com/evansd/whitenoise {%- endif %} -redis==4.2.2 # https://github.com/redis/redis-py +redis==4.4.0 # https://github.com/redis/redis-py {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} hiredis==2.0.0 # https://github.com/redis/hiredis-py {%- endif %} {%- if cookiecutter.use_celery == "y" %} -celery==5.2.6 # pyup: < 6.0 # https://github.com/celery/celery -django-celery-beat==2.2.1 # https://github.com/celery/django-celery-beat +celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery +django-celery-beat==2.4.0 # https://github.com/celery/django-celery-beat {%- if cookiecutter.use_docker == 'y' %} -flower==1.0.0 # https://github.com/mher/flower +flower==1.2.0 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn[standard]==0.17.6 # https://github.com/encode/uvicorn +uvicorn[standard]==0.20.0 # https://github.com/encode/uvicorn {%- endif %} # Django # ------------------------------------------------------------------------------ -django==3.2.13 # pyup: < 4.0 # https://www.djangoproject.com/ -django-environ==0.8.1 # https://github.com/joke2k/django-environ -django-model-utils==4.2.0 # https://github.com/jazzband/django-model-utils -django-allauth==0.50.0 # https://github.com/pennersr/django-allauth +django==4.0.8 # pyup: < 4.1 # https://www.djangoproject.com/ +django-environ==0.9.0 # https://github.com/joke2k/django-environ +django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils +django-allauth==0.51.0 # https://github.com/pennersr/django-allauth django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-crispy-forms -crispy-bootstrap5==0.6 # https://github.com/django-crispy-forms/crispy-bootstrap5 +crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5 {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} -django-compressor==3.1 # https://github.com/django-compressor/django-compressor +django-compressor==4.1 # https://github.com/django-compressor/django-compressor {%- endif %} django-redis==5.2.0 # https://github.com/jazzband/django-redis {%- if cookiecutter.use_drf == 'y' %} # Django REST Framework -djangorestframework==3.13.1 # https://github.com/encode/django-rest-framework -django-cors-headers==3.11.0 # https://github.com/adamchainz/django-cors-headers +djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework +django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers # DRF-spectacular for api documentation -drf-spectacular==0.22.1 # https://github.com/tfranzel/drf-spectacular +drf-spectacular==0.24.2 # https://github.com/tfranzel/drf-spectacular {%- endif %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %} django-webpack-loader==1.5.0 # https://github.com/django-webpack/django-webpack-loader diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index ea65e429c..6082a72c8 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,48 +1,48 @@ -r base.txt -Werkzeug[watchdog]==2.0.3 # https://github.com/pallets/werkzeug +Werkzeug[watchdog]==2.2.2 # https://github.com/pallets/werkzeug ipdb==0.13.9 # https://github.com/gotcha/ipdb {%- if cookiecutter.use_docker == 'y' %} -psycopg2==2.9.3 # https://github.com/psycopg/psycopg2 +psycopg2==2.9.5 # https://github.com/psycopg/psycopg2 {%- else %} -psycopg2-binary==2.9.3 # https://github.com/psycopg/psycopg2 +psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2 {%- endif %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} -watchgod==0.8.2 # https://github.com/samuelcolvin/watchgod +watchfiles==0.18.1 # https://github.com/samuelcolvin/watchfiles {%- endif %} # Testing # ------------------------------------------------------------------------------ -mypy==0.950 # https://github.com/python/mypy -django-stubs==1.9.0 # https://github.com/typeddjango/django-stubs -pytest==7.1.2 # https://github.com/pytest-dev/pytest -pytest-sugar==0.9.4 # https://github.com/Frozenball/pytest-sugar +mypy==0.982 # https://github.com/python/mypy +django-stubs==1.12.0 # https://github.com/typeddjango/django-stubs +pytest==7.2.0 # https://github.com/pytest-dev/pytest +pytest-sugar==0.9.6 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} -djangorestframework-stubs==1.4.0 # https://github.com/typeddjango/djangorestframework-stubs +djangorestframework-stubs==1.7.0 # https://github.com/typeddjango/djangorestframework-stubs {%- endif %} # Documentation # ------------------------------------------------------------------------------ -sphinx==4.5.0 # https://github.com/sphinx-doc/sphinx +sphinx==5.3.0 # https://github.com/sphinx-doc/sphinx sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8==4.0.1 # https://github.com/PyCQA/flake8 -flake8-isort==4.1.1 # https://github.com/gforcada/flake8-isort -coverage==6.3.2 # https://github.com/nedbat/coveragepy -black==22.3.0 # https://github.com/psf/black +flake8==6.0.0 # https://github.com/PyCQA/flake8 +flake8-isort==5.0.3 # https://github.com/gforcada/flake8-isort +coverage==6.5.0 # https://github.com/nedbat/coveragepy +black==22.10.0 # https://github.com/psf/black pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django {%- if cookiecutter.use_celery == 'y' %} pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery {%- endif %} -pre-commit==2.18.1 # https://github.com/pre-commit/pre-commit +pre-commit==2.20.0 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy -django-debug-toolbar==3.2.4 # https://github.com/jazzband/django-debug-toolbar -django-extensions==3.1.5 # https://github.com/django-extensions/django-extensions -django-coverage-plugin==2.0.2 # https://github.com/nedbat/django_coverage_plugin +django-debug-toolbar==3.8.1 # https://github.com/jazzband/django-debug-toolbar +django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions +django-coverage-plugin==3.0.0 # https://github.com/nedbat/django_coverage_plugin pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 6708666f9..c9b5b88a7 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -3,12 +3,12 @@ -r base.txt gunicorn==20.1.0 # https://github.com/benoitc/gunicorn -psycopg2==2.9.3 # https://github.com/psycopg/psycopg2 +psycopg2==2.9.5 # https://github.com/psycopg/psycopg2 {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.5.10 # https://github.com/getsentry/sentry-python +sentry-sdk==1.11.1 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.0.0 # https://github.com/redis/hiredis-py @@ -17,26 +17,28 @@ hiredis==2.0.0 # https://github.com/redis/hiredis-py # Django # ------------------------------------------------------------------------------ {%- if cookiecutter.cloud_provider == 'AWS' %} -django-storages[boto3]==1.12.3 # https://github.com/jschneier/django-storages +django-storages[boto3]==1.13.1 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'GCP' %} -django-storages[google]==1.12.3 # https://github.com/jschneier/django-storages +django-storages[google]==1.13.1 # https://github.com/jschneier/django-storages +{%- elif cookiecutter.cloud_provider == 'Azure' %} +django-storages[azure]==1.13.1 # https://github.com/jschneier/django-storages {%- endif %} {%- if cookiecutter.mail_service == 'Mailgun' %} -django-anymail[mailgun]==8.5 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Amazon SES' %} -django-anymail[amazon_ses]==8.5 # https://github.com/anymail/django-anymail +django-anymail[amazon_ses]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mailjet' %} -django-anymail[mailjet]==8.5 # https://github.com/anymail/django-anymail +django-anymail[mailjet]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mandrill' %} -django-anymail[mandrill]==8.5 # https://github.com/anymail/django-anymail +django-anymail[mandrill]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Postmark' %} -django-anymail[postmark]==8.5 # https://github.com/anymail/django-anymail +django-anymail[postmark]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Sendgrid' %} -django-anymail[sendgrid]==8.5 # https://github.com/anymail/django-anymail +django-anymail[sendgrid]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SendinBlue' %} -django-anymail[sendinblue]==8.5 # https://github.com/anymail/django-anymail +django-anymail[sendinblue]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SparkPost' %} -django-anymail[sparkpost]==8.5 # https://github.com/anymail/django-anymail +django-anymail[sparkpost]==8.6 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Other SMTP' %} -django-anymail==8.5 # https://github.com/anymail/django-anymail +django-anymail==8.6 # https://github.com/anymail/django-anymail {%- endif %} diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 425359e69..69b0ccfc8 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.9.9 +python-3.10.8 diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg index dad64e1fa..3bec1fbee 100644 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ b/{{cookiecutter.project_slug}}/setup.cfg @@ -18,7 +18,7 @@ force_grid_wrap = 0 use_parentheses = true [mypy] -python_version = 3.9 +python_version = 3.10 check_untyped_defs = True ignore_missing_imports = True warn_unused_ignores = True diff --git a/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt b/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt new file mode 100644 index 000000000..63d1587e6 --- /dev/null +++ b/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt @@ -0,0 +1,23 @@ +##basic build dependencies of various Django apps for Ubuntu Jammy 22.04 +#build-essential metapackage install: make, gcc, g++, +build-essential +#required to translate +gettext +python3-dev + +##shared dependencies of: +##Pillow, pylibmc +zlib1g-dev + +##Postgresql and psycopg2 dependencies +libpq-dev + +##Pillow dependencies +libtiff5-dev +libjpeg8-dev +libfreetype6-dev +liblcms2-dev +libwebp-dev + +##django-extensions +graphviz-dev diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py index b4056707a..fb6532709 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/__init__.py @@ -1,7 +1,5 @@ __version__ = "{{ cookiecutter.version }}" __version_info__ = tuple( - [ - int(num) if num.isdigit() else num - for num in __version__.replace("-", ".", 1).split(".") - ] + int(num) if num.isdigit() else num + for num in __version__.replace("-", ".", 1).split(".") ) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py index 335648e07..7095a4714 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/conftest.py @@ -10,5 +10,5 @@ def media_storage(settings, tmpdir): @pytest.fixture -def user() -> User: +def user(db) -> User: return UserFactory() diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py index 4c4d6954c..acd18512f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py @@ -1,4 +1,3 @@ -# Generated by Django 3.2.9 on 2021-11-20 11:23 import django.contrib.auth.models import django.contrib.auth.validators from django.db import migrations, models diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py index edd306cb8..e30476227 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -1,4 +1,5 @@ -from typing import Any, Sequence +from collections.abc import Sequence +from typing import Any from django.contrib.auth import get_user_model from factory import Faker, post_generation diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py index c50a4be4c..a370784fc 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_admin.py @@ -1,10 +1,7 @@ -import pytest from django.urls import reverse from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - class TestUserAdmin: def test_changelist(self, admin_client): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py index 83b623f45..7d9c444d3 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_urls.py @@ -1,10 +1,7 @@ -import pytest from django.urls import resolve, reverse from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - def test_user_detail(user: User): assert ( diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py index 924573089..4d163bf08 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_drf_views.py @@ -1,11 +1,8 @@ -import pytest from django.test import RequestFactory from {{ cookiecutter.project_slug }}.users.api.views import UserViewSet from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - class TestUserViewSet: def test_get_queryset(self, user: User, rf: RequestFactory): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py index e51bb6bf2..261f88c8c 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_forms.py @@ -1,14 +1,11 @@ """ Module for all Form Tests. """ -import pytest from django.utils.translation import gettext_lazy as _ from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - class TestUserAdminCreationForm: """ diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py index 3194be1fd..b09bcdf0b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_models.py @@ -1,9 +1,5 @@ -import pytest - from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - def test_user_get_absolute_url(user: User): assert user.get_absolute_url() == f"/users/{user.username}/" diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_swagger.py index 7f5b75844..f97658b55 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,8 +1,6 @@ import pytest from django.urls import reverse -pytestmark = pytest.mark.django_db - def test_swagger_accessible_by_admin(admin_client): url = reverse("api-docs") @@ -10,6 +8,7 @@ def test_swagger_accessible_by_admin(admin_client): assert response.status_code == 200 +@pytest.mark.django_db def test_swagger_ui_not_accessible_by_normal_user(client): url = reverse("api-docs") response = client.get(url) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py index aab6d0a87..7cd056db5 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_urls.py @@ -1,10 +1,7 @@ -import pytest from django.urls import resolve, reverse from {{ cookiecutter.project_slug }}.users.models import User -pytestmark = pytest.mark.django_db - def test_detail(user: User): assert ( diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py index 944daca52..d968d7ec9 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/test_views.py @@ -63,7 +63,8 @@ class TestUserUpdateView: # Initialize the form form = UserAdminChangeForm() - form.cleaned_data = [] + form.cleaned_data = {} + form.instance = user view.form_valid(form) messages_sent = [m.message for m in messages.get_messages(request)] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py index b712d3239..27595ad1a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py @@ -22,4 +22,15 @@ class StaticRootGoogleCloudStorage(GoogleCloudStorage): class MediaRootGoogleCloudStorage(GoogleCloudStorage): location = "media" file_overwrite = False +{%- elif cookiecutter.cloud_provider == 'Azure' -%} +from storages.backends.azure_storage import AzureStorage + + +class StaticRootAzureStorage(AzureStorage): + location = "static" + + +class MediaRootAzureStorage(AzureStorage): + location = "media" + file_overwrite = False {%- endif %}