diff --git a/.github/contributors.json b/.github/contributors.json
index ca5762fe8..13c4eafd3 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1387,5 +1387,15 @@
"name": "Morten Kaae",
"github_login": "MortenKaae",
"twitter_username": ""
+ },
+ {
+ "name": "Birtibu",
+ "github_login": "Birtibu",
+ "twitter_username": ""
+ },
+ {
+ "name": "Matheus Jardim Bernardes",
+ "github_login": "matheusjardimb",
+ "twitter_username": ""
}
]
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c7cdda633..dbda77b5e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -30,7 +30,7 @@ jobs:
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
- run: pytest tests
+ run: pytest -n auto tests
docker:
strategy:
@@ -110,6 +110,6 @@ jobs:
run: pip install -r requirements.txt
- uses: actions/setup-node@v3
with:
- node-version: "16"
+ node-version: "18"
- name: Bare Metal ${{ matrix.script.name }}
run: sh tests/test_bare.sh ${{ matrix.script.args }}
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 930465a57..2c7876d3c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -17,13 +17,13 @@ repos:
- id: detect-private-key
- repo: https://github.com/pre-commit/mirrors-prettier
- rev: "v3.0.0-alpha.6"
+ rev: "v3.0.0-alpha.9-for-vscode"
hooks:
- id: prettier
args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade
- rev: v3.3.1
+ rev: v3.4.0
hooks:
- id: pyupgrade
args: [--py311-plus]
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index beb30d845..4598ff77c 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -4,12 +4,17 @@
# Required
version: 2
+# Set the version of Python and other tools you might need
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.11"
+
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
-# Version of Python and requirements required to build the docs
+# Declare the Python requirements required to build your docs
python:
- version: "3.8"
install:
- requirements: docs/requirements.txt
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 415b29a2e..f572bd79e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,266 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
+## 2023.06.08
+
+
+### Fixed
+
+- Fix failure in user view test caused by translations ([#4374](https://github.com/cookiecutter/cookiecutter-django/pull/4374))
+
+### Updated
+
+- Update to Python 3.11.4 in production Docker compose ([#4378](https://github.com/cookiecutter/cookiecutter-django/pull/4378))
+
+- Update to Python 3.11.4 in docs Docker compose ([#4379](https://github.com/cookiecutter/cookiecutter-django/pull/4379))
+
+- Update to Python 3.11.4 in local Docker compose ([#4380](https://github.com/cookiecutter/cookiecutter-django/pull/4380))
+
+- Update celery to 5.3.0 ([#4369](https://github.com/cookiecutter/cookiecutter-django/pull/4369))
+
+- Update werkzeug to 2.3.5 ([#4377](https://github.com/cookiecutter/cookiecutter-django/pull/4377))
+
+## 2023.06.07
+
+
+### Changed
+
+- Replace `runserver` with `runserver_plus` ([#4373](https://github.com/cookiecutter/cookiecutter-django/pull/4373))
+
+- Add translations for Brazilian Portuguese ([#4367](https://github.com/cookiecutter/cookiecutter-django/pull/4367))
+
+### Updated
+
+- Update sentry-sdk to 1.25.1 ([#4376](https://github.com/cookiecutter/cookiecutter-django/pull/4376))
+
+- Update django-extensions to 3.2.3 ([#4372](https://github.com/cookiecutter/cookiecutter-django/pull/4372))
+
+- Update djangorestframework-stubs to 3.14.1 ([#4366](https://github.com/cookiecutter/cookiecutter-django/pull/4366))
+
+- Update django-stubs to 4.2.1 ([#4365](https://github.com/cookiecutter/cookiecutter-django/pull/4365))
+
+- Update mypy to 1.3.0 ([#4327](https://github.com/cookiecutter/cookiecutter-django/pull/4327))
+
+## 2023.06.02
+
+
+### Updated
+
+- Update sentry-sdk to 1.25.0 ([#4364](https://github.com/cookiecutter/cookiecutter-django/pull/4364))
+
+## 2023.05.30
+
+
+### Updated
+
+- Update hiredis to 2.2.3 ([#4360](https://github.com/cookiecutter/cookiecutter-django/pull/4360))
+
+- Update django-debug-toolbar to 4.1.0 ([#4359](https://github.com/cookiecutter/cookiecutter-django/pull/4359))
+
+- Update redis to 4.5.5 ([#4358](https://github.com/cookiecutter/cookiecutter-django/pull/4358))
+
+- Update django-anymail to 10.0 ([#4357](https://github.com/cookiecutter/cookiecutter-django/pull/4357))
+
+- Update coverage to 7.2.7 ([#4356](https://github.com/cookiecutter/cookiecutter-django/pull/4356))
+
+## 2023.05.28
+
+
+## 2023.05.24
+
+
+### Fixed
+
+- Prevent Celery restarts on media file changes ([#4352](https://github.com/cookiecutter/cookiecutter-django/pull/4352))
+
+### Updated
+
+- Update coverage to 7.2.6 ([#4351](https://github.com/cookiecutter/cookiecutter-django/pull/4351))
+
+## 2023.05.23
+
+
+### Changed
+
+- Fix compatibility webpack-bundle-tracker>=2.0.0 js library required after upgrade django-webpack-loader>=2.0.0 ([#4350](https://github.com/cookiecutter/cookiecutter-django/pull/4350))
+
+### Updated
+
+- Update sphinx-rtd-theme to 1.2.1 ([#4348](https://github.com/cookiecutter/cookiecutter-django/pull/4348))
+
+- Update sentry-sdk to 1.24.0 ([#4349](https://github.com/cookiecutter/cookiecutter-django/pull/4349))
+
+- Bump webpack-bundle-tracker from 1.8.1 to 2.0.0 in /{{cookiecutter.project_slug}} ([#4347](https://github.com/cookiecutter/cookiecutter-django/pull/4347))
+
+- Update django-webpack-loader to 2.0.0 ([#4345](https://github.com/cookiecutter/cookiecutter-django/pull/4345))
+
+- Update pytest-xdist to 3.3.1 ([#4344](https://github.com/cookiecutter/cookiecutter-django/pull/4344))
+
+- Update requests to 2.31.0 ([#4346](https://github.com/cookiecutter/cookiecutter-django/pull/4346))
+
+## 2023.05.18
+
+
+### Updated
+
+- Update pre-commit to 3.3.2 ([#4342](https://github.com/cookiecutter/cookiecutter-django/pull/4342))
+
+## 2023.05.17
+
+
+### Updated
+
+- Update sentry-sdk to 1.23.1 ([#4341](https://github.com/cookiecutter/cookiecutter-django/pull/4341))
+
+## 2023.05.15
+
+
+### Updated
+
+- Update django-cors-headers to 4.0.0 ([#4329](https://github.com/cookiecutter/cookiecutter-django/pull/4329))
+
+- Update sentry-sdk to 1.23.0 ([#4337](https://github.com/cookiecutter/cookiecutter-django/pull/4337))
+
+## 2023.05.09
+
+
+### Updated
+
+- Update werkzeug to 2.3.4 ([#4325](https://github.com/cookiecutter/cookiecutter-django/pull/4325))
+
+## 2023.05.08
+
+
+### Updated
+
+- Auto-update pre-commit hooks ([#4320](https://github.com/cookiecutter/cookiecutter-django/pull/4320))
+
+- Update sentry-sdk to 1.22.2 ([#4321](https://github.com/cookiecutter/cookiecutter-django/pull/4321))
+
+## 2023.05.04
+
+
+### Changed
+
+- Remove pytz from dependencies ([#4309](https://github.com/cookiecutter/cookiecutter-django/pull/4309))
+
+### Updated
+
+- Update django-anymail to 9.2 ([#4316](https://github.com/cookiecutter/cookiecutter-django/pull/4316))
+
+- Update pre-commit to 3.3.1 ([#4315](https://github.com/cookiecutter/cookiecutter-django/pull/4315))
+
+- Update coverage to 7.2.5 ([#4314](https://github.com/cookiecutter/cookiecutter-django/pull/4314))
+
+- Update django to 4.1.9 ([#4313](https://github.com/cookiecutter/cookiecutter-django/pull/4313))
+
+- Update sentry-sdk to 1.21.1 ([#4312](https://github.com/cookiecutter/cookiecutter-django/pull/4312))
+
+- Update requests to 2.30.0 ([#4311](https://github.com/cookiecutter/cookiecutter-django/pull/4311))
+
+## 2023.05.02
+
+
+### Updated
+
+- Upgrade traefik to 2.10.1 ([#4304](https://github.com/cookiecutter/cookiecutter-django/pull/4304))
+
+- Update uvicorn to 0.22.0 ([#4305](https://github.com/cookiecutter/cookiecutter-django/pull/4305))
+
+- Update werkzeug to 2.3.3 ([#4307](https://github.com/cookiecutter/cookiecutter-django/pull/4307))
+
+## 2023.04.28
+
+
+### Changed
+
+- Add django-upgrade to pre-commit hooks ([#4298](https://github.com/cookiecutter/cookiecutter-django/pull/4298))
+
+## 2023.04.27
+
+
+### Updated
+
+- Update djangorestframework-stubs to 3.14.0 ([#4303](https://github.com/cookiecutter/cookiecutter-django/pull/4303))
+
+- Update werkzeug to 2.3.1 ([#4302](https://github.com/cookiecutter/cookiecutter-django/pull/4302))
+
+- Update django-stubs to 4.2.0 ([#4301](https://github.com/cookiecutter/cookiecutter-django/pull/4301))
+
+## 2023.04.26
+
+
+### Updated
+
+- Upgrade cssnano to v6.0.0 ([#4233](https://github.com/cookiecutter/cookiecutter-django/pull/4233))
+
+- Upgrade concurrently to 8.0.1 ([#4237](https://github.com/cookiecutter/cookiecutter-django/pull/4237))
+
+- Upgrade to node v18 ([#4294](https://github.com/cookiecutter/cookiecutter-django/pull/4294))
+
+- Update coverage to 7.2.3 ([#4297](https://github.com/cookiecutter/cookiecutter-django/pull/4297))
+
+- Update mypy to 1.2.0 ([#4295](https://github.com/cookiecutter/cookiecutter-django/pull/4295))
+
+- Update werkzeug to 2.3.0 ([#4296](https://github.com/cookiecutter/cookiecutter-django/pull/4296))
+
+## 2023.04.25
+
+
+### Updated
+
+- Update sentry-sdk to 1.21.0 ([#4293](https://github.com/cookiecutter/cookiecutter-django/pull/4293))
+
+- Update sphinx to 6.2.1 ([#4292](https://github.com/cookiecutter/cookiecutter-django/pull/4292))
+
+- Bump traefik from 2.9.10 to 2.10.0 ([#4290](https://github.com/cookiecutter/cookiecutter-django/pull/4290))
+
+- Auto-update pre-commit hooks ([#4288](https://github.com/cookiecutter/cookiecutter-django/pull/4288))
+
+## 2023.04.24
+
+
+### Updated
+
+- Auto-update pre-commit hooks ([#4286](https://github.com/cookiecutter/cookiecutter-django/pull/4286))
+
+- Update sphinx to 6.2.0 ([#4285](https://github.com/cookiecutter/cookiecutter-django/pull/4285))
+
+## 2023.04.19
+
+
+### Updated
+
+- Update sentry-sdk to 1.20.0 ([#4282](https://github.com/cookiecutter/cookiecutter-django/pull/4282))
+
+## 2023.04.18
+
+
+### Documentation
+
+- Document how to add 3rd party packages with Docker ([#4279](https://github.com/cookiecutter/cookiecutter-django/pull/4279))
+
+## 2023.04.15
+
+
+### Changed
+
+- Add username_type option ([#3958](https://github.com/cookiecutter/cookiecutter-django/pull/3958))
+
+- Fix inconsistent line length and move configs to pyproject.toml ([#4276](https://github.com/cookiecutter/cookiecutter-django/pull/4276))
+
+- Relax rules for linting of pull requests on this template ([#4273](https://github.com/cookiecutter/cookiecutter-django/pull/4273))
+
+- Add more pre-commit hooks ([#4266](https://github.com/cookiecutter/cookiecutter-django/pull/4266))
+
+- Upgrade Python to version 3.11 (Faster CPython) ([#4256](https://github.com/cookiecutter/cookiecutter-django/pull/4256))
+
+### Updated
+
+- Update drf-spectacular to 0.26.2 ([#4277](https://github.com/cookiecutter/cookiecutter-django/pull/4277))
+
+- Update pytest to 7.3.1 ([#4272](https://github.com/cookiecutter/cookiecutter-django/pull/4272))
+
## 2023.04.13
### Updated
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 47ece91dc..4e2f1fb31 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -369,6 +369,13 @@ Listed in alphabetical order.
Mathijs Hoogland |
diff --git a/README.md b/README.md
index 988eb970a..767ed5bb7 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ _These features can be enabled during initial project setup._
This project is run by volunteers. Please support them in their efforts to maintain and improve Cookiecutter Django:
- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB.
+- Fabio C. Barrionuevo, Core Developer ([GitHub](https://github.com/luzfcb)): expertise in Python/Django, hands-on DevOps and frontend experience.
- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience.
Projects that provide financial support to the maintainers:
diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst
index 935e86020..3dbe6e47d 100644
--- a/docs/developing-locally-docker.rst
+++ b/docs/developing-locally-docker.rst
@@ -144,6 +144,19 @@ This tells our computer that all future commands are specifically for the dev1 m
$ eval "$(docker-machine env dev1)"
+Add 3rd party python packages
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To install a new 3rd party python package, you cannot use ``pip install ``, that would only add the package to the container. The container is ephemeral, so that new library won't be persisted if you run another container. Instead, you should modify the Docker image:
+You have to modify the relevant requirement file: base, local or production by adding: ::
+
+ ==
+
+To get this change picked up, you'll need to rebuild the image(s) and restart the running container: ::
+
+ docker-compose -f local.yml build
+ docker-compose -f local.yml up
+
Debugging
~~~~~~~~~
diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst
index b8655a84c..b79033aaa 100644
--- a/docs/developing-locally.rst
+++ b/docs/developing-locally.rst
@@ -174,7 +174,7 @@ Sass Compilation & Live Reloading
If you've opted for Gulp or Webpack as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
-#. Make sure that `Node.js`_ v16 is installed on your machine.
+#. Make sure that `Node.js`_ v18 is installed on your machine.
#. In the project root, install the JS dependencies with::
$ npm install
diff --git a/docs/requirements.txt b/docs/requirements.txt
index c16401c84..1ae530fa7 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -1,3 +1,3 @@
-sphinx==6.1.3
-sphinx-rtd-theme==1.2.0
+sphinx==6.2.1
+sphinx-rtd-theme==1.2.2
myst-parser==1.0.0
diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py
index 129f34ab7..351e7cfcb 100644
--- a/hooks/post_gen_project.py
+++ b/hooks/post_gen_project.py
@@ -107,10 +107,6 @@ def remove_heroku_files():
# don't remove the file if we are using travisci but not using heroku
continue
os.remove(file_name)
- remove_heroku_build_hooks()
-
-
-def remove_heroku_build_hooks():
shutil.rmtree("bin")
@@ -205,7 +201,9 @@ def handle_js_runner(choice, use_docker, use_async):
"gulp-uglify-es",
]
if not use_docker:
- dev_django_cmd = "uvicorn config.asgi:application --reload" if use_async else "python manage.py runserver"
+ dev_django_cmd = (
+ "uvicorn config.asgi:application --reload" if use_async else "python manage.py runserver_plus"
+ )
scripts.update(
{
"dev": "concurrently npm:dev:*",
@@ -454,8 +452,6 @@ def main():
if "{{ cookiecutter.use_heroku }}".lower() == "n":
remove_heroku_files()
- elif "{{ cookiecutter.frontend_pipeline }}" != "Django Compressor":
- remove_heroku_build_hooks()
if "{{ cookiecutter.use_docker }}".lower() == "n" and "{{ cookiecutter.use_heroku }}".lower() == "n":
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
diff --git a/requirements.txt b/requirements.txt
index 7ee3bbdea..f964e4ac7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
cookiecutter==2.1.1
-sh==2.0.3; sys_platform != "win32"
+sh==2.0.4; sys_platform != "win32"
binaryornot==0.4.4
# Code quality
@@ -7,19 +7,21 @@ binaryornot==0.4.4
black==23.3.0
isort==5.12.0
flake8==6.0.0
-pre-commit==3.2.2
+django-upgrade==1.13.0
+pre-commit==3.3.2
# Testing
# ------------------------------------------------------------------------------
-tox==4.4.12
+tox==4.6.0
pytest==7.3.1
+pytest-xdist==3.3.1
pytest-cookies==0.7.0
pytest-instafail==0.5.0
pyyaml==6.0
# Scripting
# ------------------------------------------------------------------------------
-PyGithub==1.58.1
+PyGithub==1.58.2
gitpython==3.1.31
jinja2==3.1.2
-requests==2.28.2
+requests==2.31.0
diff --git a/setup.py b/setup.py
index eb7d14ffd..f541bdee6 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@ except ImportError:
from distutils.core import setup
# We use calendar versioning
-version = "2023.04.13"
+version = "2023.06.08"
with open("README.rst") as readme_file:
long_description = readme_file.read()
diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py
index db63b39e4..8c8aa572b 100755
--- a/tests/test_cookiecutter_generation.py
+++ b/tests/test_cookiecutter_generation.py
@@ -1,3 +1,4 @@
+import glob
import os
import re
import sys
@@ -24,6 +25,7 @@ elif sys.platform.startswith("darwin") and os.getenv("CI"):
# automatically by running pre-commit after generation however they are tedious
# to fix in the template, so we don't insist too much in fixing them.
AUTOFIXABLE_STYLES = os.getenv("AUTOFIXABLE_STYLES") == "1"
+auto_fixable = pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="auto-fixable")
@pytest.fixture
@@ -186,7 +188,7 @@ def test_flake8_passes(cookies, context_override):
pytest.fail(e.stdout.decode())
-@pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="Black is auto-fixable")
+@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."""
@@ -205,7 +207,7 @@ def test_black_passes(cookies, context_override):
pytest.fail(e.stdout.decode())
-@pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="isort is auto-fixable")
+@auto_fixable
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
def test_isort_passes(cookies, context_override):
"""Check whether generated project passes isort style."""
@@ -217,6 +219,27 @@ def test_isort_passes(cookies, context_override):
pytest.fail(e.stdout.decode())
+@auto_fixable
+@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
+def test_django_upgrade_passes(cookies, context_override):
+ """Check whether generated project passes django-upgrade."""
+ result = cookies.bake(extra_context=context_override)
+
+ python_files = [
+ file_path.removeprefix(f"{result.project_path}/")
+ for file_path in glob.glob(str(result.project_path / "**" / "*.py"), recursive=True)
+ ]
+ try:
+ sh.django_upgrade(
+ "--target-version",
+ "4.1",
+ *python_files,
+ _cwd=str(result.project_path),
+ )
+ except sh.ErrorReturnCode as e:
+ pytest.fail(e.stdout.decode())
+
+
@pytest.mark.parametrize(
["use_docker", "expected_test_script"],
[
diff --git a/tox.ini b/tox.ini
index b10d16427..903d5a53b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -5,7 +5,7 @@ envlist = py311,black-template
[testenv]
deps = -rrequirements.txt
passenv = AUTOFIXABLE_STYLES
-commands = pytest {posargs:./tests}
+commands = pytest -n auto {posargs:./tests}
[testenv:black-template]
deps = black
diff --git a/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml b/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml
new file mode 100644
index 000000000..242f861a6
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/.idea/runConfigurations/runserver_plus.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
index 5d8670e4a..3a0411d81 100644
--- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
+++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
@@ -18,14 +18,20 @@ repos:
- id: detect-private-key
- repo: https://github.com/pre-commit/mirrors-prettier
- rev: v3.0.0-alpha.6
+ rev: v3.0.0-alpha.9-for-vscode
hooks:
- id: prettier
args: ['--tab-width', '2', '--single-quote']
- exclude: {{cookiecutter.project_slug}}/templates/
+ exclude: '{{cookiecutter.project_slug}}/templates/'
+
+ - repo: https://github.com/adamchainz/django-upgrade
+ rev: '1.13.0'
+ hooks:
+ - id: django-upgrade
+ args: ['--target-version', '4.1']
- repo: https://github.com/asottile/pyupgrade
- rev: v3.3.1
+ rev: v3.4.0
hooks:
- id: pyupgrade
args: [--py311-plus]
diff --git a/{{cookiecutter.project_slug}}/bin/post_compile b/{{cookiecutter.project_slug}}/bin/post_compile
index a9c94b39a..16719f493 100644
--- a/{{cookiecutter.project_slug}}/bin/post_compile
+++ b/{{cookiecutter.project_slug}}/bin/post_compile
@@ -1,4 +1,5 @@
#!/usr/bin/env bash
+{%- if cookiecutter.frontend_pipeline == "Django Compressor" %}
compress_enabled() {
python << END
@@ -19,4 +20,7 @@ if compress_enabled
then
python manage.py compress
fi
+{%- endif %}
+
python manage.py collectstatic --noinput
+python manage.py compilemessages -i site-packages
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile
index 2b9e9f7d9..3636ce1ef 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 specfic python version used in this file.
-FROM python:3.11.3-slim-bullseye as python
+# define an alias for the specific python version used in this file.
+FROM python:3.11.4-slim-bullseye as python
# Python build stage
FROM python as python-build-stage
diff --git a/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start b/{{cookiecutter.project_slug}}/compose/local/django/celery/beat/start
index 61f83968b..8adc4891a 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'
-exec watchfiles celery.__main__.main --args '-A config.celery_app beat -l INFO'
+exec watchfiles --filter python 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 ac3cc6b36..b4783d2f0 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/celery/flower/start
@@ -3,6 +3,6 @@
set -o errexit
set -o nounset
-exec watchfiles celery.__main__.main \
+exec watchfiles --filter python 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 16341fdd1..183a80159 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
-exec watchfiles celery.__main__.main --args '-A config.celery_app worker -l INFO'
+exec watchfiles --filter python 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 6415d7fb4..ec57dc8e4 100644
--- a/{{cookiecutter.project_slug}}/compose/local/django/start
+++ b/{{cookiecutter.project_slug}}/compose/local/django/start
@@ -9,5 +9,5 @@ python manage.py migrate
{%- if cookiecutter.use_async == 'y' %}
exec uvicorn config.asgi:application --host 0.0.0.0 --reload --reload-include '*.html'
{%- else %}
-exec python manage.py runserver 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 f8bcc35bd..f9895a083 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 specfic python version used in this file.
-FROM python:3.11.3-slim-bullseye as python
+# define an alias for the specific python version used in this file.
+FROM python:3.11.4-slim-bullseye as python
# Python build stage
diff --git a/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile
index 8062fa689..707ed0c9d 100644
--- a/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/local/node/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16-bullseye-slim
+FROM node:18-bullseye-slim
WORKDIR /app
diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
index 84c702db0..5a863ddc5 100644
--- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile
@@ -1,5 +1,5 @@
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%}
-FROM node:16-bullseye-slim as client-builder
+FROM node:18-bullseye-slim as client-builder
ARG APP_HOME=/app
WORKDIR ${APP_HOME}
@@ -24,8 +24,8 @@ ENV DJANGO_AZURE_ACCOUNT_NAME=${DJANGO_AZURE_ACCOUNT_NAME}
RUN npm run build
{%- endif %}
-# define an alias for the specfic python version used in this file.
-FROM python:3.11.3-slim-bullseye as python
+# define an alias for the specific python version used in this file.
+FROM python:3.11.4-slim-bullseye as python
# Python build stage
FROM python as python-build-stage
@@ -121,4 +121,8 @@ RUN chown django:django ${APP_HOME}
USER django
+RUN DATABASE_URL="" \
+ DJANGO_SETTINGS_MODULE="config.settings.test" \
+ python manage.py compilemessages
+
ENTRYPOINT ["/entrypoint"]
diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
index 7b053059d..581bbfebd 100644
--- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
+++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile
@@ -1,4 +1,4 @@
-FROM traefik:2.9.10
+FROM traefik:2.10.1
RUN mkdir -p /etc/traefik/acme \
&& touch /etc/traefik/acme/acme.json \
&& chmod 600 /etc/traefik/acme/acme.json
diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py
index c0ca31f36..487669e0a 100644
--- a/{{cookiecutter.project_slug}}/config/settings/base.py
+++ b/{{cookiecutter.project_slug}}/config/settings/base.py
@@ -26,6 +26,12 @@ DEBUG = env.bool("DJANGO_DEBUG", False)
TIME_ZONE = "{{ cookiecutter.timezone }}"
# https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = "en-us"
+# https://docs.djangoproject.com/en/dev/ref/settings/#languages
+# from django.utils.translation import gettext_lazy as _
+# LANGUAGES = [
+# ('en', _('English')),
+# ('pt-br', _('Português')),
+# ]
# https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1
# https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
diff --git a/{{cookiecutter.project_slug}}/locale/README.md b/{{cookiecutter.project_slug}}/locale/README.md
new file mode 100644
index 000000000..b2a8a0ef2
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/locale/README.md
@@ -0,0 +1,32 @@
+# Translations
+
+Start by configuring the `LANGUAGES` settings in `base.py`, by uncommenting languages you are willing to support. Then, translations strings will be placed in this folder when running:
+
+```bash
+{% if cookiecutter.use_docker == 'y' %}docker-compose -f local.yml run --rm django {% endif %}python manage.py makemessages -all --no-location
+```
+
+This should generate `django.po` (stands for Portable Object) files under each locale `/LC_MESSAGES/django.po`. Each translatable string in the codebase is collected with its `msgid` and need to be translated as `msgstr`, for example:
+
+```po
+msgid "users"
+msgstr "utilisateurs"
+```
+
+Once all translations are done, they need to be compiled into `.mo` files (stands for Machine Object), which are the actual binary files used by the application:
+
+```bash
+{% if cookiecutter.use_docker == 'y' %}docker-compose -f local.yml run --rm django {% endif %}python manage.py compilemessages
+```
+
+Note that the `.po` files are NOT used by the application directly, so if the `.mo` files are out of dates, the content won't appear as translated even if the `.po` files are up-to-date.
+
+## Production
+
+The production image runs `compilemessages` automatically at build time, so as long as your translated source files (PO) are up-to-date, you're good to go.
+
+## Add a new language
+
+1. Update the [`LANGUAGES` setting](https://docs.djangoproject.com/en/stable/ref/settings/#std-setting-LANGUAGES) to your project's base settings.
+2. Create the locale folder for the language next to this file, e.g. `fr_FR` for French. Make sure the case is correct.
+3. Run `makemessages` (as instructed above) to generate the PO files for the new language.
diff --git a/{{cookiecutter.project_slug}}/locale/README.rst b/{{cookiecutter.project_slug}}/locale/README.rst
deleted file mode 100644
index c2f1dcd6f..000000000
--- a/{{cookiecutter.project_slug}}/locale/README.rst
+++ /dev/null
@@ -1,6 +0,0 @@
-Translations
-============
-
-Translations will be placed in this folder when running::
-
- python manage.py makemessages
diff --git a/{{cookiecutter.project_slug}}/locale/en_US/LC_MESSAGES/django.po b/{{cookiecutter.project_slug}}/locale/en_US/LC_MESSAGES/django.po
new file mode 100644
index 000000000..6a4aa2e0b
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/locale/en_US/LC_MESSAGES/django.po
@@ -0,0 +1,12 @@
+# Translations for the {{ cookiecutter.project_name }} project
+# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }}
+# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: {{ cookiecutter.version }}\n"
+"Language: en-US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
diff --git a/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po b/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po
new file mode 100644
index 000000000..2556abba8
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po
@@ -0,0 +1,315 @@
+# Translations for the {{ cookiecutter.project_name }} project
+# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }}
+# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: {{ cookiecutter.version }}\n"
+"Language: pt-BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:5
+#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:8
+msgid "Account Inactive"
+msgstr "Conta Inativa"
+
+#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:10
+msgid "This account is inactive."
+msgstr "Esta conta está inativa."
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:7
+msgid "Account"
+msgstr "Conta"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:10
+msgid "E-mail Addresses"
+msgstr "Endereços de E-mail"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:13
+msgid "The following e-mail addresses are associated with your account:"
+msgstr "Os seguintes endereços de e-mail estão associados à sua conta:"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:27
+msgid "Verified"
+msgstr "Verificado"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:29
+msgid "Unverified"
+msgstr "Não verificado"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:31
+msgid "Primary"
+msgstr "Primário"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:37
+msgid "Make Primary"
+msgstr "Tornar Primário"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:38
+msgid "Re-send Verification"
+msgstr "Reenviar verificação"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:39
+msgid "Remove"
+msgstr "Remover"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:46
+msgid "Warning:"
+msgstr "Aviso:"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:46
+msgid ""
+"You currently do not have any e-mail address set up. You should really add "
+"an e-mail address so you can receive notifications, reset your password, etc."
+msgstr ""
+"No momento, você não tem nenhum endereço de e-mail configurado. Você "
+"realmente deve adicionar um endereço de e-mail para receber notificações, "
+"redefinir sua senha etc."
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:51
+msgid "Add E-mail Address"
+msgstr "Adicionar Endereço de E-mail"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:56
+msgid "Add E-mail"
+msgstr "Adicionar E-mail"
+
+#: {{cookiecutter.project_slug}}/templates/account/email.html:66
+msgid "Do you really want to remove the selected e-mail address?"
+msgstr "Você realmente deseja remover o endereço de e-mail selecionado?"
+
+#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:6
+#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:10
+msgid "Confirm E-mail Address"
+msgstr "Confirme o endereço de e-mail"
+
+#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:16
+#, python-format
+msgid ""
+"Please confirm that %(email)s is an e-mail "
+"address for user %(user_display)s."
+msgstr ""
+"Confirme se %(email)s é um endereço de "
+"e-mail do usuário %(user_display)s."
+
+#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:20
+msgid "Confirm"
+msgstr "Confirmar"
+
+#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:27
+#, python-format
+msgid ""
+"This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request."
+msgstr "Este link de confirmação de e-mail expirou ou é inválido. "
+"Por favor, emita um novo pedido de confirmação por e-mail."
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:7
+#: {{cookiecutter.project_slug}}/templates/account/login.html:11
+#: {{cookiecutter.project_slug}}/templates/account/login.html:56
+#: {{cookiecutter.project_slug}}/templates/base.html:72
+msgid "Sign In"
+msgstr "Entrar"
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:17
+msgid "Please sign in with one of your existing third party accounts:"
+msgstr "Faça login com uma de suas contas de terceiros existentes:"
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:19
+#, python-format
+msgid ""
+"Or, sign up for a %(site_name)s account and "
+"sign in below:"
+msgstr "Ou, cadastre-se para uma conta em %(site_name)s e entre abaixo:"
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:32
+msgid "or"
+msgstr "or"
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:41
+#, python-format
+msgid ""
+"If you have not created an account yet, then please sign up first."
+msgstr "Se você ainda não criou uma conta, registre-se primeiro."
+
+#: {{cookiecutter.project_slug}}/templates/account/login.html:55
+msgid "Forgot Password?"
+msgstr "Esqueceu sua senha?"
+
+#: {{cookiecutter.project_slug}}/templates/account/logout.html:5
+#: {{cookiecutter.project_slug}}/templates/account/logout.html:8
+#: {{cookiecutter.project_slug}}/templates/account/logout.html:17
+#: {{cookiecutter.project_slug}}/templates/base.html:61
+msgid "Sign Out"
+msgstr "Sair"
+
+#: {{cookiecutter.project_slug}}/templates/account/logout.html:10
+msgid "Are you sure you want to sign out?"
+msgstr "Você tem certeza que deseja sair?"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_change.html:6
+#: {{cookiecutter.project_slug}}/templates/account/password_change.html:9
+#: {{cookiecutter.project_slug}}/templates/account/password_change.html:14
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:5
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:4
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:7
+msgid "Change Password"
+msgstr "Alterar Senha"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:7
+#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:11
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:6
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:9
+msgid "Password Reset"
+msgstr "Redefinição de senha"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:16
+msgid ""
+"Forgotten your password? Enter your e-mail address below, and we'll send you "
+"an e-mail allowing you to reset it."
+msgstr "Esqueceu sua senha? Digite seu endereço de e-mail abaixo e enviaremos um e-mail permitindo que você o redefina."
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:21
+msgid "Reset My Password"
+msgstr "Redefinir minha senha"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:24
+msgid "Please contact us if you have any trouble resetting your password."
+msgstr "Entre em contato conosco se tiver algum problema para redefinir sua senha."
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:15
+msgid ""
+"We have sent you an e-mail. Please contact us if you do not receive it "
+"within a few minutes."
+msgstr "Enviamos um e-mail para você. Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8
+msgid "Bad Token"
+msgstr "Token Inválido"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:12
+#, python-format
+msgid ""
+"The password reset link was invalid, possibly because it has already been "
+"used. Please request a new password reset"
+"a>."
+msgstr "O link de redefinição de senha era inválido, possivelmente porque já foi usado. "
+"Solicite uma nova redefinição de senha."
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:18
+msgid "change password"
+msgstr "alterar senha"
+
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:21
+#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:8
+msgid "Your password is now changed."
+msgstr "Sua senha agora foi alterada."
+
+#: {{cookiecutter.project_slug}}/templates/account/password_set.html:6
+#: {{cookiecutter.project_slug}}/templates/account/password_set.html:9
+#: {{cookiecutter.project_slug}}/templates/account/password_set.html:14
+msgid "Set Password"
+msgstr "Definir Senha"
+
+#: {{cookiecutter.project_slug}}/templates/account/signup.html:6
+msgid "Signup"
+msgstr "Cadastro"
+
+#: {{cookiecutter.project_slug}}/templates/account/signup.html:9
+#: {{cookiecutter.project_slug}}/templates/account/signup.html:19
+#: {{cookiecutter.project_slug}}/templates/base.html:67
+msgid "Sign Up"
+msgstr "Cadastro"
+
+#: {{cookiecutter.project_slug}}/templates/account/signup.html:11
+#, python-format
+msgid ""
+"Already have an account? Then please sign in."
+msgstr "já tem uma conta? Então, por favor, faça login."
+
+#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:5
+#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:8
+msgid "Sign Up Closed"
+msgstr "Inscrições encerradas"
+
+#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:10
+msgid "We are sorry, but the sign up is currently closed."
+msgstr "Lamentamos, mas as inscrições estão encerradas no momento."
+
+#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:5
+#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:8
+#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:5
+#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:8
+msgid "Verify Your E-mail Address"
+msgstr "Verifique seu endereço de e-mail"
+
+#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:10
+msgid ""
+"We have sent an e-mail to you for verification. Follow the link provided to "
+"finalize the signup process. Please contact us if you do not receive it "
+"within a few minutes."
+msgstr "Enviamos um e-mail para você para verificação. Siga o link fornecido para finalizar o processo de inscrição. Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
+
+#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:12
+msgid ""
+"This part of the site requires us to verify that\n"
+"you are who you claim to be. For this purpose, we require that you\n"
+"verify ownership of your e-mail address. "
+msgstr "Esta parte do site exige que verifiquemos se você é quem afirma ser.\n"
+"Para esse fim, exigimos que você verifique a propriedade\n"
+"do seu endereço de e-mail."
+
+#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:16
+msgid ""
+"We have sent an e-mail to you for\n"
+"verification. Please click on the link inside this e-mail. Please\n"
+"contact us if you do not receive it within a few minutes."
+msgstr "Enviamos um e-mail para você para verificação.\n"
+"Por favor, clique no link dentro deste e-mail.\n"
+"Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
+
+#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:20
+#, python-format
+msgid ""
+"Note: you can still change your e-"
+"mail address."
+msgstr "Nota: você ainda pode alterar seu endereço de e-mail."
+
+#: {{cookiecutter.project_slug}}/templates/base.html:57
+msgid "My Profile"
+msgstr "Meu perfil"
+
+#: {{cookiecutter.project_slug}}/users/admin.py:17
+msgid "Personal info"
+msgstr "Informação pessoal"
+
+#: {{cookiecutter.project_slug}}/users/admin.py:19
+msgid "Permissions"
+msgstr "Permissões"
+
+#: {{cookiecutter.project_slug}}/users/admin.py:30
+msgid "Important dates"
+msgstr "Datas importantes"
+
+#: {{cookiecutter.project_slug}}/users/apps.py:7
+msgid "Users"
+msgstr "Usuários"
+
+#: {{cookiecutter.project_slug}}/users/forms.py:24
+#: {{cookiecutter.project_slug}}/users/tests/test_forms.py:36
+msgid "This username has already been taken."
+msgstr "Este nome de usuário já foi usado."
+
+#: {{cookiecutter.project_slug}}/users/models.py:15
+msgid "Name of User"
+msgstr "Nome do Usuário"
+
+#: {{cookiecutter.project_slug}}/users/views.py:23
+msgid "Information successfully updated"
+msgstr "Informação atualizada com sucesso"
diff --git a/{{cookiecutter.project_slug}}/package.json b/{{cookiecutter.project_slug}}/package.json
index 90ac63763..fdfd26bf3 100644
--- a/{{cookiecutter.project_slug}}/package.json
+++ b/{{cookiecutter.project_slug}}/package.json
@@ -7,12 +7,12 @@
"@popperjs/core": "^2.10.2",
"autoprefixer": "^10.4.0",
"babel-loader": "^9.1.2",
- "bootstrap": "^5.1.3",
+ "bootstrap": "^5.2.3",
"browser-sync": "^2.27.7",
"css-loader": "^6.5.1",
"gulp-concat": "^2.6.1",
- "concurrently": "^7.0.0",
- "cssnano": "^5.0.11",
+ "concurrently": "^8.0.1",
+ "cssnano": "^6.0.0",
"gulp": "^4.0.2",
"gulp-imagemin": "^7.1.0",
"gulp-plumber": "^1.2.1",
@@ -29,13 +29,13 @@
"sass": "^1.43.4",
"sass-loader": "^13.2.0",
"webpack": "^5.65.0",
- "webpack-bundle-tracker": "^1.4.0",
+ "webpack-bundle-tracker": "^2.0.0",
"webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.6.0",
"webpack-merge": "^5.8.0"
},
"engines": {
- "node": "16"
+ "node": "18"
},
"browserslist": [
"last 2 versions"
diff --git a/{{cookiecutter.project_slug}}/production.yml b/{{cookiecutter.project_slug}}/production.yml
index 4d56fbfa8..30d72d61e 100644
--- a/{{cookiecutter.project_slug}}/production.yml
+++ b/{{cookiecutter.project_slug}}/production.yml
@@ -97,6 +97,7 @@ services:
- production_postgres_data_backups:/backups:z
{%- endif %}
{%- if cookiecutter.cloud_provider == 'None' %}
+
nginx:
build:
context: .
diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt
index 0fdee1f86..9b2159edf 100644
--- a/{{cookiecutter.project_slug}}/requirements/base.txt
+++ b/{{cookiecutter.project_slug}}/requirements/base.txt
@@ -1,4 +1,3 @@
-pytz==2023.3 # https://github.com/stub42/pytz
python-slugify==8.0.1 # https://github.com/un33k/python-slugify
Pillow==9.5.0 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
@@ -12,24 +11,24 @@ argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %}
whitenoise==6.4.0 # https://github.com/evansd/whitenoise
{%- endif %}
-redis==4.5.4 # https://github.com/redis/redis-py
+redis==4.5.5 # https://github.com/redis/redis-py
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
-hiredis==2.2.2 # https://github.com/redis/hiredis-py
+hiredis==2.2.3 # https://github.com/redis/hiredis-py
{%- endif %}
{%- if cookiecutter.use_celery == "y" %}
-celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery
+celery==5.3.0 # pyup: < 6.0 # https://github.com/celery/celery
django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %}
flower==1.2.0 # https://github.com/mher/flower
{%- endif %}
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
-uvicorn[standard]==0.21.1 # https://github.com/encode/uvicorn
+uvicorn[standard]==0.22.0 # https://github.com/encode/uvicorn
{%- endif %}
# Django
# ------------------------------------------------------------------------------
-django==4.1.8 # pyup: < 4.2 # https://www.djangoproject.com/
+django==4.1.9 # pyup: < 4.2 # https://www.djangoproject.com/
django-environ==0.10.0 # https://github.com/joke2k/django-environ
django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils
django-allauth==0.54.0 # https://github.com/pennersr/django-allauth
@@ -42,10 +41,10 @@ django-redis==5.2.0 # https://github.com/jazzband/django-redis
{%- if cookiecutter.use_drf == 'y' %}
# Django REST Framework
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
-django-cors-headers==3.14.0 # https://github.com/adamchainz/django-cors-headers
+django-cors-headers==4.0.0 # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation
-drf-spectacular==0.26.1 # https://github.com/tfranzel/drf-spectacular
+drf-spectacular==0.26.2 # https://github.com/tfranzel/drf-spectacular
{%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
-django-webpack-loader==1.8.1 # https://github.com/django-webpack/django-webpack-loader
+django-webpack-loader==2.0.0 # https://github.com/django-webpack/django-webpack-loader
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index a867b0673..3e8b13133 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -1,6 +1,6 @@
-r base.txt
-Werkzeug[watchdog]==2.2.3 # https://github.com/pallets/werkzeug
+Werkzeug[watchdog]==2.3.5 # https://github.com/pallets/werkzeug
ipdb==0.13.13 # https://github.com/gotcha/ipdb
{%- if cookiecutter.use_docker == 'y' %}
psycopg2==2.9.6 # https://github.com/psycopg/psycopg2
@@ -13,36 +13,36 @@ watchfiles==0.19.0 # https://github.com/samuelcolvin/watchfiles
# Testing
# ------------------------------------------------------------------------------
-mypy==1.1.1 # https://github.com/python/mypy
-django-stubs==1.16.0 # https://github.com/typeddjango/django-stubs
+mypy==1.3.0 # https://github.com/python/mypy
+django-stubs==4.2.1 # https://github.com/typeddjango/django-stubs
pytest==7.3.1 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.7 # https://github.com/Frozenball/pytest-sugar
{%- if cookiecutter.use_drf == "y" %}
-djangorestframework-stubs==1.10.0 # https://github.com/typeddjango/djangorestframework-stubs
+djangorestframework-stubs==3.14.1 # https://github.com/typeddjango/djangorestframework-stubs
{%- endif %}
# Documentation
# ------------------------------------------------------------------------------
-sphinx==6.1.3 # https://github.com/sphinx-doc/sphinx
+sphinx==6.2.1 # https://github.com/sphinx-doc/sphinx
sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild
# Code quality
# ------------------------------------------------------------------------------
flake8==6.0.0 # https://github.com/PyCQA/flake8
flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort
-coverage==7.2.2 # https://github.com/nedbat/coveragepy
+coverage==7.2.7 # https://github.com/nedbat/coveragepy
black==23.3.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==3.2.2 # https://github.com/pre-commit/pre-commit
+pre-commit==3.3.2 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy
-django-debug-toolbar==4.0.0 # https://github.com/jazzband/django-debug-toolbar
-django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions
+django-debug-toolbar==4.1.0 # https://github.com/jazzband/django-debug-toolbar
+django-extensions==3.2.3 # 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 42cdbf53f..aec79b3d3 100644
--- a/{{cookiecutter.project_slug}}/requirements/production.txt
+++ b/{{cookiecutter.project_slug}}/requirements/production.txt
@@ -8,10 +8,10 @@ psycopg2==2.9.6 # https://github.com/psycopg/psycopg2
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
-sentry-sdk==1.19.0 # https://github.com/getsentry/sentry-python
+sentry-sdk==1.25.1 # https://github.com/getsentry/sentry-python
{%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
-hiredis==2.2.2 # https://github.com/redis/hiredis-py
+hiredis==2.2.3 # https://github.com/redis/hiredis-py
{%- endif %}
# Django
@@ -24,21 +24,21 @@ django-storages[google]==1.13.2 # https://github.com/jschneier/django-storages
django-storages[azure]==1.13.2 # https://github.com/jschneier/django-storages
{%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %}
-django-anymail[mailgun]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[mailgun]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Amazon SES' %}
-django-anymail[amazon_ses]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[amazon-ses]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mailjet' %}
-django-anymail[mailjet]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[mailjet]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mandrill' %}
-django-anymail[mandrill]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[mandrill]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Postmark' %}
-django-anymail[postmark]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[postmark]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Sendgrid' %}
-django-anymail[sendgrid]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[sendgrid]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SendinBlue' %}
-django-anymail[sendinblue]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[sendinblue]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SparkPost' %}
-django-anymail[sparkpost]==9.1 # https://github.com/anymail/django-anymail
+django-anymail[sparkpost]==10.0 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
-django-anymail==9.1 # https://github.com/anymail/django-anymail
+django-anymail==10.0 # https://github.com/anymail/django-anymail
{%- endif %}
diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt
index afe12ad1b..431fc7e8c 100644
--- a/{{cookiecutter.project_slug}}/runtime.txt
+++ b/{{cookiecutter.project_slug}}/runtime.txt
@@ -1 +1 @@
-python-3.11.3
+python-3.11.4
diff --git a/{{cookiecutter.project_slug}}/webpack/common.config.js b/{{cookiecutter.project_slug}}/webpack/common.config.js
index 6aba2bc77..d95434dbd 100644
--- a/{{cookiecutter.project_slug}}/webpack/common.config.js
+++ b/{{cookiecutter.project_slug}}/webpack/common.config.js
@@ -20,7 +20,8 @@ module.exports = {
},
plugins: [
new BundleTracker({
- filename: path.resolve(__dirname, '../webpack-stats.json'),
+ path: path.resolve(path.join(__dirname, '../')),
+ filename: 'webpack-stats.json',
}),
new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash].css' }),
],
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
index ad51a6e18..44f0d5c52 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/templates/base.html
@@ -20,7 +20,7 @@
{%- if cookiecutter.frontend_pipeline in ['None', 'Django Compressor'] %}
{%- raw %}
-
+
{%- endraw %}
{%- endif %}
{%- raw %}
@@ -51,7 +51,7 @@
{% render_bundle 'vendors' 'js' attrs='defer' %}
{%- endraw %}{% else %}{% raw %}
-
+
{%- endraw %}{% endif %}{% raw %}
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 0cd0021ff..2c1027038 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
@@ -7,6 +7,7 @@ from django.contrib.sessions.middleware import SessionMiddleware
from django.http import HttpRequest, HttpResponseRedirect
from django.test import RequestFactory
from django.urls import reverse
+from django.utils.translation import gettext_lazy as _
from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm
from {{ cookiecutter.project_slug }}.users.models import User
@@ -72,7 +73,7 @@ class TestUserUpdateView:
view.form_valid(form)
messages_sent = [m.message for m in messages.get_messages(request)]
- assert messages_sent == ["Information successfully updated"]
+ assert messages_sent == [_("Information successfully updated")]
class TestUserRedirectView:
|