Merge branch 'master' into patch-1

This commit is contained in:
Bruno Alla 2021-01-24 21:49:00 +00:00
commit 26a424e09c
53 changed files with 557 additions and 178 deletions

View File

@ -1037,5 +1037,35 @@
"name": "Wes Turner",
"github_login": "westurner",
"twitter_username": "westurner"
},
{
"name": "Jakub Musko",
"github_login": "umgelurgel",
"twitter_username": ""
},
{
"name": "Fabian Affolter",
"github_login": "fabaff",
"twitter_username": "fabaff"
},
{
"name": "Simon Rey",
"github_login": "eqqe",
"twitter_username": ""
},
{
"name": "Yotam Tal",
"github_login": "yotamtal",
"twitter_username": ""
},
{
"name": "John",
"github_login": "thorrak",
"twitter_username": ""
},
{
"name": "vascop",
"github_login": "vascop",
"twitter_username": ""
}
]

85
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,85 @@
name: CI
on:
push:
branches: [ master ]
pull_request:
jobs:
tox:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
tox-env:
- py38
- black-template
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install -U pip
python -m pip install -U tox
- name: Tox ${{ matrix.tox-env }}
run: tox -e ${{ matrix.tox-env }}
docker:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
script:
- name: Basic
args: ""
- name: Extended
args: "use_celery=y use_drf=y js_task_runner=Gulp"
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Docker ${{ matrix.script.name }}
run: sh tests/test_docker.sh ${{ matrix.script.args }}
bare:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
script:
- name: With Celery
args: "use_celery=y use_compressor=y"
services:
redis:
image: redis:5.0
ports:
- 6379:6379
postgres:
image: postgres:12
ports:
- 5432:5432
env:
POSTGRES_PASSWORD: postgres
env:
CELERY_BROKER_URL: "redis://localhost:6379/0"
# postgres://user:password@host:port/database
DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres"
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Bare Metal ${{ matrix.script.name }}
run: sh tests/test_bare.sh ${{ matrix.script.args }}

View File

@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2.1.3
- uses: actions/setup-python@v2
with:
python-version: 3.8
@ -26,7 +26,7 @@ jobs:
run: pre-commit autoupdate
- name: Create Pull Request
uses: peter-evans/create-pull-request@v2
uses: peter-evans/create-pull-request@v3.6.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
branch: update/pre-commit-autoupdate

View File

@ -15,9 +15,9 @@ jobs:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2.1.3
uses: actions/setup-python@v2
with:
python-version: "3.8"
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
@ -28,7 +28,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4.5.1
uses: stefanzweifel/git-auto-commit-action@v4.8.0
with:
commit_message: Update Changelog
file_pattern: CHANGELOG.md

View File

@ -13,9 +13,9 @@ jobs:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2.1.3
uses: actions/setup-python@v2
with:
python-version: "3.8"
python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
@ -24,7 +24,7 @@ jobs:
run: python scripts/update_contributors.py
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4.5.1
uses: stefanzweifel/git-auto-commit-action@v4.8.0
with:
commit_message: Update Contributors
file_pattern: CONTRIBUTORS.md .github/contributors.json

View File

@ -1,36 +0,0 @@
services:
- docker
language: python
python: 3.8
before_install:
- docker-compose -v
- docker -v
matrix:
include:
- name: Test results
script: tox -e py38
- name: Black template
script: tox -e black-template
- name: Basic Docker
script: sh tests/test_docker.sh
- name: Extended Docker
script: sh tests/test_docker.sh use_celery=y use_drf=y js_task_runner=Gulp
- name: Bare metal
script: sh tests/test_bare.sh use_celery=y use_compressor=y
services:
- postgresql
- redis-server
env:
- CELERY_BROKER_URL=redis://localhost:6379/0
install:
- pip install tox
notifications:
email:
on_success: change
on_failure: always

View File

@ -3,6 +3,218 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
<!-- GENERATOR_PLACEHOLDER -->
## [2021-01-22]
### Changed
- Use self.request.user instead of second query ([#3012](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3012))
## [2021-01-14]
### Updated
- Update tox to 3.21.1 ([#3006](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3006))
## [2021-01-10]
### Updated
- Update pylint-django to 2.4.2 ([#3003](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3003))
- Update tox to 3.21.0 ([#3002](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3002))
## [2021-01-08]
### Changed
- Upgrade Travis to Focal ([#2999](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2999))
### Updated
- Update pylint-django to 2.4.1 ([#3001](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3001))
- Update sphinx to 3.4.3 ([#3000](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/3000))
- Update pylint-django to 2.4.0 ([#2996](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2996))
## [2021-01-04]
### Updated
- Update isort to 5.7.0 ([#2988](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2988))
- Update uvicorn to 0.13.3 ([#2987](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2987))
- Auto-update pre-commit hooks ([#2990](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2990))
- Update sphinx to 3.4.2 ([#2995](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2995))
- Update pillow to 8.1.0 ([#2993](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2993))
## [2020-12-29]
### Updated
- Update pygithub to 1.54.1 ([#2982](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2982))
- Update django-storages to 1.11.1 ([#2981](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2981))
## [2020-12-26]
### Updated
- Update sphinx to 3.4.1 ([#2985](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2985))
- Update pytz to 2020.5 ([#2984](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2984))
## [2020-12-23]
### Changed
- Bump peter-evans/create-pull-request from v3.5.2 to v3.6.0 ([#2980](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2980))
### Updated
- Update flower to 0.9.7 ([#2979](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2979))
- Update sphinx to 3.4.0 ([#2978](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2978))
- Update coverage to 5.3.1 ([#2977](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2977))
- Update uvicorn to 0.13.2 ([#2976](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2976))
## [2020-12-18]
### Changed
- Bump stefanzweifel/git-auto-commit-action from v4.7.2 to v4.8.0 ([#2972](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2972))
### Updated
- Update django-storages to 1.11 ([#2973](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2973))
- Update pytest to 6.2.1 ([#2971](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2971))
- Auto-update pre-commit hooks ([#2970](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2970))
## [2020-12-14]
### Updated
- Update pytest to 6.2.0 ([#2968](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2968))
- Update django-cors-headers to 3.6.0 ([#2967](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2967))
- Update uvicorn to 0.13.1 ([#2966](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2966))
## [2020-12-10]
### Changed
- Hot-reload support to celery ([#2554](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2554))
### Updated
- Update uvicorn to 0.13.0 ([#2962](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2962))
- Update sentry-sdk to 0.19.5 ([#2965](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2965))
## [2020-12-09]
### Changed
- Bump peter-evans/create-pull-request from v3.5.1 to v3.5.2 ([#2964](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2964))
## [2020-12-08]
### Updated
- Update pre-commit to 2.9.3 ([#2961](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2961))
## [2020-12-04]
### Updated
- Update django-debug-toolbar to 3.2 ([#2959](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2959))
## [2020-12-02]
### Updated
- Update django-model-utils to 4.1.1 ([#2957](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2957))
- Update pygithub to 1.54 ([#2958](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2958))
## [2020-11-26]
### Updated
- Update django-extensions to 3.1.0 ([#2947](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2947))
- Update pre-commit to 2.9.2 ([#2948](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2948))
- Update django-allauth to 0.44.0 ([#2945](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2945))
## [2020-11-25]
### Changed
- Bump peter-evans/create-pull-request from v3.5.0 to v3.5.1 ([#2944](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2944))
## [2020-11-23]
### Updated
- Update uvicorn to 0.12.3 ([#2943](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2943))
- Update pre-commit to 2.9.0 ([#2942](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2942))
## [2020-11-21]
### Changed
- Fix after uvicorn 0.12.0 - Ship extra dependencies ([#2939](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2939))
## [2020-11-20]
### Updated
- Update sentry-sdk to 0.19.4 ([#2938](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2938))
## [2020-11-19]
### Updated
- Update django-crispy-forms to 1.10.0 ([#2937](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2937))
## [2020-11-17]
### Changed
- Bump peter-evans/create-pull-request from v2 to v3.5.0 ([#2936](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2936))
## [2020-11-15]
### Changed
- Fix formatting in docs ([#2935](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2935))
## [2020-11-13]
### Changed
- Upgrade factory-boy to 3.1.0 ([#2932](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2932))
### Updated
- Update sentry-sdk to 0.19.3 ([#2933](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2933))
- Update sphinx to 3.3.1 ([#2934](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2934))
## [2020-11-12]
### Changed
- Migrate CI to Github Actions ([#2931](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2931))
## [2020-11-06]
### Updated
- Update djangorestframework to 3.12.2 ([#2930](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2930))
## [2020-11-04]
### Changed
- Fix docs service and add RTD support ([#2920](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2920))
- Bump stefanzweifel/git-auto-commit-action from v4.6.0 to v4.7.2 ([#2914](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2914))
### Updated
- Auto-update pre-commit hooks ([#2908](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2908))
- Update mypy to 0.790 ([#2886](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2886))
- Update django-stubs to 1.7.0 ([#2916](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2916))
## [2020-11-03]
### Updated
- Update sentry-sdk to 0.19.2 ([#2926](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2926))
- Update sphinx to 3.3.0 ([#2925](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2925))
- Update django to 3.0.11 ([#2924](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2924))
- Update pytz to 2020.4 ([#2923](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2923))
- Update pre-commit to 2.8.2 ([#2919](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2919))
- Update pytest to 6.1.2 ([#2917](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2917))
- Update sh to 1.14.1 ([#2912](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2912))
- Update pytest-django to 4.1.0 ([#2911](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2911))
- Update pillow to 8.0.1 ([#2910](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2910))
- Update django-celery-beat to 2.1.0 ([#2907](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2907))
- Update uvicorn to 0.12.2 ([#2906](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2906))
## [2020-10-19]
### Updated
- Update sentry-sdk to 0.19.1 ([#2905](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2905))
## [2020-10-17]
### Updated
- Update django-allauth to 0.43.0 ([#2901](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2901))
- Update pytest-django to 4.0.0 ([#2903](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2903))
## [2020-10-15]
### Updated
- Update pillow to 8.0.0 ([#2898](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2898))
## [2020-10-14]
### Updated
- Auto-update pre-commit hooks ([#2897](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2897))
- Update sentry-sdk to 0.19.0 ([#2896](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2896))
## [2020-10-13]
### Updated
- Update isort to 5.6.4 ([#2895](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2895))
## [2020-10-12]
### Changed
- Bump stefanzweifel/git-auto-commit-action from v4.5.1 to v4.6.0 ([#2893](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2893))
### Updated
- Auto-update pre-commit hooks ([#2892](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2892))
## [2020-10-11]
### Updated
- Auto-update pre-commit hooks ([#2890](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2890))
- Update isort to 5.6.3 ([#2891](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2891))
- Update django-anymail to 8.1 ([#2887](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2887))
- Update tox to 3.20.1 ([#2885](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2885))
## [2020-10-09]
### Updated
- Auto-update pre-commit hooks ([#2884](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2884))
- Update isort to 5.6.1 ([#2883](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2883))
## [2020-10-08]
### Changed
- Add dedicated websockets package ([#2881](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2881))
### Updated
- Update isort to 5.6.0 ([#2882](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2882))
## [2020-10-04]
### Updated
- Update pytest to 6.1.1 ([#2880](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2880))
- Update mypy and django-stubs ([#2874](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2874))
- Auto-update pre-commit hooks ([#2876](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2876))
- Update flake8 to 3.8.4 ([#2877](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2877))
## [2020-10-01]
### Changed
- Bump actions/setup-python from v2.1.2 to v2.1.3 ([#2869](https://api.github.com/repos/pydanny/cookiecutter-django/pulls/2869))

View File

@ -656,6 +656,13 @@ Listed in alphabetical order.
</td>
<td></td>
</tr>
<tr>
<td>Fabian Affolter</td>
<td>
<a href="https://github.com/fabaff">fabaff</a>
</td>
<td>fabaff</td>
</tr>
<tr>
<td>Felipe Arruda</td>
<td>
@ -796,6 +803,13 @@ Listed in alphabetical order.
</td>
<td></td>
</tr>
<tr>
<td>Jakub Musko</td>
<td>
<a href="https://github.com/umgelurgel">umgelurgel</a>
</td>
<td></td>
</tr>
<tr>
<td>James Williams</td>
<td>
@ -852,6 +866,13 @@ Listed in alphabetical order.
</td>
<td>afrowave</td>
</tr>
<tr>
<td>John</td>
<td>
<a href="https://github.com/thorrak">thorrak</a>
</td>
<td></td>
</tr>
<tr>
<td>John Cass</td>
<td>
@ -1272,6 +1293,13 @@ Listed in alphabetical order.
</td>
<td>saschalalala</td>
</tr>
<tr>
<td>Simon Rey</td>
<td>
<a href="https://github.com/eqqe">eqqe</a>
</td>
<td></td>
</tr>
<tr>
<td>Sorasful</td>
<td>
@ -1398,6 +1426,13 @@ Listed in alphabetical order.
</td>
<td>egregors</td>
</tr>
<tr>
<td>vascop</td>
<td>
<a href="https://github.com/vascop">vascop</a>
</td>
<td></td>
</tr>
<tr>
<td>Vicente G. Reyes</td>
<td>
@ -1461,6 +1496,13 @@ Listed in alphabetical order.
</td>
<td></td>
</tr>
<tr>
<td>Yotam Tal</td>
<td>
<a href="https://github.com/yotamtal">yotamtal</a>
</td>
<td></td>
</tr>
<tr>
<td>Yuchen Xie</td>
<td>

View File

@ -1,8 +1,8 @@
Cookiecutter Django
=======================
===================
.. image:: https://travis-ci.org/pydanny/cookiecutter-django.svg?branch=master
:target: https://travis-ci.org/pydanny/cookiecutter-django?branch=master
.. image:: https://img.shields.io/github/workflow/status/pydanny/cookiecutter-django/CI/master
:target: https://github.com/pydanny/cookiecutter-django/actions?query=workflow%3ACI
:alt: Build Status
.. image:: https://readthedocs.org/projects/cookiecutter-django/badge/?version=latest

View File

@ -34,10 +34,10 @@ First things first.
$ git init # A git repo is required for pre-commit to install
$ pre-commit install
.. note::
.. note::
the `pre-commit` exists in the generated project as default.
for the details of `pre-commit`, follow the [site of pre-commit](https://pre-commit.com/).
the `pre-commit` exists in the generated project as default.
for the details of `pre-commit`, follow the [site of pre-commit](https://pre-commit.com/).
#. Create a new PostgreSQL database using createdb_: ::

View File

@ -15,15 +15,30 @@ If you set up your project to `develop locally with docker`_, run the following
Navigate to port 7000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development.
Note: using Docker for documentation sets up a temporary SQLite file by setting the environment variable ``DATABASE_URL=sqlite:///readthedocs.db`` in ``docs/conf.py`` to avoid a dependency on PostgreSQL.
Generate API documentation
----------------------------
Edit the ``docs/_source`` files and project application docstrings to create your documentation.
Edit the ``docs`` files and project application docstrings to create your documentation.
Sphinx can automatically include class and function signatures and docstrings in generated documentation.
Sphinx can automatically include class and function signatures and docstrings in generated documentation.
See the generated project documentation for more examples.
Setting up ReadTheDocs
----------------------
To setup your documentation on `ReadTheDocs`_, you must
1. Go to `ReadTheDocs`_ and login/create an account
2. Add your GitHub repository
3. Trigger a build
Additionally, you can auto-build Pull Request previews, but `you must enable it`_.
.. _localhost: http://localhost:7000/
.. _Sphinx: https://www.sphinx-doc.org/en/master/index.html
.. _develop locally: ./developing-locally.html
.. _develop locally with docker: ./developing-locally-docker.html
.. _ReadTheDocs: https://readthedocs.org/
.. _you must enable it: https://docs.readthedocs.io/en/latest/guides/autobuild-docs-for-pull-requests.html#autobuild-documentation-for-pull-requests

View File

@ -1,23 +1,23 @@
cookiecutter==1.7.2
sh==1.14.0
sh==1.14.1
binaryornot==0.4.4
# Code quality
# ------------------------------------------------------------------------------
black==20.8b1
isort==5.5.4
isort==5.7.0
flake8==3.8.4
flake8-isort==4.0.0
# Testing
# ------------------------------------------------------------------------------
tox==3.20.0
pytest==6.1.1
tox==3.21.2
pytest==5.4.3 # pyup: <6 # https://github.com/hackebrot/pytest-cookies/issues/51
pytest-cookies==0.5.1
pytest-instafail==0.4.2
pyyaml==5.3.1
pyyaml==5.4.1
# Scripting
# ------------------------------------------------------------------------------
PyGithub==1.53
PyGithub==1.54.1
jinja2==2.11.2

View File

@ -10,7 +10,7 @@ except ImportError:
# Our version ALWAYS matches the version of Django we support
# If Django has a new release, we branch, tag, then update this setting after the tag.
version = "3.0.10"
version = "3.0.11"
if sys.argv[-1] == "tag":
os.system(f'git tag -a {version} -m "version {version}"')

View File

@ -6,9 +6,9 @@
set -o errexit
set -x
# Install modern pip to use new resolver:
# https://blog.python.org/2020/07/upgrade-pip-20-2-changes-20-3.html
pip install 'pip>=20.2'
# Install modern pip with new resolver:
# https://blog.python.org/2020/11/pip-20-3-release-new-resolver.html
pip install 'pip>=20.3'
# install test requirements
pip install -r requirements.txt
@ -25,7 +25,7 @@ cd my_awesome_project
sudo utility/install_os_dependencies.sh install
# Install Python deps
pip install --use-feature=2020-resolver -r requirements/local.txt
pip install -r requirements/local.txt
# run the project's tests
pytest

View File

@ -58,7 +58,7 @@ jobs:
run: docker-compose -f local.yml exec -T django pytest
- name: Tear down the Stack
run: docker-compose down
run: docker-compose -f local.yml down
{%- else %}

View File

@ -4,7 +4,7 @@ fail_fast: true
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
rev: v3.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@ -16,7 +16,7 @@ repos:
- id: black
- repo: https://github.com/timothycrosley/isort
rev: 5.5.4
rev: 5.7.0
hooks:
- id: isort

View File

@ -0,0 +1,9 @@
version: 2
sphinx:
configuration: docs/conf.py
python:
version: 3.8
install:
- requirements: requirements/local.txt

View File

@ -1,4 +1,4 @@
dist: xenial
dist: focal
language: python
python:

View File

@ -4,4 +4,4 @@ set -o errexit
set -o nounset
celery -A config.celery_app worker -l INFO
watchgod celery.__main__.main --args -A config.celery_app worker -l INFO

View File

@ -24,6 +24,8 @@ COPY ./requirements /requirements
# All imports needed for autodoc.
RUN pip install -r /requirements/local.txt -r /requirements/production.txt
WORKDIR /docs
COPY ./compose/local/docs/start /start-docs
RUN sed -i 's/\r$//g' /start-docs
RUN chmod +x /start-docs
CMD make livehtml
WORKDIR /docs

View File

@ -0,0 +1,7 @@
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
make livehtml

View File

@ -5,6 +5,11 @@ entryPoints:
web:
# http
address: ":80"
http:
# https://docs.traefik.io/routing/entrypoints/#entrypoint
redirections:
entryPoint:
to: web-secure
web-secure:
# https
@ -27,19 +32,6 @@ certificatesResolvers:
http:
routers:
web-router:
{%- if cookiecutter.domain_name.count('.') == 1 %}
rule: "Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)"
{% else %}
rule: "Host(`{{ cookiecutter.domain_name }}`)"
{%- endif %}
entryPoints:
- web
middlewares:
- redirect
- csrf
service: django
web-secure-router:
{%- if cookiecutter.domain_name.count('.') == 1 %}
rule: "Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)"
@ -67,11 +59,6 @@ http:
{%- endif %}
middlewares:
redirect:
# https://docs.traefik.io/master/middlewares/redirectscheme/
redirectScheme:
scheme: https
permanent: true
csrf:
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

View File

@ -7,6 +7,7 @@ from sentry_sdk.integrations.logging import LoggingIntegration
{%- if cookiecutter.use_celery == 'y' %}
from sentry_sdk.integrations.celery import CeleryIntegration
{% endif %}
from sentry_sdk.integrations.redis import RedisIntegration
{% endif -%}
from .base import * # noqa
@ -351,9 +352,9 @@ sentry_logging = LoggingIntegration(
)
{%- if cookiecutter.use_celery == 'y' %}
integrations = [sentry_logging, DjangoIntegration(), CeleryIntegration()]
integrations = [sentry_logging, DjangoIntegration(), CeleryIntegration(), RedisIntegration()]
{% else %}
integrations = [sentry_logging, DjangoIntegration()]
integrations = [sentry_logging, DjangoIntegration(), RedisIntegration()]
{% endif -%}
sentry_sdk.init(

View File

@ -5,7 +5,7 @@
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build -c .
SOURCEDIR = ./_source
SOURCEDIR = .
BUILDDIR = ./_build
{%- if cookiecutter.use_docker == 'y' %}
APP = /app

View File

@ -14,11 +14,19 @@ import os
import sys
import django
{% if cookiecutter.use_docker == 'y' %}
sys.path.insert(0, os.path.abspath("/app"))
os.environ.setdefault("DATABASE_URL", "")
{% else %}
sys.path.insert(0, os.path.abspath(".."))
if os.getenv("READTHEDOCS", default=False) == "True":
sys.path.insert(0, os.path.abspath(".."))
os.environ["DJANGO_READ_DOT_ENV_FILE"] = "True"
os.environ["USE_DOCKER"] = "no"
else:
{%- if cookiecutter.use_docker == 'y' %}
sys.path.insert(0, os.path.abspath("/app"))
{%- else %}
sys.path.insert(0, os.path.abspath(".."))
{%- endif %}
os.environ["DATABASE_URL"] = "sqlite:///readthedocs.db"
{%- if cookiecutter.use_celery == 'y' %}
os.environ["CELERY_BROKER_URL"] = os.getenv("REDIS_URL", "redis://redis:6379")
{%- endif %}
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
django.setup()

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

View File

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

View File

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

Before

Width:  |  Height:  |  Size: 249 KiB

After

Width:  |  Height:  |  Size: 249 KiB

View File

Before

Width:  |  Height:  |  Size: 229 KiB

After

Width:  |  Height:  |  Size: 229 KiB

View File

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 230 KiB

View File

Before

Width:  |  Height:  |  Size: 222 KiB

After

Width:  |  Height:  |  Size: 222 KiB

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -51,7 +51,8 @@ services:
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
ports:
- "7000:7000"
command: /start-docs
{%- if cookiecutter.use_mailhog == 'y' %}
mailhog:

View File

@ -1,6 +1,6 @@
pytz==2020.1 # https://github.com/stub42/pytz
pytz==2020.5 # https://github.com/stub42/pytz
python-slugify==4.0.1 # https://github.com/un33k/python-slugify
Pillow==7.2.0 # https://github.com/python-pillow/Pillow
Pillow==8.1.0 # https://github.com/python-pillow/Pillow
{%- if cookiecutter.use_compressor == "y" %}
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
rcssmin==1.0.6 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin
@ -18,28 +18,28 @@ hiredis==1.1.0 # https://github.com/redis/hiredis-py
{%- endif %}
{%- if cookiecutter.use_celery == "y" %}
celery==4.4.6 # pyup: < 5.0,!=4.4.7 # https://github.com/celery/celery
django-celery-beat==2.0.0 # https://github.com/celery/django-celery-beat
django-celery-beat==2.2.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %}
flower==0.9.5 # https://github.com/mher/flower
flower==0.9.7 # https://github.com/mher/flower
{%- endif %}
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
uvicorn==0.12.1 # https://github.com/encode/uvicorn
uvicorn[standard]==0.13.3 # https://github.com/encode/uvicorn
{%- endif %}
# Django
# ------------------------------------------------------------------------------
django==3.0.10 # pyup: < 3.1 # https://www.djangoproject.com/
django==3.0.11 # pyup: < 3.1 # https://www.djangoproject.com/
django-environ==0.4.5 # https://github.com/joke2k/django-environ
django-model-utils==4.0.0 # https://github.com/jazzband/django-model-utils
django-allauth==0.42.0 # https://github.com/pennersr/django-allauth
django-crispy-forms==1.9.2 # https://github.com/django-crispy-forms/django-crispy-forms
django-model-utils==4.1.1 # https://github.com/jazzband/django-model-utils
django-allauth==0.44.0 # https://github.com/pennersr/django-allauth
django-crispy-forms==1.10.0 # https://github.com/django-crispy-forms/django-crispy-forms
{%- if cookiecutter.use_compressor == "y" %}
django-compressor==2.4 # https://github.com/django-compressor/django-compressor
{%- endif %}
django-redis==4.12.1 # https://github.com/jazzband/django-redis
{%- if cookiecutter.use_drf == "y" %}
# Django REST Framework
djangorestframework==3.12.1 # https://github.com/encode/django-rest-framework
django-cors-headers==3.5.0 # https://github.com/adamchainz/django-cors-headers
djangorestframework==3.12.2 # https://github.com/encode/django-rest-framework
django-cors-headers==3.6.0 # https://github.com/adamchainz/django-cors-headers
{%- endif %}

View File

@ -7,39 +7,39 @@ psycopg2==2.8.6 # https://github.com/psycopg/psycopg2
{%- else %}
psycopg2-binary==2.8.6 # https://github.com/psycopg/psycopg2
{%- endif %}
{%- if cookiecutter.use_async == 'y' %}
{%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %}
watchgod==0.6 # https://github.com/samuelcolvin/watchgod
{%- endif %}
# Testing
# ------------------------------------------------------------------------------
mypy==0.782 # https://github.com/python/mypy
django-stubs==1.6.0 # https://github.com/typeddjango/django-stubs
pytest==6.1.1 # https://github.com/pytest-dev/pytest
mypy==0.800 # https://github.com/python/mypy
django-stubs==1.7.0 # https://github.com/typeddjango/django-stubs
pytest==6.2.1 # https://github.com/pytest-dev/pytest
pytest-sugar==0.9.4 # https://github.com/Frozenball/pytest-sugar
# Documentation
# ------------------------------------------------------------------------------
sphinx==3.2.1 # https://github.com/sphinx-doc/sphinx
sphinx==3.4.3 # https://github.com/sphinx-doc/sphinx
sphinx-autobuild==2020.9.1 # https://github.com/GaretJax/sphinx-autobuild
# Code quality
# ------------------------------------------------------------------------------
flake8==3.8.4 # https://github.com/PyCQA/flake8
flake8-isort==4.0.0 # https://github.com/gforcada/flake8-isort
coverage==5.3 # https://github.com/nedbat/coveragepy
coverage==5.3.1 # https://github.com/nedbat/coveragepy
black==20.8b1 # https://github.com/ambv/black
pylint-django==2.3.0 # https://github.com/PyCQA/pylint-django
pylint-django==2.4.2 # https://github.com/PyCQA/pylint-django
{%- if cookiecutter.use_celery == 'y' %}
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
{%- endif %}
pre-commit==2.7.1 # https://github.com/pre-commit/pre-commit
pre-commit==2.9.3 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
factory-boy==3.0.1 # https://github.com/FactoryBoy/factory_boy
factory-boy==3.2.0 # https://github.com/FactoryBoy/factory_boy
django-debug-toolbar==3.1.1 # https://github.com/jazzband/django-debug-toolbar
django-extensions==3.0.9 # https://github.com/django-extensions/django-extensions
django-debug-toolbar==3.2 # https://github.com/jazzband/django-debug-toolbar
django-extensions==3.1.0 # https://github.com/django-extensions/django-extensions
django-coverage-plugin==1.8.0 # https://github.com/nedbat/django_coverage_plugin
pytest-django==3.10.0 # https://github.com/pytest-dev/pytest-django
pytest-django==4.1.0 # https://github.com/pytest-dev/pytest-django

View File

@ -8,7 +8,7 @@ psycopg2==2.8.6 # https://github.com/psycopg/psycopg2
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %}
{%- if cookiecutter.use_sentry == "y" %}
sentry-sdk==0.18.0 # https://github.com/getsentry/sentry-python
sentry-sdk==0.19.5 # https://github.com/getsentry/sentry-python
{%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
hiredis==1.1.0 # https://github.com/redis/hiredis-py
@ -17,26 +17,26 @@ hiredis==1.1.0 # https://github.com/redis/hiredis-py
# Django
# ------------------------------------------------------------------------------
{%- if cookiecutter.cloud_provider == 'AWS' %}
django-storages[boto3]==1.10.1 # https://github.com/jschneier/django-storages
django-storages[boto3]==1.11.1 # https://github.com/jschneier/django-storages
{%- elif cookiecutter.cloud_provider == 'GCP' %}
django-storages[google]==1.10.1 # https://github.com/jschneier/django-storages
django-storages[google]==1.11.1 # https://github.com/jschneier/django-storages
{%- endif %}
{%- if cookiecutter.mail_service == 'Mailgun' %}
django-anymail[mailgun]==8.0 # https://github.com/anymail/django-anymail
django-anymail[mailgun]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Amazon SES' %}
django-anymail[amazon_ses]==8.0 # https://github.com/anymail/django-anymail
django-anymail[amazon_ses]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mailjet' %}
django-anymail[mailjet]==8.0 # https://github.com/anymail/django-anymail
django-anymail[mailjet]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Mandrill' %}
django-anymail[mandrill]==8.0 # https://github.com/anymail/django-anymail
django-anymail[mandrill]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Postmark' %}
django-anymail[postmark]==8.0 # https://github.com/anymail/django-anymail
django-anymail[postmark]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Sendgrid' %}
django-anymail[sendgrid]==8.0 # https://github.com/anymail/django-anymail
django-anymail[sendgrid]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SendinBlue' %}
django-anymail[sendinblue]==8.0 # https://github.com/anymail/django-anymail
django-anymail[sendinblue]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'SparkPost' %}
django-anymail[sparkpost]==8.0 # https://github.com/anymail/django-anymail
django-anymail[sparkpost]==8.1 # https://github.com/anymail/django-anymail
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
django-anymail==8.0 # https://github.com/anymail/django-anymail
django-anymail==8.1 # https://github.com/anymail/django-anymail
{%- endif %}

View File

@ -1 +1 @@
python-3.8.5
python-3.8.7

View File

@ -59,20 +59,20 @@
{% endblock %}
{% block javascript %}
{% block inline_javascript %}
{{ block.super }}
<script type="text/javascript">
(function() {
var message = "{% trans 'Do you really want to remove the selected e-mail address?' %}";
var actions = document.getElementsByName('action_remove');
window.addEventListener('DOMContentLoaded',function() {
const message = "{% trans 'Do you really want to remove the selected e-mail address?' %}";
const actions = document.getElementsByName('action_remove');
if (actions.length) {
actions[0].addEventListener("click", function(e) {
if (! confirm(message)) {
if (!confirm(message)) {
e.preventDefault();
}
});
}
})();
});
$('.form-group').removeClass('row');
</script>

View File

@ -31,6 +31,30 @@
{% endraw %}{% endif %}{% raw %}
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock %}
<!-- Le javascript
================================================== -->
{# Placed at the top of the document so pages load faster with defer #}
{% block javascript %}
{% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "y" and cookiecutter.js_task_runner == "Gulp" %}{% raw %}
<!-- Vendor dependencies bundled as one file-->
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
<script defer src="{% static 'js/vendors.js' %}"></script>
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endraw %}{% else %}{% raw %}
<!-- Bootstrap JS and its dependencies-->
<script defer src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script defer src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<!-- Your stuff: Third-party javascript libraries go here -->
{% endraw %}{% endif %}{% raw %}
<!-- place project specific Javascript in this file -->
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
<script defer src="{% static 'js/project.js' %}"></script>
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock javascript %}
</head>
@ -92,30 +116,9 @@
{% block modal %}{% endblock modal %}
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
{% block javascript %}
{% endraw %}{% if cookiecutter.custom_bootstrap_compilation == "y" and cookiecutter.js_task_runner == "Gulp" %}{% raw %}
<!-- Vendor dependencies bundled as one file-->
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
<script src="{% static 'js/vendors.js' %}"></script>
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endraw %}{% else %}{% raw %}
<!-- Bootstrap JS and its dependencies-->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<!-- Your stuff: Third-party javascript libraries go here -->
{% endraw %}{% endif %}{% raw %}
<!-- place project specific Javascript in this file -->
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% compress js %}{% endraw %}{% endif %}{% raw %}
<script src="{% static 'js/project.js' %}"></script>
{% endraw %}{% if cookiecutter.use_compressor == "y" %}{% raw %}{% endcompress %}{% endraw %}{% endif %}{% raw %}
{% endblock javascript %}
{% block inline_javascript %}
{# Script tags with only code, no src (defer by default) #}
{% endblock inline_javascript %}
</body>
</html>
{% endraw %}

View File

@ -53,18 +53,6 @@ class Migration(migrations.Migration):
verbose_name="username",
),
),
(
"first_name",
models.CharField(
blank=True, max_length=30, verbose_name="first name"
),
),
(
"last_name",
models.CharField(
blank=True, max_length=150, verbose_name="last name"
),
),
(
"email",
models.EmailField(

View File

@ -9,6 +9,8 @@ class User(AbstractUser):
#: First and last name do not cover name patterns around the globe
name = CharField(_("Name of User"), blank=True, max_length=255)
first_name = None # type: ignore
last_name = None # type: ignore
def get_absolute_url(self):
"""Get url for user's detail view.

View File

@ -23,7 +23,7 @@ class UserFactory(DjangoModelFactory):
digits=True,
upper_case=True,
lower_case=True,
).generate(extra_kwargs={})
).evaluate(None, None, extra={"locale": None})
)
self.set_password(password)

View File

@ -1,8 +1,12 @@
import pytest
from django.contrib import messages
from django.contrib.auth.models import AnonymousUser
from django.contrib.messages.middleware import MessageMiddleware
from django.contrib.sessions.middleware import SessionMiddleware
from django.http.response import Http404
from django.test import RequestFactory
from {{ cookiecutter.project_slug }}.users.forms import UserChangeForm
from {{ cookiecutter.project_slug }}.users.models import User
from {{ cookiecutter.project_slug }}.users.tests.factories import UserFactory
from {{ cookiecutter.project_slug }}.users.views import (
@ -41,6 +45,25 @@ class TestUserUpdateView:
assert view.get_object() == user
def test_form_valid(self, user: User, rf: RequestFactory):
view = UserUpdateView()
request = rf.get("/fake-url/")
# Add the session/message middleware to the request
SessionMiddleware().process_request(request)
MessageMiddleware().process_request(request)
request.user = user
view.request = request
# Initialize the form
form = UserChangeForm()
form.cleaned_data = []
view.form_valid(form)
messages_sent = [m.message for m in messages.get_messages(request)]
assert messages_sent == ["Information successfully updated"]
class TestUserRedirectView:
def test_get_redirect_url(self, user: User, rf: RequestFactory):

View File

@ -27,11 +27,11 @@ class UserUpdateView(LoginRequiredMixin, UpdateView):
return reverse("users:detail", kwargs={"username": self.request.user.username})
def get_object(self):
return User.objects.get(username=self.request.user.username)
return self.request.user
def form_valid(self, form):
messages.add_message(
self.request, messages.INFO, _("Infos successfully updated")
self.request, messages.INFO, _("Information successfully updated")
)
return super().form_valid(form)