diff --git a/.flake8 b/.flake8 index 84b4b4411..3a87b269b 100644 --- a/.flake8 +++ b/.flake8 @@ -1,3 +1,4 @@ [flake8] exclude = docs max-line-length = 119 +extend-ignore = E203 diff --git a/.github/contributors.json b/.github/contributors.json index 4419e2620..bccbb725f 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1423,5 +1423,50 @@ "name": "Imran Rahman", "github_login": "infraredCoding", "twitter_username": "" + }, + { + "name": "hleroy", + "github_login": "hleroy", + "twitter_username": "" + }, + { + "name": "Shayan Karimi", + "github_login": "shywn-mrk", + "twitter_username": "shywn_mrk" + }, + { + "name": "Sadra Yahyapour", + "github_login": "lnxpy", + "twitter_username": "lnxpylnxpy" + }, + { + "name": "Tharushan", + "github_login": "Tharushan", + "twitter_username": "" + }, + { + "name": "Fateme Fouladkar", + "github_login": "FatemeFouladkar", + "twitter_username": "" + }, + { + "name": "zhaoruibing", + "github_login": "zhaoruibing", + "twitter_username": "" + }, + { + "name": "MinWoo Sung", + "github_login": "SungMinWoo", + "twitter_username": "" + }, + { + "name": "itisnotyourenv", + "github_login": "itisnotyourenv", + "twitter_username": "" + }, + { + "name": "Vageeshan Mankala", + "github_login": "vagi8", + "twitter_username": "" } ] \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dbda77b5e..17510ae25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: name: "pytest ${{ matrix.os }}" runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" @@ -53,7 +53,7 @@ jobs: COMPOSE_DOCKER_CLI_BUILD: 1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" @@ -75,7 +75,7 @@ jobs: - name: Webpack args: "frontend_pipeline=Webpack use_heroku=y" - name: Email Username - args: "username_type=email ci_tool=Github" + args: "username_type=email ci_tool=Github project_name='Something superduper long - the great amazing project' project_slug=my_awesome_project" name: "Bare metal ${{ matrix.script.name }}" runs-on: ubuntu-latest @@ -97,7 +97,7 @@ jobs: DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" diff --git a/.github/workflows/django-issue-checker.yml b/.github/workflows/django-issue-checker.yml index cbfea922d..a926f7513 100644 --- a/.github/workflows/django-issue-checker.yml +++ b/.github/workflows/django-issue-checker.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" diff --git a/.github/workflows/pre-commit-autoupdate.yml b/.github/workflows/pre-commit-autoupdate.yml index 75bfe0a20..67fe9f94a 100644 --- a/.github/workflows/pre-commit-autoupdate.yml +++ b/.github/workflows/pre-commit-autoupdate.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: "3.11" diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index f48f297aa..eb037b675 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml index 78d72c241..9b93ef6f1 100644 --- a/.github/workflows/update-contributors.yml +++ b/.github/workflows/update-contributors.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 26f80b163..0327a46f2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,20 +17,20 @@ repos: - id: detect-private-key - repo: https://github.com/pre-commit/mirrors-prettier - rev: "v3.0.0" + rev: "v3.0.3" hooks: - id: prettier args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade - rev: v3.9.0 + rev: v3.11.1 hooks: - id: pyupgrade args: [--py311-plus] exclude: hooks/ - repo: https://github.com/psf/black - rev: 23.7.0 + rev: 23.9.1 hooks: - id: black @@ -40,7 +40,7 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 645064266..6dd30cb85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,295 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 2023.09.21 + + +### Updated + +- Auto-update pre-commit hooks ([#4589](https://github.com/cookiecutter/cookiecutter-django/pull/4589)) + +- Update djlint to 1.34.0 ([#4590](https://github.com/cookiecutter/cookiecutter-django/pull/4590)) + +## 2023.09.19 + + +### Updated + +- Auto-update pre-commit hooks ([#4588](https://github.com/cookiecutter/cookiecutter-django/pull/4588)) + +- Update djlint to 1.33.0 ([#4587](https://github.com/cookiecutter/cookiecutter-django/pull/4587)) + +## 2023.09.16 + + +### Updated + +- Auto-update pre-commit hooks ([#4586](https://github.com/cookiecutter/cookiecutter-django/pull/4586)) + +## 2023.09.15 + + +### Updated + +- Update flake8-isort to 6.1.0 ([#4585](https://github.com/cookiecutter/cookiecutter-django/pull/4585)) + +- Update pillow to 10.0.1 ([#4584](https://github.com/cookiecutter/cookiecutter-django/pull/4584)) + +## 2023.09.14 + + +### Updated + +- Update sphinx to 7.2.6 ([#4583](https://github.com/cookiecutter/cookiecutter-django/pull/4583)) + +## 2023.09.13 + + +### Updated + +- Update sentry-sdk to 1.31.0 ([#4582](https://github.com/cookiecutter/cookiecutter-django/pull/4582)) + +## 2023.09.12 + + +### Updated + +- Update django-storages to 1.14 ([#4564](https://github.com/cookiecutter/cookiecutter-django/pull/4564)) + +## 2023.09.11 + + +### Updated + +- Auto-update pre-commit hooks ([#4579](https://github.com/cookiecutter/cookiecutter-django/pull/4579)) + +- Update black to 23.9.1 ([#4580](https://github.com/cookiecutter/cookiecutter-django/pull/4580)) + +- Update django-allauth to 0.56.1 ([#4576](https://github.com/cookiecutter/cookiecutter-django/pull/4576)) + +## 2023.09.08 + + +### Updated + +- Update pytest to 7.4.2 ([#4573](https://github.com/cookiecutter/cookiecutter-django/pull/4573)) + +## 2023.09.07 + + +### Updated + +- Update django-allauth to 0.56.0 ([#4571](https://github.com/cookiecutter/cookiecutter-django/pull/4571)) + +## 2023.09.06 + + +### Changed + +- Replace Mailhog with Mailpit ([#4551](https://github.com/cookiecutter/cookiecutter-django/pull/4551)) + +### Updated + +- Update sphinx to 7.2.5 ([#4569](https://github.com/cookiecutter/cookiecutter-django/pull/4569)) + +- Bump actions/checkout from 3 to 4 ([#4565](https://github.com/cookiecutter/cookiecutter-django/pull/4565)) + +- Update coverage to 7.3.1 ([#4567](https://github.com/cookiecutter/cookiecutter-django/pull/4567)) + +## 2023.09.04 + + +### Updated + +- Update django to 4.2.5 ([#4563](https://github.com/cookiecutter/cookiecutter-django/pull/4563)) + +## 2023.09.03 + + +### Updated + +- Update celery to 5.3.4 ([#4562](https://github.com/cookiecutter/cookiecutter-django/pull/4562)) + +## 2023.09.02 + + +### Updated + +- Update pytest to 7.4.1 ([#4561](https://github.com/cookiecutter/cookiecutter-django/pull/4561)) + +- Update pre-commit to 3.4.0 ([#4560](https://github.com/cookiecutter/cookiecutter-django/pull/4560)) + +- Update django-environ to 0.11.2 ([#4558](https://github.com/cookiecutter/cookiecutter-django/pull/4558)) + +## 2023.09.01 + + +## 2023.08.31 + + +### Updated + +- Auto-update pre-commit hooks ([#4550](https://github.com/cookiecutter/cookiecutter-django/pull/4550)) + +- Update django-allauth to 0.55.2 ([#4549](https://github.com/cookiecutter/cookiecutter-django/pull/4549)) + +- Update celery to 5.3.3 ([#4553](https://github.com/cookiecutter/cookiecutter-django/pull/4553)) + +## 2023.08.30 + + +### Updated + +- Update django-environ to 0.11.0 ([#4548](https://github.com/cookiecutter/cookiecutter-django/pull/4548)) + +## 2023.08.29 + + +### Updated + +- Update sentry-sdk to 1.30.0 ([#4546](https://github.com/cookiecutter/cookiecutter-django/pull/4546)) + +## 2023.08.28 + + +### Changed + +- Add French translations ([#4454](https://github.com/cookiecutter/cookiecutter-django/pull/4454)) + +- Change `MEDIA_URL` to an absolute URL in tests ([#4460](https://github.com/cookiecutter/cookiecutter-django/pull/4460)) + +### Fixed + +- Fix a small compatibility issue between black and flake8 ([#4541](https://github.com/cookiecutter/cookiecutter-django/pull/4541)) + +### Updated + +- Update django-allauth to 0.55.0 ([#4535](https://github.com/cookiecutter/cookiecutter-django/pull/4535)) + +- Update watchfiles to 0.20.0 ([#4537](https://github.com/cookiecutter/cookiecutter-django/pull/4537)) + +- Update Python version from 3.11.4 to 3.11.5 ([#4542](https://github.com/cookiecutter/cookiecutter-django/pull/4542)) + +## 2023.08.19 + + +### Changed + +- Override `_after_postgeneration` to force save in `UserFactory` ([#4534](https://github.com/cookiecutter/cookiecutter-django/pull/4534)) + +## 2023.08.17 + + +### Updated + +- Update argon2-cffi to 23.1.0 ([#4527](https://github.com/cookiecutter/cookiecutter-django/pull/4527)) + +- Auto-update pre-commit hooks ([#4530](https://github.com/cookiecutter/cookiecutter-django/pull/4530)) + +## 2023.08.16 + + +### Updated + +- Update django-upgrade to 1.14.1 ([#4528](https://github.com/cookiecutter/cookiecutter-django/pull/4528)) + +## 2023.08.15 + + +### Updated + +- Update redis to 5.0.0 ([#4526](https://github.com/cookiecutter/cookiecutter-django/pull/4526)) + +## 2023.08.14 + + +### Changed + +- Install Django and DRF stubs with `compatible-mypy` extra (as per offical recommendation) ([#4361](https://github.com/cookiecutter/cookiecutter-django/pull/4361)) + +- Fix `overrideCommand` value in `devcontainer` so that the `django` container can run (#4517) ([#4517](https://github.com/cookiecutter/cookiecutter-django/pull/4517)) + +### Fixed + +- Prevent error in data migration caused by long project name ([#4525](https://github.com/cookiecutter/cookiecutter-django/pull/4525)) + +- Remove unused gulp-concat when Webpack is selected ([#4520](https://github.com/cookiecutter/cookiecutter-django/pull/4520)) + +- Exclude env files from container image (add .envs/ to .dockerignore) ([#4476](https://github.com/cookiecutter/cookiecutter-django/pull/4476)) + +### Updated + +- Update werkzeug to 2.3.7 ([#4521](https://github.com/cookiecutter/cookiecutter-django/pull/4521)) + +- Update coverage to 7.3.0 ([#4516](https://github.com/cookiecutter/cookiecutter-django/pull/4516)) + +- Update django-debug-toolbar to 4.2.0 ([#4511](https://github.com/cookiecutter/cookiecutter-django/pull/4511)) + +- Update flower to 2.0.1 ([#4518](https://github.com/cookiecutter/cookiecutter-django/pull/4518)) + +## 2023.08.10 + + +### Fixed + +- Corrected 'or' translation to pt-br ([#4507](https://github.com/cookiecutter/cookiecutter-django/pull/4507)) + +## 2023.08.04 + + +### Updated + +- Auto-update pre-commit hooks ([#4503](https://github.com/cookiecutter/cookiecutter-django/pull/4503)) + +## 2023.08.01 + + +### Updated + +- Auto-update pre-commit hooks ([#4499](https://github.com/cookiecutter/cookiecutter-django/pull/4499)) + +- Update django-anymail to 10.1 ([#4497](https://github.com/cookiecutter/cookiecutter-django/pull/4497)) + +- Update sentry-sdk to 1.29.2 ([#4496](https://github.com/cookiecutter/cookiecutter-django/pull/4496)) + +- Update django to 4.2.4 ([#4495](https://github.com/cookiecutter/cookiecutter-django/pull/4495)) + +- Update flake8 to 6.1.0 ([#4489](https://github.com/cookiecutter/cookiecutter-django/pull/4489)) + +- Update uvicorn to 0.23.2 ([#4490](https://github.com/cookiecutter/cookiecutter-django/pull/4490)) + +- Update sentry-sdk to 1.29.1 ([#4494](https://github.com/cookiecutter/cookiecutter-django/pull/4494)) + +## 2023.07.30 + + +### Fixed + +- Fix `README.md` file extension in `setup.py` ([#4488](https://github.com/cookiecutter/cookiecutter-django/pull/4488)) + +## 2023.07.28 + + +### Changed + +- Add support for Drone CI ([#4382](https://github.com/cookiecutter/cookiecutter-django/pull/4382)) + +## 2023.07.27 + + +### Documentation + +- Document that `docker exec` does not work for running management commands ([#4487](https://github.com/cookiecutter/cookiecutter-django/pull/4487)) + +- Add Webpack instructions for developping locally with HTTPS ([#4486](https://github.com/cookiecutter/cookiecutter-django/pull/4486)) + +## 2023.07.25 + + +### Updated + +- Upgrade to traefik 2.10.4 ([#4483](https://github.com/cookiecutter/cookiecutter-django/pull/4483)) + ## 2023.07.24 diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 4941f07f7..f7615c108 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -796,6 +796,13 @@ Listed in alphabetical order. fabaff + + Fateme Fouladkar + + FatemeFouladkar + + + Felipe Arruda @@ -936,6 +943,13 @@ Listed in alphabetical order. + + hleroy + + hleroy + + + Hoai-Thu Vuong @@ -985,6 +999,13 @@ Listed in alphabetical order. + + itisnotyourenv + + itisnotyourenv + + + Ivan Khomutov @@ -1454,6 +1475,13 @@ Listed in alphabetical order. + + MinWoo Sung + + SungMinWoo + + + monosans @@ -1692,6 +1720,13 @@ Listed in alphabetical order. + + Sadra Yahyapour + + lnxpy + + lnxpylnxpy + Sam Collins @@ -1713,6 +1748,13 @@ Listed in alphabetical order. sebastianreyese + + Shayan Karimi + + shywn-mrk + + shywn_mrk + Simon Rey @@ -1797,6 +1839,13 @@ Listed in alphabetical order. + + Tharushan + + Tharushan + + + Thibault J. @@ -1895,6 +1944,13 @@ Listed in alphabetical order. egregors + + Vageeshan Mankala + + vagi8 + + + vascop @@ -2007,6 +2063,13 @@ Listed in alphabetical order. + + zhaoruibing + + zhaoruibing + + + ### Special Thanks diff --git a/README.md b/README.md index a04535055..bac442703 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ production-ready Django projects quickly. - Works with Python 3.11 - 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) +- [12-Factor](https://12factor.net) based settings via [django-environ](https://github.com/joke2k/django-environ) - Secure by default. We believe in SSL. - Optimized development and production settings - Registration via [django-allauth](https://github.com/pennersr/django-allauth) @@ -45,7 +45,7 @@ _These features can be enabled during initial project setup._ - Serve static files from Amazon S3, Google Cloud Storage, Azure Storage or [Whitenoise](https://whitenoise.readthedocs.io/) - Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only) -- Integration with [MailHog](https://github.com/mailhog/MailHog) for local email testing +- Integration with [Mailpit](https://github.com/axllent/mailpit/) for local email testing - Integration with [Sentry](https://sentry.io/welcome/) for error logging ## Constraints @@ -165,7 +165,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re 4 - Webpack Choose from 1, 2, 3, 4 [1]: 1 use_celery [n]: y - use_mailhog [n]: n + use_mailpit [n]: n use_sentry [n]: y use_whitenoise [n]: n use_heroku [n]: y @@ -247,6 +247,7 @@ experience better. ## Articles +- [How to Make Your Own Django Cookiecutter Template!](https://medium.com/@FatemeFouladkar/how-to-make-your-own-django-cookiecutter-template-a753d4cbb8c2) - Aug. 10, 2023 - [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021 - [Complete Walkthrough: Blue/Green Deployment to AWS ECS using GitHub actions](https://github.com/Andrew-Chen-Wang/cookiecutter-django-ecs-github) - June 10, 2020 - [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 diff --git a/cookiecutter.json b/cookiecutter.json index 3fcab4a78..e343617d1 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -35,11 +35,11 @@ "use_drf": "n", "frontend_pipeline": ["None", "Django Compressor", "Gulp", "Webpack"], "use_celery": "n", - "use_mailhog": "n", + "use_mailpit": "n", "use_sentry": "n", "use_whitenoise": "n", "use_heroku": "n", - "ci_tool": ["None", "Travis", "Gitlab", "Github"], + "ci_tool": ["None", "Travis", "Gitlab", "Github", "Drone"], "keep_local_envs_in_vcs": "y", "debug": "n" } diff --git a/docs/developing-locally-docker.rst b/docs/developing-locally-docker.rst index 91a42d705..3a0291571 100644 --- a/docs/developing-locally-docker.rst +++ b/docs/developing-locally-docker.rst @@ -77,7 +77,7 @@ As with any shell command that we wish to run in our container, this is done usi $ docker compose -f local.yml run --rm django python manage.py createsuperuser Here, ``django`` is the target service we are executing the commands against. - +Also, please note that the ``docker exec`` does not work for running management commands. (Optionally) Designate your Docker Development Server IP -------------------------------------------------------- @@ -191,16 +191,16 @@ The ``container_name`` from the yml file can be used to check on containers with Notice that the ``container_name`` is generated dynamically using your project slug as a prefix -Mailhog +Mailpit ~~~~~~~ -When developing locally you can go with MailHog_ for email testing provided ``use_mailhog`` was set to ``y`` on setup. To proceed, +When developing locally you can go with Mailpit_ for email testing provided ``use_mailpit`` was set to ``y`` on setup. To proceed, -#. make sure ``_local_mailhog`` container is up and running; +#. make sure ``_local_mailpit`` container is up and running; #. open up ``http://127.0.0.1:8025``. -.. _Mailhog: https://github.com/mailhog/MailHog/ +.. _Mailpit: https://github.com/axllent/mailpit/ .. _`CeleryTasks`: @@ -330,3 +330,26 @@ See `https with nginx`_ for more information on this configuration. Add ``certs/*`` to the ``.gitignore`` file. This allows the folder to be included in the repo but its contents to be ignored. *This configuration is for local development environments only. Do not use this for production since you might expose your local* ``rootCA-key.pem``. + +Webpack +~~~~~~~ + +If you are using Webpack: + +1. On the ``nginx-proxy`` service in ``local.yml``, change ``depends_on`` to ``node`` instead of ``django``. + +2. On the ``node`` service in ``local.yml``, add the following environment configuration: + + :: + + environment: + - VIRTUAL_HOST=my-dev-env.local + - VIRTUAL_PORT=3000 + +3. Add the following configuration to the ``devServer`` section of ``webpack/dev.config.js``: + + :: + + client: { + webSocketURL: 'auto://0.0.0.0:0/ws', // note the `:0` after `0.0.0.0` + }, diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst index 88c8b3206..92379f4fd 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -99,39 +99,37 @@ First things first. Setup Email Backend ------------------- -MailHog +Mailpit ~~~~~~~ -.. note:: In order for the project to support MailHog_ it must have been bootstrapped with ``use_mailhog`` set to ``y``. +.. note:: In order for the project to support Mailpit_ it must have been bootstrapped with ``use_mailpit`` set to ``y``. -MailHog is used to receive emails during development, it is written in Go and has no external dependencies. +Mailpit is used to receive emails during development, it is written in Go and has no external dependencies. For instance, one of the packages we depend upon, ``django-allauth`` sends verification emails to new users signing up as well as to the existing ones who have not yet verified themselves. -#. `Download the latest MailHog release`_ for your OS. +#. `Download the latest Mailpit release`_ for your OS. -#. Rename the build to ``MailHog``. - -#. Copy the file to the project root. +#. Copy the binary file to the project root. #. Make it executable: :: - $ chmod +x MailHog + $ chmod +x mailpit #. Spin up another terminal window and start it there: :: - ./MailHog + ./mailpit #. Check out ``_ to see how it goes. Now you have your own mail server running locally, ready to receive whatever you send it. -.. _`Download the latest MailHog release`: https://github.com/mailhog/MailHog +.. _`Download the latest Mailpit release`: https://github.com/axllent/mailpit Console ~~~~~~~ -.. note:: If you have generated your project with ``use_mailhog`` set to ``n`` this will be a default setup. +.. note:: If you have generated your project with ``use_mailpit`` set to ``n`` this will be a default setup. Alternatively, deliver emails over console via ``EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'``. diff --git a/docs/project-generation-options.rst b/docs/project-generation-options.rst index edf2306d4..967b42426 100644 --- a/docs/project-generation-options.rst +++ b/docs/project-generation-options.rst @@ -115,8 +115,8 @@ Both Gulp and Webpack support Bootstrap recompilation with real-time variables a use_celery: Indicates whether the project should be configured to use Celery_. -use_mailhog: - Indicates whether the project should be configured to use MailHog_. +use_mailpit: + Indicates whether the project should be configured to use Mailpit_. use_sentry: Indicates whether the project should be configured to use Sentry_. @@ -135,6 +135,7 @@ ci_tool: 2. `Travis CI`_ 3. `Gitlab CI`_ 4. `Github Actions`_ + 5. `Drone CI`_ keep_local_envs_in_vcs: Indicates whether the project's ``.envs/.local/`` should be kept in VCS @@ -184,7 +185,7 @@ debug: .. _Celery: https://github.com/celery/celery -.. _MailHog: https://github.com/mailhog/MailHog +.. _Mailpit: https://github.com/axllent/mailpit .. _Sentry: https://github.com/getsentry/sentry @@ -196,4 +197,6 @@ debug: .. _GitLab CI: https://docs.gitlab.com/ee/ci/ +.. _Drone CI: https://docs.drone.io/pipeline/overview/ + .. _Github Actions: https://docs.github.com/en/actions diff --git a/docs/requirements.txt b/docs/requirements.txt index d06b651b3..38a8385fd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx==6.2.1 -sphinx-rtd-theme==1.2.2 +sphinx==7.2.6 +sphinx-rtd-theme==1.3.0 myst-parser==2.0.0 diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index a913f7592..37f96efc0 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -183,6 +183,7 @@ def handle_js_runner(choice, use_docker, use_async): "browser-sync", "cssnano", "gulp", + "gulp-concat", "gulp-imagemin", "gulp-plumber", "gulp-postcss", @@ -207,6 +208,24 @@ def handle_js_runner(choice, use_docker, use_async): remove_gulp_files() +def remove_prettier_pre_commit(): + with open(".pre-commit-config.yaml", "r") as fd: + content = fd.readlines() + + removing = False + new_lines = [] + for line in content: + if removing and "- repo:" in line: + removing = False + if "mirrors-prettier" in line: + removing = True + if not removing: + new_lines.append(line) + + with open(".pre-commit-config.yaml", "w") as fd: + fd.writelines(new_lines) + + def remove_celery_files(): file_names = [ os.path.join("config", "celery_app.py"), @@ -238,6 +257,10 @@ def remove_dotgithub_folder(): shutil.rmtree(".github") +def remove_dotdrone_file(): + os.remove(".drone.yml") + + def generate_random_string(length, using_digits=False, using_ascii_letters=False, using_punctuation=False): """ Example: @@ -461,6 +484,7 @@ def main(): remove_webpack_files() remove_sass_files() remove_packagejson_file() + remove_prettier_pre_commit() if "{{ cookiecutter.use_docker }}".lower() == "y": remove_node_dockerfile() else: @@ -491,6 +515,9 @@ def main(): if "{{ cookiecutter.ci_tool }}" != "Github": remove_dotgithub_folder() + if "{{ cookiecutter.ci_tool }}" != "Drone": + remove_dotdrone_file() + if "{{ cookiecutter.use_drf }}".lower() == "n": remove_drf_starter_files() diff --git a/requirements.txt b/requirements.txt index 160e70c11..c98315450 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,20 @@ -cookiecutter==2.2.3 -sh==2.0.4; sys_platform != "win32" +cookiecutter==2.3.0 +sh==2.0.6; sys_platform != "win32" binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -black==23.7.0 +black==23.9.1 isort==5.12.0 -flake8==6.0.0 -django-upgrade==1.14.0 -djlint==1.32.1 -pre-commit==3.3.3 +flake8==6.1.0 +django-upgrade==1.14.1 +djlint==1.34.0 +pre-commit==3.4.0 # Testing # ------------------------------------------------------------------------------ -tox==4.6.4 -pytest==7.4.0 +tox==4.11.3 +pytest==7.4.2 pytest-xdist==3.3.1 pytest-cookies==0.7.0 pytest-instafail==0.5.0 @@ -22,7 +22,7 @@ pyyaml==6.0.1 # Scripting # ------------------------------------------------------------------------------ -PyGithub==1.59.0 -gitpython==3.1.32 +PyGithub==1.59.1 +gitpython==3.1.36 jinja2==3.1.2 requests==2.31.0 diff --git a/setup.py b/setup.py index 43e1b54cf..bd8994171 100644 --- a/setup.py +++ b/setup.py @@ -5,9 +5,9 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2023.07.24" +version = "2023.09.21" -with open("README.rst") as readme_file: +with open("README.md") as readme_file: long_description = readme_file.read() setup( diff --git a/tests/test_cookiecutter_generation.py b/tests/test_cookiecutter_generation.py index 853935e8c..31d006bed 100755 --- a/tests/test_cookiecutter_generation.py +++ b/tests/test_cookiecutter_generation.py @@ -115,8 +115,8 @@ SUPPORTED_COMBINATIONS = [ {"frontend_pipeline": "Webpack"}, {"use_celery": "y"}, {"use_celery": "n"}, - {"use_mailhog": "y"}, - {"use_mailhog": "n"}, + {"use_mailpit": "y"}, + {"use_mailpit": "n"}, {"use_sentry": "y"}, {"use_sentry": "n"}, {"use_whitenoise": "y"}, @@ -127,6 +127,7 @@ SUPPORTED_COMBINATIONS = [ {"ci_tool": "Travis"}, {"ci_tool": "Gitlab"}, {"ci_tool": "Github"}, + {"ci_tool": "Drone"}, {"keep_local_envs_in_vcs": "y"}, {"keep_local_envs_in_vcs": "n"}, {"debug": "y"}, diff --git a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json index 6ec731ce5..393408582 100644 --- a/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json +++ b/{{cookiecutter.project_slug}}/.devcontainer/devcontainer.json @@ -24,7 +24,7 @@ ], // Tells devcontainer.json supporting services / tools whether they should run // /bin/sh -c "while sleep 1000; do :; done" when starting the container instead of the container’s default command - "overrideCommand": true, + "overrideCommand": false, "service": "django", // "remoteEnv": {"PATH": "/home/dev-user/.local/bin:${containerEnv:PATH}"}, "remoteUser": "dev-user", diff --git a/{{cookiecutter.project_slug}}/.dockerignore b/{{cookiecutter.project_slug}}/.dockerignore index 7369480e3..a602416cd 100644 --- a/{{cookiecutter.project_slug}}/.dockerignore +++ b/{{cookiecutter.project_slug}}/.dockerignore @@ -9,3 +9,4 @@ .travis.yml venv .git +.envs/ diff --git a/{{cookiecutter.project_slug}}/.drone.yml b/{{cookiecutter.project_slug}}/.drone.yml new file mode 100644 index 000000000..dc08bfbab --- /dev/null +++ b/{{cookiecutter.project_slug}}/.drone.yml @@ -0,0 +1,48 @@ +kind: pipeline +name: default + +environment: + POSTGRES_USER: '{{ cookiecutter.project_slug }}' + POSTGRES_PASSWORD: '' + POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}' + POSTGRES_HOST_AUTH_METHOD: trust + {%- if cookiecutter.use_celery == 'y' %} + CELERY_BROKER_URL: 'redis://redis:6379/0' + {%- endif %} + +steps: +- name: lint + pull: if-not-exists + image: python:3.11 + environment: + PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit + volumes: + - name: pre-commit cache + path: ${PRE_COMMIT_HOME} + commands: + - export PRE_COMMIT_HOME=$CI_PROJECT_DIR/.cache/pre-commit + - pip install -q pre-commit + - pre-commit run --show-diff-on-failure --color=always --all-files + +- name: test + pull: if-not-exists + {%- if cookiecutter.use_docker == 'y' %} + image: docker/compose:1.29.2 + environment: + DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB + commands: + - docker-compose -f local.yml build + - docker-compose -f local.yml run --rm django python manage.py migrate + - docker-compose -f local.yml up -d + - docker-compose -f local.yml run django pytest + {%- else %} + image: python:3.11 + commands: + - pip install -r requirements/local.txt + - pytest + {%- endif%} + +volumes: +- name: pre-commit cache + host: + path: /tmp/drone/cache/pre-commit diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 3a863ccb9..e39933fe1 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout Code Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 @@ -65,7 +65,7 @@ jobs: steps: - name: Checkout Code Repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 {%- if cookiecutter.use_docker == 'y' %} - name: Build the Stack diff --git a/{{cookiecutter.project_slug}}/.gitignore b/{{cookiecutter.project_slug}}/.gitignore index 541f40846..0bb322186 100644 --- a/{{cookiecutter.project_slug}}/.gitignore +++ b/{{cookiecutter.project_slug}}/.gitignore @@ -329,8 +329,8 @@ tags dump.rdb ### Project template -{%- if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' %} -MailHog +{%- if cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'n' %} +mailpit {%- endif %} {{ cookiecutter.project_slug }}/media/ diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 0d1265ac2..6efcfef9e 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -16,30 +16,28 @@ repos: - id: check-case-conflict - id: check-docstring-first - id: detect-private-key -{%- if cookiecutter.frontend_pipeline in ["Webpack", "Gulp"] %} - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.0-alpha.9-for-vscode + rev: v3.0.3 hooks: - id: prettier args: ['--tab-width', '2', '--single-quote'] exclude: '{{cookiecutter.project_slug}}/templates/' -{%- endif %} - repo: https://github.com/adamchainz/django-upgrade - rev: '1.14.0' + rev: '1.14.1' hooks: - id: django-upgrade args: ['--target-version', '4.2'] - repo: https://github.com/asottile/pyupgrade - rev: v3.7.0 + rev: v3.11.1 hooks: - id: pyupgrade args: [--py311-plus] - repo: https://github.com/psf/black - rev: 23.3.0 + rev: 23.9.1 hooks: - id: black @@ -49,12 +47,12 @@ repos: - id: isort - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 + rev: 6.1.0 hooks: - id: flake8 - repo: https://github.com/Riverside-Healthcare/djLint - rev: v1.31.1 + rev: v1.34.0 hooks: - id: djlint-reformat-django - id: djlint-django diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index 56853f8f7..ccf245a2f 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -78,37 +78,35 @@ celery -A config.celery_app worker -B -l info ``` {%- endif %} -{%- if cookiecutter.use_mailhog == "y" %} +{%- if cookiecutter.use_mailpit == "y" %} ### Email Server {%- if cookiecutter.use_docker == "y" %} -In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server [MailHog](https://github.com/mailhog/MailHog) with a web interface is available as docker container. +In development, it is often nice to be able to see emails that are being sent from your application. For that reason local SMTP server [Mailpit](https://github.com/axllent/mailpit) with a web interface is available as docker container. -Container mailhog will start automatically when you will run all docker containers. +Container mailpit will start automatically when you will run all docker containers. Please check [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html) for more details how to start all containers. -With MailHog running, to view messages that are sent by your application, open your browser and go to `http://127.0.0.1:8025` +With Mailpit running, to view messages that are sent by your application, open your browser and go to `http://127.0.0.1:8025` {%- else %} -In development, it is often nice to be able to see emails that are being sent from your application. If you choose to use [MailHog](https://github.com/mailhog/MailHog) when generating the project a local SMTP server with a web interface will be available. +In development, it is often nice to be able to see emails that are being sent from your application. If you choose to use [Mailpit](https://github.com/axllent/mailpit) when generating the project a local SMTP server with a web interface will be available. -1. [Download the latest MailHog release](https://github.com/mailhog/MailHog/releases) for your OS. +1. [Download the latest Mailpit release](https://github.com/axllent/mailpit/releases) for your OS. -2. Rename the build to `MailHog`. +2. Copy the binary file to the project root. -3. Copy the file to the project root. +3. Make it executable: -4. Make it executable: + $ chmod +x mailpit - $ chmod +x MailHog +4. Spin up another terminal window and start it there: -5. Spin up another terminal window and start it there: + ./mailpit - ./MailHog - -6. Check out to see how it goes. +5. Check out to see how it goes. Now you have your own mail server running locally, ready to receive whatever you send it. diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index 3636ce1ef..67571feed 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.5-slim-bullseye as python # Python build stage FROM python as python-build-stage diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index f9895a083..1652ac2ce 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.5-slim-bullseye as python # Python build stage diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index a48cbc4af..49950b9af 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -25,7 +25,7 @@ RUN npm run build {%- endif %} # define an alias for the specific python version used in this file. -FROM python:3.11.4-slim-bullseye as python +FROM python:3.11.5-slim-bullseye as python # Python build stage FROM python as python-build-stage diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index bdedff720..e547dfbb8 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,4 +1,4 @@ -FROM traefik:2.10.3 +FROM traefik:2.10.4 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 f02d476c1..331ff06e2 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -30,7 +30,8 @@ LANGUAGE_CODE = "en-us" # from django.utils.translation import gettext_lazy as _ # LANGUAGES = [ # ('en', _('English')), -# ('pt-br', _('Português')), +# ('fr-fr', _('French')), +# ('pt-br', _('Portuguese')), # ] # https://docs.djangoproject.com/en/dev/ref/settings/#site-id SITE_ID = 1 @@ -160,6 +161,7 @@ MIDDLEWARE = [ "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", + "allauth.account.middleware.AccountMiddleware", ] # STATIC diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index adab6087a..0304d6cd4 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -25,12 +25,12 @@ CACHES = { # EMAIL # ------------------------------------------------------------------------------ -{% if cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'y' -%} +{% if cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'y' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host -EMAIL_HOST = env("EMAIL_HOST", default="mailhog") +EMAIL_HOST = env("EMAIL_HOST", default="mailpit") # https://docs.djangoproject.com/en/dev/ref/settings/#email-port EMAIL_PORT = 1025 -{%- elif cookiecutter.use_mailhog == 'y' and cookiecutter.use_docker == 'n' -%} +{%- elif cookiecutter.use_mailpit == 'y' and cookiecutter.use_docker == 'n' -%} # https://docs.djangoproject.com/en/dev/ref/settings/#email-host EMAIL_HOST = "localhost" # https://docs.djangoproject.com/en/dev/ref/settings/#email-port diff --git a/{{cookiecutter.project_slug}}/config/settings/production.py b/{{cookiecutter.project_slug}}/config/settings/production.py index 87340b88a..971efa396 100644 --- a/{{cookiecutter.project_slug}}/config/settings/production.py +++ b/{{cookiecutter.project_slug}}/config/settings/production.py @@ -109,28 +109,28 @@ AZURE_CONTAINER = env("DJANGO_AZURE_CONTAINER_NAME") {% if cookiecutter.use_whitenoise == 'y' -%} STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" {% elif cookiecutter.cloud_provider == 'AWS' -%} -STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootS3Boto3Storage" +STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticS3Storage" COLLECTFAST_STRATEGY = "collectfast.strategies.boto3.Boto3Strategy" STATIC_URL = f"https://{aws_s3_domain}/static/" {% elif cookiecutter.cloud_provider == 'GCP' -%} -STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticRootGoogleCloudStorage" +STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticGoogleCloudStorage" 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" +STATICFILES_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.StaticAzureStorage" STATIC_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/static/" {% endif -%} # MEDIA # ------------------------------------------------------------------------------ {%- if cookiecutter.cloud_provider == 'AWS' %} -DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootS3Boto3Storage" +DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaS3Storage" MEDIA_URL = f"https://{aws_s3_domain}/media/" {%- elif cookiecutter.cloud_provider == 'GCP' %} -DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaRootGoogleCloudStorage" +DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaGoogleCloudStorage" 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" +DEFAULT_FILE_STORAGE = "{{cookiecutter.project_slug}}.utils.storages.MediaAzureStorage" MEDIA_URL = f"https://{AZURE_ACCOUNT_NAME}.blob.core.windows.net/media/" {%- endif %} diff --git a/{{cookiecutter.project_slug}}/config/settings/test.py b/{{cookiecutter.project_slug}}/config/settings/test.py index 92211ec76..68126182e 100644 --- a/{{cookiecutter.project_slug}}/config/settings/test.py +++ b/{{cookiecutter.project_slug}}/config/settings/test.py @@ -29,6 +29,11 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" # ------------------------------------------------------------------------------ TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa: F405 +# MEDIA +# ------------------------------------------------------------------------------ +# https://docs.djangoproject.com/en/dev/ref/settings/#media-url +MEDIA_URL = 'http://media.testserver' + {%- if cookiecutter.frontend_pipeline == 'Webpack' %} # django-webpack-loader # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/local.yml b/{{cookiecutter.project_slug}}/local.yml index e55e18d32..692d87499 100644 --- a/{{cookiecutter.project_slug}}/local.yml +++ b/{{cookiecutter.project_slug}}/local.yml @@ -16,8 +16,8 @@ services: {%- if cookiecutter.use_celery == 'y' %} - redis {%- endif %} - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} volumes: - .:/app:z @@ -55,11 +55,11 @@ services: ports: - '9000:9000' command: /start-docs - {%- if cookiecutter.use_mailhog == 'y' %} + {%- if cookiecutter.use_mailpit == 'y' %} - mailhog: - image: mailhog/mailhog:v1.0.0 - container_name: {{ cookiecutter.project_slug }}_local_mailhog + mailpit: + image: axllent/mailpit:v1.8 + container_name: {{ cookiecutter.project_slug }}_local_mailpit ports: - "8025:8025" @@ -77,8 +77,8 @@ services: depends_on: - redis - postgres - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} ports: [] command: /start-celeryworker @@ -90,8 +90,8 @@ services: depends_on: - redis - postgres - {%- if cookiecutter.use_mailhog == 'y' %} - - mailhog + {%- if cookiecutter.use_mailpit == 'y' %} + - mailpit {%- endif %} ports: [] command: /start-celerybeat diff --git a/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po b/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po new file mode 100644 index 000000000..67434d505 --- /dev/null +++ b/{{cookiecutter.project_slug}}/locale/fr_FR/LC_MESSAGES/django.po @@ -0,0 +1,335 @@ +# Translations for the {{ cookiecutter.project_name }} project +# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }} +# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: {{ cookiecutter.version }}\n" +"Language: fr-FR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:5 +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:8 +msgid "Account Inactive" +msgstr "Compte inactif" + +#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:10 +msgid "This account is inactive." +msgstr "Ce compte est inactif." + +#: {{cookiecutter.project_slug}}/templates/account/email.html:7 +msgid "Account" +msgstr "Compte" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:10 +msgid "E-mail Addresses" +msgstr "Adresses e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:13 +msgid "The following e-mail addresses are associated with your account:" +msgstr "Les adresses e-mail suivantes sont associées à votre compte :" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:27 +msgid "Verified" +msgstr "Vérifié" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:29 +msgid "Unverified" +msgstr "Non vérifié" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:31 +msgid "Primary" +msgstr "Primaire" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:37 +msgid "Make Primary" +msgstr "Changer Primaire" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:38 +msgid "Re-send Verification" +msgstr "Renvoyer vérification" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:39 +msgid "Remove" +msgstr "Supprimer" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:46 +msgid "Warning:" +msgstr "Avertissement:" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:46 +msgid "" +"You currently do not have any e-mail address set up. You should really add " +"an e-mail address so you can receive notifications, reset your password, etc." +msgstr "" +"Vous n'avez actuellement aucune adresse e-mail configurée. Vous devriez ajouter " +"une adresse e-mail pour reçevoir des notifications, réinitialiser votre mot " +"de passe, etc." + +#: {{cookiecutter.project_slug}}/templates/account/email.html:51 +msgid "Add E-mail Address" +msgstr "Ajouter une adresse e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:56 +msgid "Add E-mail" +msgstr "Ajouter e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/email.html:66 +msgid "Do you really want to remove the selected e-mail address?" +msgstr "Voulez-vous vraiment supprimer l'adresse e-mail sélectionnée ?" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:6 +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:10 +msgid "Confirm E-mail Address" +msgstr "Confirmez votre adresse email" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:16 +#, python-format +msgid "" +"Please confirm that %(email)s is an e-mail " +"address for user %(user_display)s." +msgstr "" +"Veuillez confirmer que %(email)s est un e-mail " +"adresse de l'utilisateur %(user_display)s." + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:20 +msgid "Confirm" +msgstr "Confirm" + +#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:27 +#, python-format +msgid "" +"This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request." +msgstr "" +"Ce lien de confirmation par e-mail a expiré ou n'est pas valide. Veuillez" + "émettre une nouvelle demande de confirmation " +"par e-mail." + +#: {{cookiecutter.project_slug}}/templates/account/login.html:7 +#: {{cookiecutter.project_slug}}/templates/account/login.html:11 +#: {{cookiecutter.project_slug}}/templates/account/login.html:56 +#: {{cookiecutter.project_slug}}/templates/base.html:72 +msgid "Sign In" +msgstr "S'identifier" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:17 +msgid "Please sign in with one of your existing third party accounts:" +msgstr "Veuillez vous connecter avec l'un de vos comptes tiers existants :" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:19 +#, python-format +msgid "" +"Or, sign up for a %(site_name)s account and " +"sign in below:" +msgstr "" +"Ou, créez un compte %(site_name)s et " +"connectez-vous ci-dessous :" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:32 +msgid "or" +msgstr "ou" + +#: {{cookiecutter.project_slug}}/templates/account/login.html:41 +#, python-format +msgid "" +"If you have not created an account yet, then please sign up first." +msgstr "" +"Si vous n'avez pas encore créé de compte, veuillez d'abord vous inscrire." + +#: {{cookiecutter.project_slug}}/templates/account/login.html:55 +msgid "Forgot Password?" +msgstr "Mot de passe oublié?" + +#: {{cookiecutter.project_slug}}/templates/account/logout.html:5 +#: {{cookiecutter.project_slug}}/templates/account/logout.html:8 +#: {{cookiecutter.project_slug}}/templates/account/logout.html:17 +#: {{cookiecutter.project_slug}}/templates/base.html:61 +msgid "Sign Out" +msgstr "Se déconnecter" + +#: {{cookiecutter.project_slug}}/templates/account/logout.html:10 +msgid "Are you sure you want to sign out?" +msgstr "Êtes-vous certain de vouloir vous déconnecter?" + +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:9 +#: {{cookiecutter.project_slug}}/templates/account/password_change.html:14 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:5 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:4 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:7 +msgid "Change Password" +msgstr "Changer le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:7 +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:11 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:9 +msgid "Password Reset" +msgstr "Réinitialisation du mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:16 +msgid "" +"Forgotten your password? Enter your e-mail address below, and we'll send you " +"an e-mail allowing you to reset it." +msgstr "" +"Mot de passe oublié? Entrez votre adresse e-mail ci-dessous, et nous vous " +"enverrons un e-mail vous permettant de le réinitialiser." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:21 +msgid "Reset My Password" +msgstr "Réinitialiser mon mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:24 +msgid "Please contact us if you have any trouble resetting your password." +msgstr "" +"Veuillez nous contacter si vous rencontrez des difficultés pour réinitialiser" +"votre mot de passe." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:15 +msgid "" +"We have sent you an e-mail. Please contact us if you do not receive it " +"within a few minutes." +msgstr "" +"Nous vous avons envoyé un e-mail. Veuillez nous contacter si vous ne le " +"recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8 +msgid "Bad Token" +msgstr "Token Invalide" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:12 +#, python-format +msgid "" +"The password reset link was invalid, possibly because it has already been " +"used. Please request a new password reset." +msgstr "" +"Le lien de réinitialisation du mot de passe n'était pas valide, peut-être parce " +"qu'il a déjà été utilisé. Veuillez faire une " +"nouvelle demande de réinitialisation de mot de passe." + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:18 +msgid "change password" +msgstr "changer le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:21 +#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:8 +msgid "Your password is now changed." +msgstr "Votre mot de passe est maintenant modifié." + +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:6 +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:9 +#: {{cookiecutter.project_slug}}/templates/account/password_set.html:14 +msgid "Set Password" +msgstr "Définir le mot de passe" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:6 +msgid "Signup" +msgstr "S'inscrire" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:9 +#: {{cookiecutter.project_slug}}/templates/account/signup.html:19 +#: {{cookiecutter.project_slug}}/templates/base.html:67 +msgid "Sign Up" +msgstr "S'inscrire" + +#: {{cookiecutter.project_slug}}/templates/account/signup.html:11 +#, python-format +msgid "" +"Already have an account? Then please sign in." +msgstr "" +"Vous avez déjà un compte? Alors veuillez vous connecter." + +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:5 +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:8 +msgid "Sign Up Closed" +msgstr "Inscriptions closes" + +#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:10 +msgid "We are sorry, but the sign up is currently closed." +msgstr "Désolé, mais l'inscription est actuellement fermée." + +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:5 +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:8 +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:5 +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:8 +msgid "Verify Your E-mail Address" +msgstr "Vérifiez votre adresse e-mail" + +#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:10 +msgid "" +"We have sent an e-mail to you for verification. Follow the link provided to " +"finalize the signup process. Please contact us if you do not receive it " +"within a few minutes." +msgstr "Nous vous avons envoyé un e-mail pour vérification. Suivez le lien fourni " +"pour finalisez le processus d'inscription. Veuillez nous contacter si vous ne le " +"recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:12 +msgid "" +"This part of the site requires us to verify that\n" +"you are who you claim to be. For this purpose, we require that you\n" +"verify ownership of your e-mail address. " +msgstr "" +"Cette partie du site nous oblige à vérifier que\n" +"vous êtes qui vous prétendez être. Nous vous demandons donc de\n" +"vérifier la propriété de votre adresse e-mail." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:16 +msgid "" +"We have sent an e-mail to you for\n" +"verification. Please click on the link inside this e-mail. Please\n" +"contact us if you do not receive it within a few minutes." +msgstr "" +"Nous vous avons envoyé un e-mail pour\n" +"vérification. Veuillez cliquer sur le lien contenu dans cet e-mail. Veuillez nous\n" +"contacter si vous ne le recevez pas d'ici quelques minutes." + +#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:20 +#, python-format +msgid "" +"Note: you can still change your e-" +"mail address." +msgstr "" +"Remarque : vous pouvez toujours changer votre e-" +"adresse e-mail." + +#: {{cookiecutter.project_slug}}/templates/base.html:57 +msgid "My Profile" +msgstr "Mon Profil" + +#: {{cookiecutter.project_slug}}/users/admin.py:17 +msgid "Personal info" +msgstr "Personal info" + +#: {{cookiecutter.project_slug}}/users/admin.py:19 +msgid "Permissions" +msgstr "Permissions" + +#: {{cookiecutter.project_slug}}/users/admin.py:30 +msgid "Important dates" +msgstr "Dates importantes" + +#: {{cookiecutter.project_slug}}/users/apps.py:7 +msgid "Users" +msgstr "Utilisateurs" + +#: {{cookiecutter.project_slug}}/users/forms.py:24 +#: {{cookiecutter.project_slug}}/users/tests/test_forms.py:36 +msgid "This username has already been taken." +msgstr "Ce nom d'utilisateur est déjà pris." + +#: {{cookiecutter.project_slug}}/users/models.py:15 +msgid "Name of User" +msgstr "Nom de l'utilisateur" + +#: {{cookiecutter.project_slug}}/users/views.py:23 +msgid "Information successfully updated" +msgstr "Informations mises à jour avec succès" diff --git a/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po b/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po index 2556abba8..1681e0f57 100644 --- a/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po +++ b/{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po @@ -127,7 +127,7 @@ msgstr "Ou, cadastre-se para uma conta em %(site_ #: {{cookiecutter.project_slug}}/templates/account/login.html:32 msgid "or" -msgstr "or" +msgstr "ou" #: {{cookiecutter.project_slug}}/templates/account/login.html:41 #, python-format diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index b0f47703f..94c3d16b7 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ python-slugify==8.0.1 # https://github.com/un33k/python-slugify -Pillow==10.0.0 # https://github.com/python-pillow/Pillow +Pillow==10.0.1 # https://github.com/python-pillow/Pillow {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %} rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin @@ -7,31 +7,31 @@ rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/n rcssmin==1.1.1 # https://github.com/ndparker/rcssmin {%- endif %} {%- endif %} -argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi +argon2-cffi==23.1.0 # https://github.com/hynek/argon2_cffi {%- if cookiecutter.use_whitenoise == 'y' %} whitenoise==6.5.0 # https://github.com/evansd/whitenoise {%- endif %} -redis==4.6.0 # https://github.com/redis/redis-py +redis==5.0.0 # https://github.com/redis/redis-py {%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %} hiredis==2.2.3 # https://github.com/redis/hiredis-py {%- endif %} {%- if cookiecutter.use_celery == "y" %} -celery==5.3.1 # pyup: < 6.0 # https://github.com/celery/celery +celery==5.3.4 # pyup: < 6.0 # https://github.com/celery/celery django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat {%- if cookiecutter.use_docker == 'y' %} -flower==2.0.0 # https://github.com/mher/flower +flower==2.0.1 # https://github.com/mher/flower {%- endif %} {%- endif %} {%- if cookiecutter.use_async == 'y' %} -uvicorn[standard]==0.23.1 # https://github.com/encode/uvicorn +uvicorn[standard]==0.23.2 # https://github.com/encode/uvicorn {%- endif %} # Django # ------------------------------------------------------------------------------ -django==4.2.3 # pyup: < 5.0 # https://www.djangoproject.com/ -django-environ==0.10.0 # https://github.com/joke2k/django-environ +django==4.2.5 # pyup: < 5.0 # https://www.djangoproject.com/ +django-environ==0.11.2 # https://github.com/joke2k/django-environ django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils -django-allauth==0.54.0 # https://github.com/pennersr/django-allauth +django-allauth==0.56.1 # https://github.com/pennersr/django-allauth django-crispy-forms==2.0 # https://github.com/django-crispy-forms/django-crispy-forms crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5 {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index 569fd2331..5afde2967 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.3.6 # https://github.com/pallets/werkzeug +Werkzeug[watchdog]==2.3.7 # https://github.com/pallets/werkzeug ipdb==0.13.13 # https://github.com/gotcha/ipdb {%- if cookiecutter.use_docker == 'y' %} psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg @@ -8,42 +8,42 @@ psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg psycopg[binary]==3.1.9 # https://github.com/psycopg/psycopg {%- endif %} {%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %} -watchfiles==0.19.0 # https://github.com/samuelcolvin/watchfiles +watchfiles==0.20.0 # https://github.com/samuelcolvin/watchfiles {%- endif %} # Testing # ------------------------------------------------------------------------------ mypy==1.4.1 # https://github.com/python/mypy -django-stubs==4.2.3 # https://github.com/typeddjango/django-stubs -pytest==7.4.0 # https://github.com/pytest-dev/pytest +django-stubs[compatible-mypy]==4.2.3 # https://github.com/typeddjango/django-stubs +pytest==7.4.2 # https://github.com/pytest-dev/pytest pytest-sugar==0.9.7 # https://github.com/Frozenball/pytest-sugar {%- if cookiecutter.use_drf == "y" %} -djangorestframework-stubs==3.14.2 # https://github.com/typeddjango/djangorestframework-stubs +djangorestframework-stubs[compatible-mypy]==3.14.2 # https://github.com/typeddjango/djangorestframework-stubs {%- endif %} # Documentation # ------------------------------------------------------------------------------ -sphinx==6.2.1 # https://github.com/sphinx-doc/sphinx +sphinx==7.2.6 # https://github.com/sphinx-doc/sphinx sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild # Code quality # ------------------------------------------------------------------------------ -flake8==6.0.0 # https://github.com/PyCQA/flake8 -flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort -coverage==7.2.7 # https://github.com/nedbat/coveragepy -black==23.7.0 # https://github.com/psf/black -djlint==1.32.1 # https://github.com/Riverside-Healthcare/djLint +flake8==6.1.0 # https://github.com/PyCQA/flake8 +flake8-isort==6.1.0 # https://github.com/gforcada/flake8-isort +coverage==7.3.1 # https://github.com/nedbat/coveragepy +black==23.9.1 # https://github.com/psf/black +djlint==1.34.0 # https://github.com/Riverside-Healthcare/djLint 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.3.3 # https://github.com/pre-commit/pre-commit +pre-commit==3.4.0 # https://github.com/pre-commit/pre-commit # Django # ------------------------------------------------------------------------------ factory-boy==3.3.0 # https://github.com/FactoryBoy/factory_boy -django-debug-toolbar==4.1.0 # https://github.com/jazzband/django-debug-toolbar +django-debug-toolbar==4.2.0 # https://github.com/jazzband/django-debug-toolbar django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions django-coverage-plugin==3.1.0 # https://github.com/nedbat/django_coverage_plugin pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index 03b75a65f..ecbb34799 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -8,7 +8,7 @@ psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- if cookiecutter.use_sentry == "y" %} -sentry-sdk==1.28.1 # https://github.com/getsentry/sentry-python +sentry-sdk==1.31.0 # https://github.com/getsentry/sentry-python {%- endif %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.2.3 # https://github.com/redis/hiredis-py @@ -17,28 +17,28 @@ hiredis==2.2.3 # https://github.com/redis/hiredis-py # Django # ------------------------------------------------------------------------------ {%- if cookiecutter.cloud_provider == 'AWS' %} -django-storages[boto3]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[s3]==1.14 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'GCP' %} -django-storages[google]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[google]==1.14 # https://github.com/jschneier/django-storages {%- elif cookiecutter.cloud_provider == 'Azure' %} -django-storages[azure]==1.13.2 # https://github.com/jschneier/django-storages +django-storages[azure]==1.14 # https://github.com/jschneier/django-storages {%- endif %} {%- if cookiecutter.mail_service == 'Mailgun' %} -django-anymail[mailgun]==10.0 # https://github.com/anymail/django-anymail +django-anymail[mailgun]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Amazon SES' %} -django-anymail[amazon-ses]==10.0 # https://github.com/anymail/django-anymail +django-anymail[amazon-ses]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mailjet' %} -django-anymail[mailjet]==10.0 # https://github.com/anymail/django-anymail +django-anymail[mailjet]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Mandrill' %} -django-anymail[mandrill]==10.0 # https://github.com/anymail/django-anymail +django-anymail[mandrill]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Postmark' %} -django-anymail[postmark]==10.0 # https://github.com/anymail/django-anymail +django-anymail[postmark]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Sendgrid' %} -django-anymail[sendgrid]==10.0 # https://github.com/anymail/django-anymail +django-anymail[sendgrid]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SendinBlue' %} -django-anymail[sendinblue]==10.0 # https://github.com/anymail/django-anymail +django-anymail[sendinblue]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'SparkPost' %} -django-anymail[sparkpost]==10.0 # https://github.com/anymail/django-anymail +django-anymail[sparkpost]==10.1 # https://github.com/anymail/django-anymail {%- elif cookiecutter.mail_service == 'Other SMTP' %} -django-anymail==10.0 # https://github.com/anymail/django-anymail +django-anymail==10.1 # https://github.com/anymail/django-anymail {%- endif %} diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 431fc7e8c..3124d55e9 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.11.4 +python-3.11.5 diff --git a/{{cookiecutter.project_slug}}/setup.cfg b/{{cookiecutter.project_slug}}/setup.cfg index 829064213..2412f1746 100644 --- a/{{cookiecutter.project_slug}}/setup.cfg +++ b/{{cookiecutter.project_slug}}/setup.cfg @@ -4,6 +4,7 @@ [flake8] max-line-length = 119 exclude = .tox,.git,*/migrations/*,*/static/CACHE/*,docs,node_modules,venv,.venv +extend-ignore = E203 [pycodestyle] max-line-length = 119 diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py index 080c734bb..e1822375b 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/contrib/sites/migrations/0003_set_site_domain_and_name.py @@ -40,8 +40,8 @@ def update_site_forward(apps, schema_editor): _update_or_create_site_with_sequence( Site, schema_editor.connection, - "{{cookiecutter.domain_name}}", - "{{cookiecutter.project_name}}", + "{{ cookiecutter.domain_name }}", + "{{ cookiecutter.project_name[:50] }}", ) diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py index 4b86f7985..bebd8adcf 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -29,6 +29,13 @@ class UserFactory(DjangoModelFactory): ) self.set_password(password) + @classmethod + def _after_postgeneration(cls, instance, create, results=None): + """Save again the instance if creating and at least one hook ran.""" + if create and results and not cls._meta.skip_postgeneration_save: + # Some post-generation hooks ran, and may have modified us. + instance.save() + class Meta: model = get_user_model() django_get_or_create = ["{{cookiecutter.username_type}}"] diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py index 27595ad1a..cc055378a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/utils/storages.py @@ -1,36 +1,36 @@ {% if cookiecutter.cloud_provider == 'AWS' -%} -from storages.backends.s3boto3 import S3Boto3Storage +from storages.backends.s3 import S3Storage -class StaticRootS3Boto3Storage(S3Boto3Storage): +class StaticS3Storage(S3Storage): location = "static" default_acl = "public-read" -class MediaRootS3Boto3Storage(S3Boto3Storage): +class MediaS3Storage(S3Storage): location = "media" file_overwrite = False {%- elif cookiecutter.cloud_provider == 'GCP' -%} from storages.backends.gcloud import GoogleCloudStorage -class StaticRootGoogleCloudStorage(GoogleCloudStorage): +class StaticGoogleCloudStorage(GoogleCloudStorage): location = "static" default_acl = "publicRead" -class MediaRootGoogleCloudStorage(GoogleCloudStorage): +class MediaGoogleCloudStorage(GoogleCloudStorage): location = "media" file_overwrite = False {%- elif cookiecutter.cloud_provider == 'Azure' -%} from storages.backends.azure_storage import AzureStorage -class StaticRootAzureStorage(AzureStorage): +class StaticAzureStorage(AzureStorage): location = "static" -class MediaRootAzureStorage(AzureStorage): +class MediaAzureStorage(AzureStorage): location = "media" file_overwrite = False {%- endif %}