mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-08-09 14:34:53 +03:00
Merge branch 'cookiecutter:master' into main
This commit is contained in:
commit
1577d206b0
4
.github/CONTRIBUTORS-template.md
vendored
4
.github/CONTRIBUTORS-template.md
vendored
|
@ -22,8 +22,8 @@ accept and merge pull requests.
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
*Audrey is also the creator of Cookiecutter. Audrey and Daniel are on
|
_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on
|
||||||
the Cookiecutter core team.*
|
the Cookiecutter core team._
|
||||||
|
|
||||||
## Other Contributors
|
## Other Contributors
|
||||||
|
|
||||||
|
|
9
.github/FUNDING.yml
vendored
9
.github/FUNDING.yml
vendored
|
@ -2,11 +2,4 @@
|
||||||
|
|
||||||
github: [pydanny, browniebroke]
|
github: [pydanny, browniebroke]
|
||||||
patreon: feldroy
|
patreon: feldroy
|
||||||
open_collective: # Replace with a single Open Collective username
|
open_collective: cookiecutter-django
|
||||||
ko_fi: # Replace with a single Ko-fi username
|
|
||||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
||||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
||||||
liberapay: # Replace with a single Liberapay username
|
|
||||||
issuehunt: # Replace with a single IssueHunt username
|
|
||||||
otechie: # Replace with a single Otechie username
|
|
||||||
custom: ["https://www.patreon.com/browniebroke"]
|
|
||||||
|
|
32
.github/ISSUE_TEMPLATE/bug.md
vendored
32
.github/ISSUE_TEMPLATE/bug.md
vendored
|
@ -12,41 +12,47 @@ labels: bug
|
||||||
|
|
||||||
<!-- To assist you best, please include commands that you've run, options you've selected and any relevant logs -->
|
<!-- To assist you best, please include commands that you've run, options you've selected and any relevant logs -->
|
||||||
|
|
||||||
* Host system configuration:
|
- Host system configuration:
|
||||||
* Version of cookiecutter CLI (get it with `cookiecutter --version`):
|
|
||||||
* OS name and version:
|
- Version of cookiecutter CLI (get it with `cookiecutter --version`):
|
||||||
|
- OS name and version:
|
||||||
|
|
||||||
On Linux, run
|
On Linux, run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
lsb_release -a 2> /dev/null || cat /etc/redhat-release 2> /dev/null || cat /etc/*-release 2> /dev/null || cat /etc/issue 2> /dev/null
|
lsb_release -a 2> /dev/null || cat /etc/redhat-release 2> /dev/null || cat /etc/*-release 2> /dev/null || cat /etc/issue 2> /dev/null
|
||||||
```
|
```
|
||||||
|
|
||||||
On MacOs, run
|
On MacOs, run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sw_vers
|
sw_vers
|
||||||
```
|
```
|
||||||
|
|
||||||
On Windows, via CMD, run
|
On Windows, via CMD, run
|
||||||
|
|
||||||
```
|
```
|
||||||
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
|
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Insert here the OS name and version
|
# Insert here the OS name and version
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
* Python version, run `python3 -V`:
|
- Python version, run `python3 -V`:
|
||||||
* Docker version (if using Docker), run `docker --version`:
|
- Docker version (if using Docker), run `docker --version`:
|
||||||
* docker-compose version (if using Docker), run `docker-compose --version`:
|
- docker-compose version (if using Docker), run `docker-compose --version`:
|
||||||
* ...
|
- ...
|
||||||
* Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html):
|
|
||||||
On Linux and MacOS: `cat ${HOME}/.cookiecutter_replay/cookiecutter-django.json`
|
- Options selected and/or [replay file](https://cookiecutter.readthedocs.io/en/latest/advanced/replay.html):
|
||||||
|
On Linux and macOS: `cat ${HOME}/.cookiecutter_replay/cookiecutter-django.json`
|
||||||
(Please, take care to remove sensitive information)
|
(Please, take care to remove sensitive information)
|
||||||
```json
|
|
||||||
# Insert here the replay file content
|
```json
|
||||||
```
|
|
||||||
|
```
|
||||||
|
|
||||||
<summary>
|
<summary>
|
||||||
Logs:
|
Logs:
|
||||||
<details>
|
<details>
|
||||||
|
|
6
.github/ISSUE_TEMPLATE/paid-support.md
vendored
6
.github/ISSUE_TEMPLATE/paid-support.md
vendored
|
@ -5,8 +5,8 @@ about: Ask Core Team members to help you out
|
||||||
|
|
||||||
Provided your question goes beyond [regular support](https://github.com/cookiecutter/cookiecutter-django/issues/new?template=question.md), and/or the task at hand is of timely/high priority nature use the below information to reach out for contributors directly.
|
Provided your question goes beyond [regular support](https://github.com/cookiecutter/cookiecutter-django/issues/new?template=question.md), and/or the task at hand is of timely/high priority nature use the below information to reach out for contributors directly.
|
||||||
|
|
||||||
* Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB.
|
- Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)).
|
||||||
|
|
||||||
* Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience.
|
- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB.
|
||||||
|
|
||||||
* Bruno Alla, Core Developer ([GitHub](https://github.com/sponsors/browniebroke)).
|
- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience.
|
||||||
|
|
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -1,6 +1,5 @@
|
||||||
<!-- Thank you for helping us out: your efforts mean a great deal to the project and the community as a whole! -->
|
<!-- Thank you for helping us out: your efforts mean a great deal to the project and the community as a whole! -->
|
||||||
|
|
||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
<!-- What's it you're proposing? -->
|
<!-- What's it you're proposing? -->
|
||||||
|
|
9
.github/changelog-template.md
vendored
9
.github/changelog-template.md
vendored
|
@ -1,8 +1,11 @@
|
||||||
{%- for change_type, pulls in grouped_pulls.items() %}
|
{%- for change_type, pulls in grouped_pulls.items() %}
|
||||||
{%- if pulls %}
|
{%- if pulls %}
|
||||||
|
|
||||||
### {{ change_type }}
|
### {{ change_type }}
|
||||||
|
|
||||||
{%- for pull_request in pulls %}
|
{%- for pull_request in pulls %}
|
||||||
|
|
||||||
- {{ pull_request.title }} ([#{{ pull_request.number }}]({{ pull_request.html_url }}))
|
- {{ pull_request.title }} ([#{{ pull_request.number }}]({{ pull_request.html_url }}))
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{% endif -%}
|
{% endif -%}
|
||||||
{% endfor -%}
|
{% endfor -%}
|
||||||
|
|
71
.github/contributors.json
vendored
71
.github/contributors.json
vendored
|
@ -53,6 +53,12 @@
|
||||||
"twitter_username": "sfdye",
|
"twitter_username": "sfdye",
|
||||||
"is_core": true
|
"is_core": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Jelmer Draaijer",
|
||||||
|
"github_login": "foarsitter",
|
||||||
|
"twitter_username": "",
|
||||||
|
"is_core": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "18",
|
"name": "18",
|
||||||
"github_login": "dezoito",
|
"github_login": "dezoito",
|
||||||
|
@ -553,11 +559,6 @@
|
||||||
"github_login": "jvanbrug",
|
"github_login": "jvanbrug",
|
||||||
"twitter_username": ""
|
"twitter_username": ""
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Jelmer Draaijer",
|
|
||||||
"github_login": "foarsitter",
|
|
||||||
"twitter_username": ""
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Jerome Caisip",
|
"name": "Jerome Caisip",
|
||||||
"github_login": "jeromecaisip",
|
"github_login": "jeromecaisip",
|
||||||
|
@ -1347,5 +1348,65 @@
|
||||||
"name": "Robin",
|
"name": "Robin",
|
||||||
"github_login": "Kaffeetasse",
|
"github_login": "Kaffeetasse",
|
||||||
"twitter_username": ""
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Patrick Tran",
|
||||||
|
"github_login": "theptrk",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tildebox",
|
||||||
|
"github_login": "tildebox",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "duffn",
|
||||||
|
"github_login": "duffn",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delphine LEMIRE",
|
||||||
|
"github_login": "DelphineLemire",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Hoai-Thu Vuong",
|
||||||
|
"github_login": "thuvh",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Arkadiusz Michał Ryś",
|
||||||
|
"github_login": "arrys",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "mpsantos",
|
||||||
|
"github_login": "mpsantos",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Morten Kaae",
|
||||||
|
"github_login": "MortenKaae",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Birtibu",
|
||||||
|
"github_login": "Birtibu",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Matheus Jardim Bernardes",
|
||||||
|
"github_login": "matheusjardimb",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "masavini",
|
||||||
|
"github_login": "masavini",
|
||||||
|
"twitter_username": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Joseph Hanna",
|
||||||
|
"github_login": "sanchimenea",
|
||||||
|
"twitter_username": ""
|
||||||
}
|
}
|
||||||
]
|
]
|
68
.github/dependabot.yml
vendored
68
.github/dependabot.yml
vendored
|
@ -18,3 +18,71 @@ updates:
|
||||||
interval: "daily"
|
interval: "daily"
|
||||||
labels:
|
labels:
|
||||||
- "update"
|
- "update"
|
||||||
|
|
||||||
|
# Enable version updates for Docker
|
||||||
|
# We need to specify each Dockerfile in a separate entry because Dependabot doesn't
|
||||||
|
# support wildcards or recursively checking subdirectories. Check this issue for updates:
|
||||||
|
# https://github.com/dependabot/dependabot-core/issues/2178
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/local/django/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
ignore:
|
||||||
|
- dependency-name: "*"
|
||||||
|
update-types:
|
||||||
|
- "version-update:semver-major"
|
||||||
|
- "version-update:semver-minor"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/local/docs/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
ignore:
|
||||||
|
- dependency-name: "*"
|
||||||
|
update-types:
|
||||||
|
- "version-update:semver-major"
|
||||||
|
- "version-update:semver-minor"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/local/node/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/production/aws/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/production/django/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
ignore:
|
||||||
|
- dependency-name: "*"
|
||||||
|
update-types:
|
||||||
|
- "version-update:semver-major"
|
||||||
|
- "version-update:semver-minor"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/production/postgres/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
||||||
|
- package-ecosystem: "docker"
|
||||||
|
directory: "{{cookiecutter.project_slug}}/compose/production/traefik/"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
labels:
|
||||||
|
- "update"
|
||||||
|
|
48
.github/workflows/ci.yml
vendored
48
.github/workflows/ci.yml
vendored
|
@ -2,6 +2,7 @@ name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
branches: ["master", "main"]
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
|
@ -9,17 +10,6 @@ concurrency:
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: actions/setup-python@v4
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
cache: pip
|
|
||||||
- name: Run pre-commit
|
|
||||||
uses: pre-commit/action@v3.0.0
|
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
@ -29,18 +19,18 @@ jobs:
|
||||||
- windows-latest
|
- windows-latest
|
||||||
- macOS-latest
|
- macOS-latest
|
||||||
|
|
||||||
name: "Run tests"
|
name: "pytest ${{ matrix.os }}"
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
cache: pip
|
cache: pip
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: pytest tests
|
run: pytest -n auto tests
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
strategy:
|
strategy:
|
||||||
|
@ -48,11 +38,15 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
script:
|
script:
|
||||||
- name: Basic
|
- name: Basic
|
||||||
args: ""
|
args: "ci_tool=Gitlab"
|
||||||
- name: Extended
|
- name: Celery & DRF
|
||||||
args: "use_celery=y use_drf=y frontend_pipeline=Gulp"
|
args: "use_celery=y use_drf=y"
|
||||||
|
- name: Gulp
|
||||||
|
args: "frontend_pipeline=Gulp"
|
||||||
|
- name: Webpack
|
||||||
|
args: "frontend_pipeline=Webpack"
|
||||||
|
|
||||||
name: "${{ matrix.script.name }} Docker"
|
name: "Docker ${{ matrix.script.name }}"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
DOCKER_BUILDKIT: 1
|
DOCKER_BUILDKIT: 1
|
||||||
|
@ -62,7 +56,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
cache: pip
|
cache: pip
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
|
@ -74,12 +68,16 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
script:
|
script:
|
||||||
- name: With Celery
|
- name: Celery
|
||||||
args: "use_celery=y frontend_pipeline='Django Compressor'"
|
args: "use_celery=y frontend_pipeline='Django Compressor'"
|
||||||
- name: With Gulp
|
- name: Gulp
|
||||||
args: "frontend_pipeline='Gulp'"
|
args: "frontend_pipeline=Gulp"
|
||||||
|
- name: Webpack
|
||||||
|
args: "frontend_pipeline=Webpack use_heroku=y"
|
||||||
|
- name: Email Username
|
||||||
|
args: "username_type=email ci_tool=Github"
|
||||||
|
|
||||||
name: "${{ matrix.script.name }} Bare metal"
|
name: "Bare metal ${{ matrix.script.name }}"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
@ -102,7 +100,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
requirements.txt
|
requirements.txt
|
||||||
|
@ -112,6 +110,6 @@ jobs:
|
||||||
run: pip install -r requirements.txt
|
run: pip install -r requirements.txt
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: "18"
|
||||||
- name: Bare Metal ${{ matrix.script.name }}
|
- name: Bare Metal ${{ matrix.script.name }}
|
||||||
run: sh tests/test_bare.sh ${{ matrix.script.args }}
|
run: sh tests/test_bare.sh ${{ matrix.script.args }}
|
||||||
|
|
2
.github/workflows/django-issue-checker.yml
vendored
2
.github/workflows/django-issue-checker.yml
vendored
|
@ -19,7 +19,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
|
|
4
.github/workflows/pre-commit-autoupdate.yml
vendored
4
.github/workflows/pre-commit-autoupdate.yml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-python@v4
|
- uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
|
|
||||||
- name: Install pre-commit
|
- name: Install pre-commit
|
||||||
run: pip install pre-commit
|
run: pip install pre-commit
|
||||||
|
@ -37,7 +37,7 @@ jobs:
|
||||||
run: pre-commit autoupdate
|
run: pre-commit autoupdate
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@v4
|
uses: peter-evans/create-pull-request@v5
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
branch: update/pre-commit-autoupdate
|
branch: update/pre-commit-autoupdate
|
||||||
|
|
2
.github/workflows/update-changelog.yml
vendored
2
.github/workflows/update-changelog.yml
vendored
|
@ -19,7 +19,7 @@ jobs:
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
|
|
2
.github/workflows/update-contributors.yml
vendored
2
.github/workflows/update-contributors.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v4
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.11"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
exclude: "{{cookiecutter.project_slug}}"
|
exclude: "{{cookiecutter.project_slug}}|.github/contributors.json|CHANGELOG.md|CONTRIBUTORS.md"
|
||||||
default_stages: [commit]
|
default_stages: [commit]
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
|
@ -6,22 +6,36 @@ repos:
|
||||||
rev: v4.4.0
|
rev: v4.4.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: check-json
|
||||||
|
- id: check-toml
|
||||||
|
- id: check-xml
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
- id: debug-statements
|
||||||
|
- id: check-builtin-literals
|
||||||
|
- id: check-case-conflict
|
||||||
|
- id: detect-private-key
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
|
rev: "v3.0.0-alpha.9-for-vscode"
|
||||||
|
hooks:
|
||||||
|
- id: prettier
|
||||||
|
args: ["--tab-width", "2"]
|
||||||
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.3.1
|
rev: v3.8.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py310-plus]
|
args: [--py311-plus]
|
||||||
exclude: hooks/
|
exclude: hooks/
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.12.0
|
rev: 23.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.11.4
|
rev: 5.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,17 @@
|
||||||
# Required
|
# Required
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
|
# Set the version of Python and other tools you might need
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
tools:
|
||||||
|
python: "3.11"
|
||||||
|
|
||||||
# Build documentation in the docs/ directory with Sphinx
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
sphinx:
|
sphinx:
|
||||||
configuration: docs/conf.py
|
configuration: docs/conf.py
|
||||||
|
|
||||||
# Version of Python and requirements required to build the docs
|
# Declare the Python requirements required to build your docs
|
||||||
python:
|
python:
|
||||||
version: "3.8"
|
|
||||||
install:
|
install:
|
||||||
- requirements: docs/requirements.txt
|
- requirements: docs/requirements.txt
|
||||||
|
|
770
CHANGELOG.md
770
CHANGELOG.md
|
@ -3,6 +3,776 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
|
||||||
|
|
||||||
<!-- GENERATOR_PLACEHOLDER -->
|
<!-- GENERATOR_PLACEHOLDER -->
|
||||||
|
|
||||||
|
## 2023.07.04
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Add PostgreSQL 15 ([#4431](https://github.com/cookiecutter/cookiecutter-django/pull/4431))
|
||||||
|
|
||||||
|
- [pre-commit.ci] pre-commit autoupdate ([#4438](https://github.com/cookiecutter/cookiecutter-django/pull/4438))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.27.0 ([#4439](https://github.com/cookiecutter/cookiecutter-django/pull/4439))
|
||||||
|
|
||||||
|
- Update postcss-preset-env to 9.0.0 ([#4437](https://github.com/cookiecutter/cookiecutter-django/pull/4437))
|
||||||
|
|
||||||
|
## 2023.07.03
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Add a devcontainer configuration with Docker ([#4198](https://github.com/cookiecutter/cookiecutter-django/pull/4198))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update django-stubs to 4.2.3 ([#4430](https://github.com/cookiecutter/cookiecutter-django/pull/4430))
|
||||||
|
|
||||||
|
- Update django to 4.2.3 ([#4435](https://github.com/cookiecutter/cookiecutter-django/pull/4435))
|
||||||
|
|
||||||
|
## 2023.06.30
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Add option to use django-allauth workflow in the admin ([#1921](https://github.com/cookiecutter/cookiecutter-django/pull/1921))
|
||||||
|
|
||||||
|
## 2023.06.29
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Replace psycopg2 by psycopg3 ([#4421](https://github.com/cookiecutter/cookiecutter-django/pull/4421))
|
||||||
|
|
||||||
|
## 2023.06.28
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgrade to django 4.2 ([#4393](https://github.com/cookiecutter/cookiecutter-django/pull/4393))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix PostgreSQL version in GitHub workflow ([#4423](https://github.com/cookiecutter/cookiecutter-django/pull/4423))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.6 ([#4427](https://github.com/cookiecutter/cookiecutter-django/pull/4427))
|
||||||
|
|
||||||
|
- Update django-compressor to 4.4 ([#4422](https://github.com/cookiecutter/cookiecutter-django/pull/4422))
|
||||||
|
|
||||||
|
## 2023.06.27
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Populate User `name` field during social auth ([#3968](https://github.com/cookiecutter/cookiecutter-django/pull/3968))
|
||||||
|
|
||||||
|
- Add djLint for HTML formatting and linting ([#4389](https://github.com/cookiecutter/cookiecutter-django/pull/4389))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Only include prettier pre-commit hook with node-based front-end pipeline ([#4418](https://github.com/cookiecutter/cookiecutter-django/pull/4418))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update djangorestframework-stubs to 3.14.2 ([#4420](https://github.com/cookiecutter/cookiecutter-django/pull/4420))
|
||||||
|
|
||||||
|
- Update django-stubs to 4.2.2 ([#4419](https://github.com/cookiecutter/cookiecutter-django/pull/4419))
|
||||||
|
|
||||||
|
## 2023.06.26
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update pytest to 7.4.0 ([#4412](https://github.com/cookiecutter/cookiecutter-django/pull/4412))
|
||||||
|
|
||||||
|
- Update redis to 4.6.0 ([#4415](https://github.com/cookiecutter/cookiecutter-django/pull/4415))
|
||||||
|
|
||||||
|
- Update mypy to 1.4.1 ([#4416](https://github.com/cookiecutter/cookiecutter-django/pull/4416))
|
||||||
|
|
||||||
|
## 2023.06.22
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update pygithub to 1.59.0 ([#4410](https://github.com/cookiecutter/cookiecutter-django/pull/4410))
|
||||||
|
|
||||||
|
- Update drf-spectacular to 0.26.3 ([#4411](https://github.com/cookiecutter/cookiecutter-django/pull/4411))
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.26.0 ([#4409](https://github.com/cookiecutter/cookiecutter-django/pull/4409))
|
||||||
|
|
||||||
|
## 2023.06.21
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Upgrade traefik to 2.10.3 ([#4408](https://github.com/cookiecutter/cookiecutter-django/pull/4408))
|
||||||
|
|
||||||
|
## 2023.06.19
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4405](https://github.com/cookiecutter/cookiecutter-django/pull/4405))
|
||||||
|
|
||||||
|
- Update celery to 5.3.1 ([#4404](https://github.com/cookiecutter/cookiecutter-django/pull/4404))
|
||||||
|
|
||||||
|
## 2023.06.18
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix missing celery env variable when running compilemessages ([#4403](https://github.com/cookiecutter/cookiecutter-django/pull/4403))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update flower to 2.0.0 ([#4402](https://github.com/cookiecutter/cookiecutter-django/pull/4402))
|
||||||
|
|
||||||
|
## 2023.06.17
|
||||||
|
|
||||||
|
|
||||||
|
## 2023.06.16
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update whitenoise to 6.5.0 ([#4400](https://github.com/cookiecutter/cookiecutter-django/pull/4400))
|
||||||
|
|
||||||
|
- Update django-redis to 5.3.0 ([#4399](https://github.com/cookiecutter/cookiecutter-django/pull/4399))
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4395](https://github.com/cookiecutter/cookiecutter-django/pull/4395))
|
||||||
|
|
||||||
|
## 2023.06.14
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update django-cors-headers to 4.1.0 ([#4391](https://github.com/cookiecutter/cookiecutter-django/pull/4391))
|
||||||
|
|
||||||
|
- Update django-upgrade to 1.14.0 ([#4394](https://github.com/cookiecutter/cookiecutter-django/pull/4394))
|
||||||
|
|
||||||
|
- Update django-webpack-loader to 2.0.1 ([#4392](https://github.com/cookiecutter/cookiecutter-django/pull/4392))
|
||||||
|
|
||||||
|
- Update pre-commit to 3.3.3 ([#4390](https://github.com/cookiecutter/cookiecutter-django/pull/4390))
|
||||||
|
|
||||||
|
## 2023.06.11
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update pytest to 7.3.2 ([#4384](https://github.com/cookiecutter/cookiecutter-django/pull/4384))
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4385](https://github.com/cookiecutter/cookiecutter-django/pull/4385))
|
||||||
|
|
||||||
|
## 2023.06.09
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix missing `compilemessages` step before deploying to prod ([#4363](https://github.com/cookiecutter/cookiecutter-django/pull/4363))
|
||||||
|
|
||||||
|
## 2023.06.08
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix failure in user view test caused by translations ([#4374](https://github.com/cookiecutter/cookiecutter-django/pull/4374))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update to Python 3.11.4 in production Docker compose ([#4378](https://github.com/cookiecutter/cookiecutter-django/pull/4378))
|
||||||
|
|
||||||
|
- Update to Python 3.11.4 in docs Docker compose ([#4379](https://github.com/cookiecutter/cookiecutter-django/pull/4379))
|
||||||
|
|
||||||
|
- Update to Python 3.11.4 in local Docker compose ([#4380](https://github.com/cookiecutter/cookiecutter-django/pull/4380))
|
||||||
|
|
||||||
|
- Update celery to 5.3.0 ([#4369](https://github.com/cookiecutter/cookiecutter-django/pull/4369))
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.5 ([#4377](https://github.com/cookiecutter/cookiecutter-django/pull/4377))
|
||||||
|
|
||||||
|
## 2023.06.07
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Replace `runserver` with `runserver_plus` ([#4373](https://github.com/cookiecutter/cookiecutter-django/pull/4373))
|
||||||
|
|
||||||
|
- Add translations for Brazilian Portuguese ([#4367](https://github.com/cookiecutter/cookiecutter-django/pull/4367))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.25.1 ([#4376](https://github.com/cookiecutter/cookiecutter-django/pull/4376))
|
||||||
|
|
||||||
|
- Update django-extensions to 3.2.3 ([#4372](https://github.com/cookiecutter/cookiecutter-django/pull/4372))
|
||||||
|
|
||||||
|
- Update djangorestframework-stubs to 3.14.1 ([#4366](https://github.com/cookiecutter/cookiecutter-django/pull/4366))
|
||||||
|
|
||||||
|
- Update django-stubs to 4.2.1 ([#4365](https://github.com/cookiecutter/cookiecutter-django/pull/4365))
|
||||||
|
|
||||||
|
- Update mypy to 1.3.0 ([#4327](https://github.com/cookiecutter/cookiecutter-django/pull/4327))
|
||||||
|
|
||||||
|
## 2023.06.02
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.25.0 ([#4364](https://github.com/cookiecutter/cookiecutter-django/pull/4364))
|
||||||
|
|
||||||
|
## 2023.05.30
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update hiredis to 2.2.3 ([#4360](https://github.com/cookiecutter/cookiecutter-django/pull/4360))
|
||||||
|
|
||||||
|
- Update django-debug-toolbar to 4.1.0 ([#4359](https://github.com/cookiecutter/cookiecutter-django/pull/4359))
|
||||||
|
|
||||||
|
- Update redis to 4.5.5 ([#4358](https://github.com/cookiecutter/cookiecutter-django/pull/4358))
|
||||||
|
|
||||||
|
- Update django-anymail to 10.0 ([#4357](https://github.com/cookiecutter/cookiecutter-django/pull/4357))
|
||||||
|
|
||||||
|
- Update coverage to 7.2.7 ([#4356](https://github.com/cookiecutter/cookiecutter-django/pull/4356))
|
||||||
|
|
||||||
|
## 2023.05.28
|
||||||
|
|
||||||
|
|
||||||
|
## 2023.05.24
|
||||||
|
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Prevent Celery restarts on media file changes ([#4352](https://github.com/cookiecutter/cookiecutter-django/pull/4352))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update coverage to 7.2.6 ([#4351](https://github.com/cookiecutter/cookiecutter-django/pull/4351))
|
||||||
|
|
||||||
|
## 2023.05.23
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix compatibility webpack-bundle-tracker>=2.0.0 js library required after upgrade django-webpack-loader>=2.0.0 ([#4350](https://github.com/cookiecutter/cookiecutter-django/pull/4350))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sphinx-rtd-theme to 1.2.1 ([#4348](https://github.com/cookiecutter/cookiecutter-django/pull/4348))
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.24.0 ([#4349](https://github.com/cookiecutter/cookiecutter-django/pull/4349))
|
||||||
|
|
||||||
|
- Bump webpack-bundle-tracker from 1.8.1 to 2.0.0 in /{{cookiecutter.project_slug}} ([#4347](https://github.com/cookiecutter/cookiecutter-django/pull/4347))
|
||||||
|
|
||||||
|
- Update django-webpack-loader to 2.0.0 ([#4345](https://github.com/cookiecutter/cookiecutter-django/pull/4345))
|
||||||
|
|
||||||
|
- Update pytest-xdist to 3.3.1 ([#4344](https://github.com/cookiecutter/cookiecutter-django/pull/4344))
|
||||||
|
|
||||||
|
- Update requests to 2.31.0 ([#4346](https://github.com/cookiecutter/cookiecutter-django/pull/4346))
|
||||||
|
|
||||||
|
## 2023.05.18
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update pre-commit to 3.3.2 ([#4342](https://github.com/cookiecutter/cookiecutter-django/pull/4342))
|
||||||
|
|
||||||
|
## 2023.05.17
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.23.1 ([#4341](https://github.com/cookiecutter/cookiecutter-django/pull/4341))
|
||||||
|
|
||||||
|
## 2023.05.15
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update django-cors-headers to 4.0.0 ([#4329](https://github.com/cookiecutter/cookiecutter-django/pull/4329))
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.23.0 ([#4337](https://github.com/cookiecutter/cookiecutter-django/pull/4337))
|
||||||
|
|
||||||
|
## 2023.05.09
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.4 ([#4325](https://github.com/cookiecutter/cookiecutter-django/pull/4325))
|
||||||
|
|
||||||
|
## 2023.05.08
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4320](https://github.com/cookiecutter/cookiecutter-django/pull/4320))
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.22.2 ([#4321](https://github.com/cookiecutter/cookiecutter-django/pull/4321))
|
||||||
|
|
||||||
|
## 2023.05.04
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Remove pytz from dependencies ([#4309](https://github.com/cookiecutter/cookiecutter-django/pull/4309))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update django-anymail to 9.2 ([#4316](https://github.com/cookiecutter/cookiecutter-django/pull/4316))
|
||||||
|
|
||||||
|
- Update pre-commit to 3.3.1 ([#4315](https://github.com/cookiecutter/cookiecutter-django/pull/4315))
|
||||||
|
|
||||||
|
- Update coverage to 7.2.5 ([#4314](https://github.com/cookiecutter/cookiecutter-django/pull/4314))
|
||||||
|
|
||||||
|
- Update django to 4.1.9 ([#4313](https://github.com/cookiecutter/cookiecutter-django/pull/4313))
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.21.1 ([#4312](https://github.com/cookiecutter/cookiecutter-django/pull/4312))
|
||||||
|
|
||||||
|
- Update requests to 2.30.0 ([#4311](https://github.com/cookiecutter/cookiecutter-django/pull/4311))
|
||||||
|
|
||||||
|
## 2023.05.02
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Upgrade traefik to 2.10.1 ([#4304](https://github.com/cookiecutter/cookiecutter-django/pull/4304))
|
||||||
|
|
||||||
|
- Update uvicorn to 0.22.0 ([#4305](https://github.com/cookiecutter/cookiecutter-django/pull/4305))
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.3 ([#4307](https://github.com/cookiecutter/cookiecutter-django/pull/4307))
|
||||||
|
|
||||||
|
## 2023.04.28
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Add django-upgrade to pre-commit hooks ([#4298](https://github.com/cookiecutter/cookiecutter-django/pull/4298))
|
||||||
|
|
||||||
|
## 2023.04.27
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update djangorestframework-stubs to 3.14.0 ([#4303](https://github.com/cookiecutter/cookiecutter-django/pull/4303))
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.1 ([#4302](https://github.com/cookiecutter/cookiecutter-django/pull/4302))
|
||||||
|
|
||||||
|
- Update django-stubs to 4.2.0 ([#4301](https://github.com/cookiecutter/cookiecutter-django/pull/4301))
|
||||||
|
|
||||||
|
## 2023.04.26
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Upgrade cssnano to v6.0.0 ([#4233](https://github.com/cookiecutter/cookiecutter-django/pull/4233))
|
||||||
|
|
||||||
|
- Upgrade concurrently to 8.0.1 ([#4237](https://github.com/cookiecutter/cookiecutter-django/pull/4237))
|
||||||
|
|
||||||
|
- Upgrade to node v18 ([#4294](https://github.com/cookiecutter/cookiecutter-django/pull/4294))
|
||||||
|
|
||||||
|
- Update coverage to 7.2.3 ([#4297](https://github.com/cookiecutter/cookiecutter-django/pull/4297))
|
||||||
|
|
||||||
|
- Update mypy to 1.2.0 ([#4295](https://github.com/cookiecutter/cookiecutter-django/pull/4295))
|
||||||
|
|
||||||
|
- Update werkzeug to 2.3.0 ([#4296](https://github.com/cookiecutter/cookiecutter-django/pull/4296))
|
||||||
|
|
||||||
|
## 2023.04.25
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.21.0 ([#4293](https://github.com/cookiecutter/cookiecutter-django/pull/4293))
|
||||||
|
|
||||||
|
- Update sphinx to 6.2.1 ([#4292](https://github.com/cookiecutter/cookiecutter-django/pull/4292))
|
||||||
|
|
||||||
|
- Bump traefik from 2.9.10 to 2.10.0 ([#4290](https://github.com/cookiecutter/cookiecutter-django/pull/4290))
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4288](https://github.com/cookiecutter/cookiecutter-django/pull/4288))
|
||||||
|
|
||||||
|
## 2023.04.24
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Auto-update pre-commit hooks ([#4286](https://github.com/cookiecutter/cookiecutter-django/pull/4286))
|
||||||
|
|
||||||
|
- Update sphinx to 6.2.0 ([#4285](https://github.com/cookiecutter/cookiecutter-django/pull/4285))
|
||||||
|
|
||||||
|
## 2023.04.19
|
||||||
|
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update sentry-sdk to 1.20.0 ([#4282](https://github.com/cookiecutter/cookiecutter-django/pull/4282))
|
||||||
|
|
||||||
|
## 2023.04.18
|
||||||
|
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
- Document how to add 3rd party packages with Docker ([#4279](https://github.com/cookiecutter/cookiecutter-django/pull/4279))
|
||||||
|
|
||||||
|
## 2023.04.15
|
||||||
|
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Add username_type option ([#3958](https://github.com/cookiecutter/cookiecutter-django/pull/3958))
|
||||||
|
|
||||||
|
- Fix inconsistent line length and move configs to pyproject.toml ([#4276](https://github.com/cookiecutter/cookiecutter-django/pull/4276))
|
||||||
|
|
||||||
|
- Relax rules for linting of pull requests on this template ([#4273](https://github.com/cookiecutter/cookiecutter-django/pull/4273))
|
||||||
|
|
||||||
|
- Add more pre-commit hooks ([#4266](https://github.com/cookiecutter/cookiecutter-django/pull/4266))
|
||||||
|
|
||||||
|
- Upgrade Python to version 3.11 (Faster CPython) ([#4256](https://github.com/cookiecutter/cookiecutter-django/pull/4256))
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- Update drf-spectacular to 0.26.2 ([#4277](https://github.com/cookiecutter/cookiecutter-django/pull/4277))
|
||||||
|
|
||||||
|
- Update pytest to 7.3.1 ([#4272](https://github.com/cookiecutter/cookiecutter-django/pull/4272))
|
||||||
|
|
||||||
|
## 2023.04.13
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update tox to 4.4.12 ([#4271](https://github.com/cookiecutter/cookiecutter-django/pull/4271))
|
||||||
|
|
||||||
|
## 2023.04.10
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pytest-sugar to 0.9.7 ([#4269](https://github.com/cookiecutter/cookiecutter-django/pull/4269))
|
||||||
|
- Update pytest to 7.3.0 ([#4268](https://github.com/cookiecutter/cookiecutter-django/pull/4268))
|
||||||
|
|
||||||
|
## 2023.04.07
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Upgrade traefik to 2.9.10 ([#4267](https://github.com/cookiecutter/cookiecutter-django/pull/4267))
|
||||||
|
|
||||||
|
## 2023.04.05
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Update indent for nginx config file ([#4260](https://github.com/cookiecutter/cookiecutter-django/pull/4260))
|
||||||
|
### Updated
|
||||||
|
- Update tox to 4.4.11 ([#4262](https://github.com/cookiecutter/cookiecutter-django/pull/4262))
|
||||||
|
- Update django to 4.1.8 ([#4258](https://github.com/cookiecutter/cookiecutter-django/pull/4258))
|
||||||
|
- Update pre-commit to 3.2.2 ([#4259](https://github.com/cookiecutter/cookiecutter-django/pull/4259))
|
||||||
|
|
||||||
|
## 2023.04.04
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Upgrade to Django 4.1 ([#4028](https://github.com/cookiecutter/cookiecutter-django/pull/4028))
|
||||||
|
- Remove deprecated security setting ([#4247](https://github.com/cookiecutter/cookiecutter-django/pull/4247))
|
||||||
|
### Fixed
|
||||||
|
- Replace `runserver_plus` with `runserver` ([#4255](https://github.com/cookiecutter/cookiecutter-django/pull/4255))
|
||||||
|
- Fix traefik rule priority for media router ([#4244](https://github.com/cookiecutter/cookiecutter-django/pull/4244))
|
||||||
|
### Updated
|
||||||
|
- Update sentry-sdk to 1.19.0 ([#4254](https://github.com/cookiecutter/cookiecutter-django/pull/4254))
|
||||||
|
- Update django-debug-toolbar to 4.0.0 ([#4251](https://github.com/cookiecutter/cookiecutter-django/pull/4251))
|
||||||
|
|
||||||
|
## 2023.04.03
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- fix: Syntax for ignoring specific noqa errors ([#4250](https://github.com/cookiecutter/cookiecutter-django/pull/4250))
|
||||||
|
### Updated
|
||||||
|
- Update psycopg2-binary to 2.9.6 ([#4249](https://github.com/cookiecutter/cookiecutter-django/pull/4249))
|
||||||
|
- Update psycopg2 to 2.9.6 ([#4248](https://github.com/cookiecutter/cookiecutter-django/pull/4248))
|
||||||
|
|
||||||
|
## 2023.04.01
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pytest-instafail to 0.5.0 ([#4240](https://github.com/cookiecutter/cookiecutter-django/pull/4240))
|
||||||
|
- Update pillow to 9.5.0 ([#4242](https://github.com/cookiecutter/cookiecutter-django/pull/4242))
|
||||||
|
- Update django-allauth to 0.54.0 ([#4241](https://github.com/cookiecutter/cookiecutter-django/pull/4241))
|
||||||
|
|
||||||
|
## 2023.03.29
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update redis to 4.5.4 ([#4239](https://github.com/cookiecutter/cookiecutter-django/pull/4239))
|
||||||
|
- Update pytz to 2023.3 ([#4238](https://github.com/cookiecutter/cookiecutter-django/pull/4238))
|
||||||
|
- Update black to 23.3.0 ([#4236](https://github.com/cookiecutter/cookiecutter-django/pull/4236))
|
||||||
|
|
||||||
|
## 2023.03.27
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update watchfiles to 0.19.0 ([#4232](https://github.com/cookiecutter/cookiecutter-django/pull/4232))
|
||||||
|
|
||||||
|
## 2023.03.26
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pre-commit to 3.2.1 ([#4229](https://github.com/cookiecutter/cookiecutter-django/pull/4229))
|
||||||
|
|
||||||
|
## 2023.03.25
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pytz to 2023.2 ([#4228](https://github.com/cookiecutter/cookiecutter-django/pull/4228))
|
||||||
|
|
||||||
|
## 2023.03.23
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Bump traefik from 2.9.8 to 2.9.9 ([#4225](https://github.com/cookiecutter/cookiecutter-django/pull/4225))
|
||||||
|
|
||||||
|
## 2023.03.22
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update redis to 4.5.3 ([#4227](https://github.com/cookiecutter/cookiecutter-django/pull/4227))
|
||||||
|
|
||||||
|
## 2023.03.20
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update django-allauth to 0.53.1 ([#4223](https://github.com/cookiecutter/cookiecutter-django/pull/4223))
|
||||||
|
- Update redis to 4.5.2 ([#4222](https://github.com/cookiecutter/cookiecutter-django/pull/4222))
|
||||||
|
|
||||||
|
## 2023.03.18
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update drf-spectacular to 0.26.1 ([#4221](https://github.com/cookiecutter/cookiecutter-django/pull/4221))
|
||||||
|
- Update pygithub to 1.58.1 ([#4220](https://github.com/cookiecutter/cookiecutter-django/pull/4220))
|
||||||
|
- Update pre-commit to 3.2.0 ([#4219](https://github.com/cookiecutter/cookiecutter-django/pull/4219))
|
||||||
|
|
||||||
|
## 2023.03.16
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Pin base Python Docker images to bugfix ([#4194](https://github.com/cookiecutter/cookiecutter-django/pull/4194))
|
||||||
|
### Fixed
|
||||||
|
- Trim leading and trailing space in `domain_name` and `email` ([#4163](https://github.com/cookiecutter/cookiecutter-django/pull/4163))
|
||||||
|
### Updated
|
||||||
|
- Update djangorestframework-stubs to 1.10.0 ([#4217](https://github.com/cookiecutter/cookiecutter-django/pull/4217))
|
||||||
|
- Update django-stubs to 1.16.0 ([#4216](https://github.com/cookiecutter/cookiecutter-django/pull/4216))
|
||||||
|
- Update coverage to 7.2.2 ([#4218](https://github.com/cookiecutter/cookiecutter-django/pull/4218))
|
||||||
|
- Update sentry-sdk to 1.17.0 ([#4215](https://github.com/cookiecutter/cookiecutter-django/pull/4215))
|
||||||
|
- Bump Docker python image from 3.10.9 to 3.10.10 on production Django ([#4214](https://github.com/cookiecutter/cookiecutter-django/pull/4214))
|
||||||
|
- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for docs ([#4213](https://github.com/cookiecutter/cookiecutter-django/pull/4213))
|
||||||
|
- Bump Docker python image from 3.10.9-slim-bullseye to 3.10.10-slim-bullseye for local Django service ([#4212](https://github.com/cookiecutter/cookiecutter-django/pull/4212))
|
||||||
|
- Update uvicorn to 0.21.1 ([#4211](https://github.com/cookiecutter/cookiecutter-django/pull/4211))
|
||||||
|
- Update django-allauth to 0.53.0 ([#4210](https://github.com/cookiecutter/cookiecutter-django/pull/4210))
|
||||||
|
|
||||||
|
## 2023.03.14
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update django-celery-beat to 2.5.0 ([#4208](https://github.com/cookiecutter/cookiecutter-django/pull/4208))
|
||||||
|
|
||||||
|
## 2023.03.13
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update uvicorn to 0.21.0 ([#4203](https://github.com/cookiecutter/cookiecutter-django/pull/4203))
|
||||||
|
- Update django-anymail to 9.1 ([#4206](https://github.com/cookiecutter/cookiecutter-django/pull/4206))
|
||||||
|
- Update tox to 4.4.7 ([#4207](https://github.com/cookiecutter/cookiecutter-django/pull/4207))
|
||||||
|
|
||||||
|
## 2023.03.09
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fix the omit configuration for coverage ([#4201](https://github.com/cookiecutter/cookiecutter-django/pull/4201))
|
||||||
|
### Updated
|
||||||
|
- Update ipdb to 0.13.13 ([#4202](https://github.com/cookiecutter/cookiecutter-django/pull/4202))
|
||||||
|
|
||||||
|
## 2023.03.07
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update mypy to 1.1.1 ([#4196](https://github.com/cookiecutter/cookiecutter-django/pull/4196))
|
||||||
|
- Update django-environ to 0.10.0 ([#4195](https://github.com/cookiecutter/cookiecutter-django/pull/4195))
|
||||||
|
|
||||||
|
## 2023.03.04
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Add option to serve media files locally using nginx ([#2457](https://github.com/cookiecutter/cookiecutter-django/pull/2457))
|
||||||
|
### Documentation
|
||||||
|
- Include contributing page to the docs ([#4144](https://github.com/cookiecutter/cookiecutter-django/pull/4144))
|
||||||
|
### Updated
|
||||||
|
- Update myst-parser to 0.19.1 ([#4193](https://github.com/cookiecutter/cookiecutter-django/pull/4193))
|
||||||
|
- Update pytest to 7.2.2 ([#4191](https://github.com/cookiecutter/cookiecutter-django/pull/4191))
|
||||||
|
- Update drf-spectacular to 0.26.0 ([#4192](https://github.com/cookiecutter/cookiecutter-django/pull/4192))
|
||||||
|
|
||||||
|
## 2023.02.28
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pre-commit to 3.1.1 ([#4188](https://github.com/cookiecutter/cookiecutter-django/pull/4188))
|
||||||
|
|
||||||
|
## 2023.02.27
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update sentry-sdk to 1.16.0 ([#4187](https://github.com/cookiecutter/cookiecutter-django/pull/4187))
|
||||||
|
|
||||||
|
## 2023.02.26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Fix readthedocs config file for generated project ([#4172](https://github.com/cookiecutter/cookiecutter-django/pull/4172))
|
||||||
|
### Updated
|
||||||
|
- Bump traefik from v2.2.11 to 2.9.8 ([#4164](https://github.com/cookiecutter/cookiecutter-django/pull/4164))
|
||||||
|
- Update coverage to 7.2.1 ([#4186](https://github.com/cookiecutter/cookiecutter-django/pull/4186))
|
||||||
|
|
||||||
|
## 2023.02.25
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Run linting with pre-commit on GitLab ([#4150](https://github.com/cookiecutter/cookiecutter-django/pull/4150))
|
||||||
|
### Fixed
|
||||||
|
- Disable caching for linter job on GitHub actions ([#4166](https://github.com/cookiecutter/cookiecutter-django/pull/4166))
|
||||||
|
### Documentation
|
||||||
|
- Add instuction to run celery beat ([#4162](https://github.com/cookiecutter/cookiecutter-django/pull/4162))
|
||||||
|
### Updated
|
||||||
|
- Bump garland/aws-cli-docker from 1.15.47 to 1.16.140 ([#4136](https://github.com/cookiecutter/cookiecutter-django/pull/4136))
|
||||||
|
- Update djangorestframework-stubs to 1.9.1 ([#4184](https://github.com/cookiecutter/cookiecutter-django/pull/4184))
|
||||||
|
- Update whitenoise to 6.4.0 ([#4180](https://github.com/cookiecutter/cookiecutter-django/pull/4180))
|
||||||
|
- Update django-stubs to 1.15.0 ([#4183](https://github.com/cookiecutter/cookiecutter-django/pull/4183))
|
||||||
|
- Update django-crispy-forms to 2.0 ([#4158](https://github.com/cookiecutter/cookiecutter-django/pull/4158))
|
||||||
|
- Update django-cors-headers to 3.14.0 ([#4181](https://github.com/cookiecutter/cookiecutter-django/pull/4181))
|
||||||
|
- Update python-slugify to 8.0.1 ([#4178](https://github.com/cookiecutter/cookiecutter-django/pull/4178))
|
||||||
|
- Update pre-commit to 3.1.0 ([#4176](https://github.com/cookiecutter/cookiecutter-django/pull/4176))
|
||||||
|
- Update mypy to 1.0.1 ([#4168](https://github.com/cookiecutter/cookiecutter-django/pull/4168))
|
||||||
|
- Update werkzeug to 2.2.3 ([#4160](https://github.com/cookiecutter/cookiecutter-django/pull/4160))
|
||||||
|
- Update coverage to 7.2.0 ([#4177](https://github.com/cookiecutter/cookiecutter-django/pull/4177))
|
||||||
|
- Update django to 4.0.10 ([#4159](https://github.com/cookiecutter/cookiecutter-django/pull/4159))
|
||||||
|
- Update hiredis to 2.2.2 ([#4156](https://github.com/cookiecutter/cookiecutter-django/pull/4156))
|
||||||
|
|
||||||
|
## 2023.02.17
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Update version of github actions on the template project ([#4167](https://github.com/cookiecutter/cookiecutter-django/pull/4167))
|
||||||
|
|
||||||
|
## 2023.02.09
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Remove unused pip cache paths in GHA & add a note for pre-commit.ci ([#4151](https://github.com/cookiecutter/cookiecutter-django/pull/4151))
|
||||||
|
### Updated
|
||||||
|
- Update mypy to 0.991 ([#4106](https://github.com/cookiecutter/cookiecutter-django/pull/4106))
|
||||||
|
|
||||||
|
## 2023.02.08
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update sphinx to 6.1.3 ([#4148](https://github.com/cookiecutter/cookiecutter-django/pull/4148))
|
||||||
|
- Update redis to 4.5.1 ([#4147](https://github.com/cookiecutter/cookiecutter-django/pull/4147))
|
||||||
|
|
||||||
|
## 2023.02.07
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Bump postcss-preset-env from 7.8.3 to 8.0.1 ([#4115](https://github.com/cookiecutter/cookiecutter-django/pull/4115))
|
||||||
|
- Bump sass-loader from 12.6.0 to 13.2.0 ([#4116](https://github.com/cookiecutter/cookiecutter-django/pull/4116))
|
||||||
|
- Bump babel-loader from 8.3.0 to 9.1.2 ([#4117](https://github.com/cookiecutter/cookiecutter-django/pull/4117))
|
||||||
|
- Bump postcss-loader from 6.2.1 to 7.0.2 ([#4114](https://github.com/cookiecutter/cookiecutter-django/pull/4114))
|
||||||
|
- Bump webpack-cli from 4.10.0 to 5.0.1 ([#4118](https://github.com/cookiecutter/cookiecutter-django/pull/4118))
|
||||||
|
- Update redis to 4.5.0 ([#4142](https://github.com/cookiecutter/cookiecutter-django/pull/4142))
|
||||||
|
- Update sentry-sdk to 1.15.0 ([#4141](https://github.com/cookiecutter/cookiecutter-django/pull/4141))
|
||||||
|
|
||||||
|
## 2023.02.06
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Change `RequestFactory` to `APIRequestFactory` in tests for API views ([#4110](https://github.com/cookiecutter/cookiecutter-django/pull/4110))
|
||||||
|
### Fixed
|
||||||
|
- Fix django-webpack-loader setup when running tests ([#4128](https://github.com/cookiecutter/cookiecutter-django/pull/4128))
|
||||||
|
### Documentation
|
||||||
|
- Added AWS ECS Full Deployment Article to README ([#2630](https://github.com/cookiecutter/cookiecutter-django/pull/2630))
|
||||||
|
### Updated
|
||||||
|
- Update hiredis to 2.2.1 ([#4123](https://github.com/cookiecutter/cookiecutter-django/pull/4123))
|
||||||
|
- Update tox to 4.4.4 ([#4133](https://github.com/cookiecutter/cookiecutter-django/pull/4133))
|
||||||
|
- Update django to 4.0.9 ([#4134](https://github.com/cookiecutter/cookiecutter-django/pull/4134))
|
||||||
|
- Update django-webpack-loader to 1.8.1 ([#4132](https://github.com/cookiecutter/cookiecutter-django/pull/4132))
|
||||||
|
|
||||||
|
## 2023.02.05
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- Add note about which service to request when running locally with Docker & Webpack or Gulp ([#4130](https://github.com/cookiecutter/cookiecutter-django/pull/4130))
|
||||||
|
|
||||||
|
## 2023.02.03
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pre-commit to 3.0.4 ([#4127](https://github.com/cookiecutter/cookiecutter-django/pull/4127))
|
||||||
|
|
||||||
|
## 2023.02.02
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update python-slugify to 8.0.0 ([#4111](https://github.com/cookiecutter/cookiecutter-django/pull/4111))
|
||||||
|
- Update pre-commit to 3.0.3 ([#4121](https://github.com/cookiecutter/cookiecutter-django/pull/4121))
|
||||||
|
- Update black to 23.1.0 ([#4120](https://github.com/cookiecutter/cookiecutter-django/pull/4120))
|
||||||
|
- Update black pre-commit hook ([#4122](https://github.com/cookiecutter/cookiecutter-django/pull/4122))
|
||||||
|
|
||||||
|
## 2023.01.29
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Add Webpack support ([#3623](https://github.com/cookiecutter/cookiecutter-django/pull/3623))
|
||||||
|
- Remove `BrokenLinkEmailsMiddleware` ([#4112](https://github.com/cookiecutter/cookiecutter-django/pull/4112))
|
||||||
|
|
||||||
|
## 2023.01.28
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Refactor `merge_production_dotenvs_in_dotenv.py` ([#4105](https://github.com/cookiecutter/cookiecutter-django/pull/4105))
|
||||||
|
### Updated
|
||||||
|
- Update isort to 5.12.0 ([#4109](https://github.com/cookiecutter/cookiecutter-django/pull/4109))
|
||||||
|
- Auto-update pre-commit hooks ([#4108](https://github.com/cookiecutter/cookiecutter-django/pull/4108))
|
||||||
|
|
||||||
|
## 2023.01.27
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update django-stubs to 1.14.0 ([#4103](https://github.com/cookiecutter/cookiecutter-django/pull/4103))
|
||||||
|
|
||||||
|
## 2023.01.26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Rename BASE_DIR_PATH to BASE_DIR ([#4102](https://github.com/cookiecutter/cookiecutter-django/pull/4102))
|
||||||
|
### Updated
|
||||||
|
- Update pre-commit to 3.0.1 ([#4104](https://github.com/cookiecutter/cookiecutter-django/pull/4104))
|
||||||
|
- Update tox to 4.4.2 ([#4101](https://github.com/cookiecutter/cookiecutter-django/pull/4101))
|
||||||
|
|
||||||
|
## 2023.01.25
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Rename ROOT_DIR to BASE_DIR ([#4086](https://github.com/cookiecutter/cookiecutter-django/pull/4086))
|
||||||
|
- Update postgres and redis to point to mini tiers ([#4099](https://github.com/cookiecutter/cookiecutter-django/pull/4099))
|
||||||
|
### Updated
|
||||||
|
- Update coverage to 7.1.0 ([#4100](https://github.com/cookiecutter/cookiecutter-django/pull/4100))
|
||||||
|
|
||||||
|
## 2023.01.24
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pre-commit to 3.0.0 ([#4098](https://github.com/cookiecutter/cookiecutter-django/pull/4098))
|
||||||
|
|
||||||
|
## 2023.01.23
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update sentry-sdk to 1.14.0 ([#4096](https://github.com/cookiecutter/cookiecutter-django/pull/4096))
|
||||||
|
|
||||||
|
## 2023.01.22
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update django-compressor to 4.3.1 ([#4094](https://github.com/cookiecutter/cookiecutter-django/pull/4094))
|
||||||
|
|
||||||
|
## 2023.01.21
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update django-stubs to 1.13.2 ([#4093](https://github.com/cookiecutter/cookiecutter-django/pull/4093))
|
||||||
|
|
||||||
|
## 2023.01.19
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Add sourcemaps support to Gulp ([#4089](https://github.com/cookiecutter/cookiecutter-django/pull/4089))
|
||||||
|
### Updated
|
||||||
|
- Update coverage to 7.0.5 ([#4092](https://github.com/cookiecutter/cookiecutter-django/pull/4092))
|
||||||
|
- Update redis to 4.4.2 ([#4091](https://github.com/cookiecutter/cookiecutter-django/pull/4091))
|
||||||
|
- Update requests to 2.28.2 ([#4090](https://github.com/cookiecutter/cookiecutter-django/pull/4090))
|
||||||
|
- Update tox to 4.3.5 ([#4087](https://github.com/cookiecutter/cookiecutter-django/pull/4087))
|
||||||
|
|
||||||
|
## 2023.01.17
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update tox to 4.3.3 ([#4081](https://github.com/cookiecutter/cookiecutter-django/pull/4081))
|
||||||
|
|
||||||
|
## 2023.01.15
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update pytest to 7.2.1 ([#4077](https://github.com/cookiecutter/cookiecutter-django/pull/4077))
|
||||||
|
- Update pytz to 2022.7.1 ([#4078](https://github.com/cookiecutter/cookiecutter-django/pull/4078))
|
||||||
|
|
||||||
|
## 2023.01.12
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
- Update sentry-sdk to 1.13.0 ([#4074](https://github.com/cookiecutter/cookiecutter-django/pull/4074))
|
||||||
|
|
||||||
|
## 2023.01.11
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Update Celery instructions in the documentation ([#4061](https://github.com/cookiecutter/cookiecutter-django/pull/4061))
|
||||||
|
### Updated
|
||||||
|
- Update tox to 4.2.7 ([#4073](https://github.com/cookiecutter/cookiecutter-django/pull/4073))
|
||||||
|
|
||||||
## 2023.01.10
|
## 2023.01.10
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
|
|
||||||
Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PyPA Code of Conduct](https://www.pypa.io/en/latest/code-of-conduct/).
|
Everyone who interacts in the Cookiecutter project's codebase, issue trackers, chat rooms, and mailing lists is expected to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/)
|
||||||
|
|
|
@ -2,41 +2,81 @@
|
||||||
|
|
||||||
Always happy to get issues identified and pull requests!
|
Always happy to get issues identified and pull requests!
|
||||||
|
|
||||||
## Getting your pull request merged in
|
## General considerations
|
||||||
|
|
||||||
1. Keep it small. The smaller the pull request, the more likely we are to accept.
|
1. Keep it small. The smaller the change, the more likely we are to accept.
|
||||||
2. Pull requests that fix a current issue get priority for review.
|
2. Changes that fix a current issue get priority for review.
|
||||||
|
3. Check out [GitHub guide][submit-a-pr] if you've never created a pull request before.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
1. Fork the repo
|
||||||
|
2. Clone your fork
|
||||||
|
3. Create a branch for your changes
|
||||||
|
|
||||||
|
This last step is very important, don't start developing from master, it'll cause pain if you need to send another change later.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
You'll need to run the tests using Python 3.11. We recommend using [tox](https://tox.readthedocs.io/en/latest/) to run the tests. It will automatically create a fresh virtual environment and install our test dependencies, such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/).
|
||||||
|
|
||||||
|
We'll also run the tests on GitHub actions when you send your pull request, but it's a good idea to run them locally before you send it.
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
Please install [tox](https://tox.readthedocs.io/en/latest/), which is a generic virtualenv management and test command line tool.
|
First, make sure that your version of Python is 3.11:
|
||||||
|
|
||||||
[tox](https://tox.readthedocs.io/en/latest/) is available for download from [PyPI](https://pypi.python.org/pypi) via [pip](https://pypi.python.org/pypi/pip/):
|
```bash
|
||||||
|
$ python --version
|
||||||
|
Python 3.11.3
|
||||||
|
```
|
||||||
|
|
||||||
$ pip install tox
|
Any version that starts with 3.11 will do. If you need to install it, you can get it from [python.org](https://www.python.org/downloads/).
|
||||||
|
|
||||||
It will automatically create a fresh virtual environment and install our test dependencies,
|
Then install `tox`, if not already installed:
|
||||||
such as [pytest-cookies](https://pypi.python.org/pypi/pytest-cookies/) and [flake8](https://pypi.python.org/pypi/flake8/).
|
|
||||||
|
|
||||||
### Run the Tests
|
```bash
|
||||||
|
$ python -m pip install tox
|
||||||
|
```
|
||||||
|
|
||||||
Tox uses pytest under the hood, hence it supports the same syntax for selecting tests.
|
### Run the template's test suite
|
||||||
|
|
||||||
For further information please consult the [pytest usage docs](https://pytest.org/latest/usage.html#specifying-tests-selecting-tests).
|
To run the tests of the template using the current Python version:
|
||||||
|
|
||||||
To run all tests using various versions of python in virtualenvs defined in tox.ini, just run tox.:
|
```bash
|
||||||
|
$ tox -e py
|
||||||
|
```
|
||||||
|
|
||||||
$ tox
|
This uses `pytest `under the hood, and you can pass options to it after a `--`. So to run a particular test:
|
||||||
|
|
||||||
It is possible to test with a specific version of python. To do this, the command
|
```bash
|
||||||
is:
|
$ tox -e py -- -k test_default_configuration
|
||||||
|
```
|
||||||
|
|
||||||
$ tox -e py310
|
For further information, please consult the [pytest usage docs](https://pytest.org/en/latest/how-to/usage.html#specifying-which-tests-to-run).
|
||||||
|
|
||||||
This will run pytest with the python3.10 interpreter, for example.
|
### Run the generated project tests
|
||||||
|
|
||||||
To run a particular test with tox for against your current Python version:
|
The template tests are checking that the generated project is fully rendered and that it passes `flake8`. We also have some test scripts which generate a specific project combination, install the dependencies, run the tests of the generated project, install FE dependencies and generate the docs. They will install the template dependencies, so make sure you create and activate a virtual environment first.
|
||||||
|
|
||||||
$ tox -e py -- -k test_default_configuration
|
```bash
|
||||||
|
$ python -m venv venv
|
||||||
|
$ source venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
These tests are slower and can be run with or without Docker:
|
||||||
|
|
||||||
|
- Without Docker: `scripts/test_bare.sh` (for bare metal)
|
||||||
|
- With Docker: `scripts/test_docker.sh`
|
||||||
|
|
||||||
|
All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ scripts/test_bare.sh use_celery=y
|
||||||
|
```
|
||||||
|
|
||||||
|
## Submitting a pull request
|
||||||
|
|
||||||
|
Once you're happy with your changes and they look ok locally, push and send send [a pull request][submit-a-pr] to the main repo, which will trigger the tests on GitHub actions. If they fail, try to fix them. A maintainer should take a look at your change and give you feedback or merge it.
|
||||||
|
|
||||||
|
[submit-a-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request
|
||||||
|
|
102
CONTRIBUTORS.md
102
CONTRIBUTORS.md
|
@ -74,10 +74,17 @@ accept and merge pull requests.
|
||||||
</td>
|
</td>
|
||||||
<td>sfdye</td>
|
<td>sfdye</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Jelmer Draaijer</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/foarsitter">foarsitter</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
*Audrey is also the creator of Cookiecutter. Audrey and Daniel are on
|
_Audrey is also the creator of Cookiecutter. Audrey and Daniel are on
|
||||||
the Cookiecutter core team.*
|
the Cookiecutter core team._
|
||||||
|
|
||||||
## Other Contributors
|
## Other Contributors
|
||||||
|
|
||||||
|
@ -292,6 +299,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Arkadiusz Michał Ryś</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/arrys">arrys</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Arnav Choudhury</td>
|
<td>Arnav Choudhury</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -362,6 +376,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Birtibu</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/Birtibu">Birtibu</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Bo Lopker</td>
|
<td>Bo Lopker</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -642,6 +663,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td>jangeador</td>
|
<td>jangeador</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Delphine LEMIRE</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/DelphineLemire">DelphineLemire</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Demetris Stavrou</td>
|
<td>Demetris Stavrou</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -705,6 +733,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td>dudanogueira</td>
|
<td>dudanogueira</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>duffn</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/duffn">duffn</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Dónal Adams</td>
|
<td>Dónal Adams</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -901,6 +936,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Hoai-Thu Vuong</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/thuvh">thuvh</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Howie Zhao</td>
|
<td>Howie Zhao</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -971,13 +1013,6 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>Jelmer Draaijer</td>
|
|
||||||
<td>
|
|
||||||
<a href="https://github.com/foarsitter">foarsitter</a>
|
|
||||||
</td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Jens Nilsson</td>
|
<td>Jens Nilsson</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1034,6 +1069,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Joseph Hanna</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/sanchimenea">sanchimenea</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>jugglinmike</td>
|
<td>jugglinmike</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1272,6 +1314,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>masavini</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/masavini">masavini</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Mateusz Ostaszewski</td>
|
<td>Mateusz Ostaszewski</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1279,6 +1328,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Matheus Jardim Bernardes</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/matheusjardimb">matheusjardimb</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Mathijs Hoogland</td>
|
<td>Mathijs Hoogland</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1398,6 +1454,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Morten Kaae</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/MortenKaae">MortenKaae</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>mozillazg</td>
|
<td>mozillazg</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1412,6 +1475,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>mpsantos</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/mpsantos">mpsantos</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Naveen</td>
|
<td>Naveen</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1475,6 +1545,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Patrick Tran</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/theptrk">theptrk</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Pawan Chaurasia</td>
|
<td>Pawan Chaurasia</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1734,6 +1811,13 @@ Listed in alphabetical order.
|
||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>tildebox</td>
|
||||||
|
<td>
|
||||||
|
<a href="https://github.com/tildebox">tildebox</a>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Tim Claessens</td>
|
<td>Tim Claessens</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
54
README.md
54
README.md
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
[](https://github.com/cookiecutter/cookiecutter-django/actions/workflows/ci.yml?query=branch%3Amaster)
|
[](https://github.com/cookiecutter/cookiecutter-django/actions/workflows/ci.yml?query=branch%3Amaster)
|
||||||
[](https://cookiecutter-django.readthedocs.io/en/latest/?badge=latest)
|
[](https://cookiecutter-django.readthedocs.io/en/latest/?badge=latest)
|
||||||
|
[](https://results.pre-commit.ci/latest/github/cookiecutter/cookiecutter-django/master)
|
||||||
|
[](https://github.com/ambv/black)
|
||||||
|
|
||||||
[](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/)
|
[](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/)
|
||||||
[](https://discord.gg/uFXweDQc5a)
|
[](https://discord.gg/uFXweDQc5a)
|
||||||
[](https://www.codetriage.com/cookiecutter/cookiecutter-django)
|
[](https://www.codetriage.com/cookiecutter/cookiecutter-django)
|
||||||
[](https://github.com/ambv/black)
|
|
||||||
|
|
||||||
Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting
|
Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting
|
||||||
production-ready Django projects quickly.
|
production-ready Django projects quickly.
|
||||||
|
@ -17,8 +19,8 @@ production-ready Django projects quickly.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- For Django 4.0
|
- For Django 4.2
|
||||||
- Works with Python 3.10
|
- Works with Python 3.11
|
||||||
- Renders Django projects with 100% starting test coverage
|
- Renders Django projects with 100% starting test coverage
|
||||||
- Twitter [Bootstrap](https://github.com/twbs/bootstrap) v5
|
- 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](http://12factor.net/) based settings via [django-environ](https://github.com/joke2k/django-environ)
|
||||||
|
@ -27,9 +29,9 @@ production-ready Django projects quickly.
|
||||||
- Registration via [django-allauth](https://github.com/pennersr/django-allauth)
|
- Registration via [django-allauth](https://github.com/pennersr/django-allauth)
|
||||||
- Comes with custom user model ready to go
|
- Comes with custom user model ready to go
|
||||||
- Optional basic ASGI setup for Websockets
|
- Optional basic ASGI setup for Websockets
|
||||||
- Optional custom static build using Gulp and livereload
|
- Optional custom static build using Gulp or Webpack
|
||||||
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
|
- Send emails via [Anymail](https://github.com/anymail/django-anymail) (using [Mailgun](http://www.mailgun.com/) by default or Amazon SES if AWS is selected cloud provider, but switchable)
|
||||||
- Media storage using Amazon S3, Google Cloud Storage or Azure Storage
|
- Media storage using Amazon S3, Google Cloud Storage, Azure Storage or nginx
|
||||||
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
|
- Docker support using [docker-compose](https://github.com/docker/compose) for development and production (using [Traefik](https://traefik.io/) with [LetsEncrypt](https://letsencrypt.org/) support)
|
||||||
- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku
|
- [Procfile](https://devcenter.heroku.com/articles/procfile) for deploying to Heroku
|
||||||
- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/)
|
- Instructions for deploying to [PythonAnywhere](https://www.pythonanywhere.com/)
|
||||||
|
@ -39,7 +41,7 @@ production-ready Django projects quickly.
|
||||||
|
|
||||||
## Optional Integrations
|
## Optional Integrations
|
||||||
|
|
||||||
*These features can be enabled during initial project setup.*
|
_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/)
|
- 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)
|
- Configuration for [Celery](https://docs.celeryq.dev) and [Flower](https://github.com/mher/flower) (the latter in Docker setup only)
|
||||||
|
@ -49,19 +51,21 @@ production-ready Django projects quickly.
|
||||||
## Constraints
|
## Constraints
|
||||||
|
|
||||||
- Only maintained 3rd party libraries are used.
|
- Only maintained 3rd party libraries are used.
|
||||||
- Uses PostgreSQL everywhere: 10.19 - 14.1 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available).
|
- Uses PostgreSQL everywhere: 10 - 15 ([MySQL fork](https://github.com/mabdullahadeel/cookiecutter-django-mysql) also available).
|
||||||
- Environment variables for configuration (This won't work with Apache/mod_wsgi).
|
- Environment variables for configuration (This won't work with Apache/mod_wsgi).
|
||||||
|
|
||||||
## Support this Project!
|
## Support this Project!
|
||||||
|
|
||||||
This project is run by volunteers. Please support them in their efforts to maintain and improve Cookiecutter Django:
|
This project is an open source project run by volunteers. You can sponsor us via [OpenCollective](https://opencollective.com/cookiecutter-django) or individually via GitHub Sponsors:
|
||||||
|
|
||||||
- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB.
|
- Daniel Roy Greenfeld, Project Lead ([GitHub](https://github.com/pydanny), [Patreon](https://www.patreon.com/danielroygreenfeld)): expertise in Django and AWS ELB.
|
||||||
|
- Fabio C. Barrionuevo, Core Developer ([GitHub](https://github.com/luzfcb)): expertise in Python/Django, hands-on DevOps and frontend experience.
|
||||||
|
- Bruno Alla, Core Developer ([GitHub](https://github.com/browniebroke)): expertise in Python/Django and DevOps.
|
||||||
- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience.
|
- Nikita Shupeyko, Core Developer ([GitHub](https://github.com/webyneter)): expertise in Python/Django, hands-on DevOps and frontend experience.
|
||||||
|
|
||||||
Projects that provide financial support to the maintainers:
|
Projects that provide financial support to the maintainers:
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
---
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://www.feldroy.com/products//two-scoops-of-django-3-x"><img src="https://cdn.shopify.com/s/files/1/0304/6901/products/Two-Scoops-of-Django-3-Alpha-Cover_540x_26507b15-e489-470b-8a97-02773dd498d1_1080x.jpg"></a>
|
<a href="https://www.feldroy.com/products//two-scoops-of-django-3-x"><img src="https://cdn.shopify.com/s/files/1/0304/6901/products/Two-Scoops-of-Django-3-Alpha-Cover_540x_26507b15-e489-470b-8a97-02773dd498d1_1080x.jpg"></a>
|
||||||
|
@ -116,16 +120,25 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
|
||||||
4 - Apache Software License 2.0
|
4 - Apache Software License 2.0
|
||||||
5 - Not open source
|
5 - Not open source
|
||||||
Choose from 1, 2, 3, 4, 5 [1]: 1
|
Choose from 1, 2, 3, 4, 5 [1]: 1
|
||||||
|
Select username_type:
|
||||||
|
1 - username
|
||||||
|
2 - email
|
||||||
|
Choose from 1, 2 [1]: 1
|
||||||
timezone [UTC]: America/Los_Angeles
|
timezone [UTC]: America/Los_Angeles
|
||||||
windows [n]: n
|
windows [n]: n
|
||||||
use_pycharm [n]: y
|
Select an editor to use. The choices are:
|
||||||
|
1 - None
|
||||||
|
2 - PyCharm
|
||||||
|
3 - VS Code
|
||||||
|
Choose from 1, 2, 3 [1]: 1
|
||||||
use_docker [n]: n
|
use_docker [n]: n
|
||||||
Select postgresql_version:
|
Select postgresql_version:
|
||||||
1 - 14
|
1 - 15
|
||||||
2 - 13
|
2 - 14
|
||||||
3 - 12
|
3 - 13
|
||||||
4 - 11
|
4 - 12
|
||||||
5 - 10
|
5 - 11
|
||||||
|
6 - 10
|
||||||
Choose from 1, 2, 3, 4, 5 [1]: 1
|
Choose from 1, 2, 3, 4, 5 [1]: 1
|
||||||
Select cloud_provider:
|
Select cloud_provider:
|
||||||
1 - AWS
|
1 - AWS
|
||||||
|
@ -149,6 +162,7 @@ Answer the prompts with your own desired [options](http://cookiecutter-django.re
|
||||||
1 - None
|
1 - None
|
||||||
2 - Django Compressor
|
2 - Django Compressor
|
||||||
3 - Gulp
|
3 - Gulp
|
||||||
|
4 - Webpack
|
||||||
Choose from 1, 2, 3, 4 [1]: 1
|
Choose from 1, 2, 3, 4 [1]: 1
|
||||||
use_celery [n]: y
|
use_celery [n]: y
|
||||||
use_mailhog [n]: n
|
use_mailhog [n]: n
|
||||||
|
@ -186,7 +200,7 @@ For local development, see the following:
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the *cookiecutter-django* tag. We check there periodically for questions.
|
- Have questions? **Before you ask questions anywhere else**, please post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/cookiecutter-django) under the _cookiecutter-django_ tag. We check there periodically for questions.
|
||||||
- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues).
|
- If you think you found a bug or want to request a feature, please open an [issue](https://github.com/cookiecutter/cookiecutter-django/issues).
|
||||||
- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a).
|
- For anything else, you can chat with us on [Discord](https://discord.gg/uFXweDQc5a).
|
||||||
|
|
||||||
|
@ -196,13 +210,14 @@ You may notice that some elements of this project do not exactly match what we d
|
||||||
|
|
||||||
## For PyUp Users
|
## For PyUp Users
|
||||||
|
|
||||||
If you are using [PyUp](https://pyup.io) to keep your dependencies updated and secure, use the code *cookiecutter* during checkout to get 15% off every month.
|
If you are using [PyUp](https://pyup.io) to keep your dependencies updated and secure, use the code _cookiecutter_ during checkout to get 15% off every month.
|
||||||
|
|
||||||
## "Your Stuff"
|
## "Your Stuff"
|
||||||
|
|
||||||
Scattered throughout the Python and HTML of this project are places marked with "your stuff". This is where third-party libraries are to be integrated with your project.
|
Scattered throughout the Python and HTML of this project are places marked with "your stuff". This is where third-party libraries are to be integrated with your project.
|
||||||
|
|
||||||
## For MySQL users
|
## For MySQL users
|
||||||
|
|
||||||
To get full MySQL support in addition to the default Postgresql, you can use this fork of the cookiecutter-django:
|
To get full MySQL support in addition to the default Postgresql, you can use this fork of the cookiecutter-django:
|
||||||
https://github.com/mabdullahadeel/cookiecutter-django-mysql
|
https://github.com/mabdullahadeel/cookiecutter-django-mysql
|
||||||
|
|
||||||
|
@ -212,12 +227,12 @@ Need a stable release? You can find them at <https://github.com/cookiecutter/coo
|
||||||
|
|
||||||
## Not Exactly What You Want?
|
## Not Exactly What You Want?
|
||||||
|
|
||||||
This is what I want. *It might not be what you want.* Don't worry, you have options:
|
This is what I want. _It might not be what you want._ Don't worry, you have options:
|
||||||
|
|
||||||
### Fork This
|
### Fork This
|
||||||
|
|
||||||
If you have differences in your preferred setup, I encourage you to fork this to create your own version.
|
If you have differences in your preferred setup, I encourage you to fork this to create your own version.
|
||||||
Once you have your fork working, let me know and I'll add it to a '*Similar Cookiecutter Templates*' list here.
|
Once you have your fork working, let me know and I'll add it to a '_Similar Cookiecutter Templates_' list here.
|
||||||
It's up to you whether to rename your fork.
|
It's up to you whether to rename your fork.
|
||||||
|
|
||||||
If you do rename your fork, I encourage you to submit it to the following places:
|
If you do rename your fork, I encourage you to submit it to the following places:
|
||||||
|
@ -233,6 +248,7 @@ experience better.
|
||||||
## Articles
|
## Articles
|
||||||
|
|
||||||
- [Cookiecutter Django With Amazon RDS](https://haseeburrehman.com/posts/cookiecutter-django-with-amazon-rds/) - Apr, 2, 2021
|
- [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
|
- [Using cookiecutter-django with Google Cloud Storage](https://ahhda.github.io/cloud/gce/django/2019/03/12/using-django-cookiecutter-cloud-storage.html) - Mar. 12, 2019
|
||||||
- [cookiecutter-django with Nginx, Route 53 and ELB](https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/) - Feb. 12, 2018
|
- [cookiecutter-django with Nginx, Route 53 and ELB](https://msaizar.com/blog/cookiecutter-django-nginx-route-53-and-elb/) - Feb. 12, 2018
|
||||||
- [cookiecutter-django and Amazon RDS](https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/) - Feb. 7, 2018
|
- [cookiecutter-django and Amazon RDS](https://msaizar.com/blog/cookiecutter-django-and-amazon-rds/) - Feb. 7, 2018
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
"description": "Behold My Awesome Project!",
|
"description": "Behold My Awesome Project!",
|
||||||
"author_name": "Daniel Roy Greenfeld",
|
"author_name": "Daniel Roy Greenfeld",
|
||||||
"domain_name": "example.com",
|
"domain_name": "example.com",
|
||||||
"email": "{{ cookiecutter.author_name.lower()|replace(' ', '-') }}@example.com",
|
"email": "{{ cookiecutter.author_name.lower() | trim() |replace(' ', '-') }}@{{ cookiecutter.domain_name.lower() | trim() }}",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"open_source_license": [
|
"open_source_license": [
|
||||||
"MIT",
|
"MIT",
|
||||||
|
@ -13,23 +13,13 @@
|
||||||
"Apache Software License 2.0",
|
"Apache Software License 2.0",
|
||||||
"Not open source"
|
"Not open source"
|
||||||
],
|
],
|
||||||
|
"username_type": ["username", "email"],
|
||||||
"timezone": "UTC",
|
"timezone": "UTC",
|
||||||
"windows": "n",
|
"windows": "n",
|
||||||
"use_pycharm": "n",
|
"editor": ["None", "PyCharm", "VS Code"],
|
||||||
"use_docker": "n",
|
"use_docker": "n",
|
||||||
"postgresql_version": [
|
"postgresql_version": ["15", "14", "13", "12", "11", "10"],
|
||||||
"14",
|
"cloud_provider": ["AWS", "GCP", "Azure", "None"],
|
||||||
"13",
|
|
||||||
"12",
|
|
||||||
"11",
|
|
||||||
"10"
|
|
||||||
],
|
|
||||||
"cloud_provider": [
|
|
||||||
"AWS",
|
|
||||||
"GCP",
|
|
||||||
"Azure",
|
|
||||||
"None"
|
|
||||||
],
|
|
||||||
"mail_service": [
|
"mail_service": [
|
||||||
"Mailgun",
|
"Mailgun",
|
||||||
"Amazon SES",
|
"Amazon SES",
|
||||||
|
@ -43,22 +33,13 @@
|
||||||
],
|
],
|
||||||
"use_async": "n",
|
"use_async": "n",
|
||||||
"use_drf": "n",
|
"use_drf": "n",
|
||||||
"frontend_pipeline": [
|
"frontend_pipeline": ["None", "Django Compressor", "Gulp", "Webpack"],
|
||||||
"None",
|
|
||||||
"Django Compressor",
|
|
||||||
"Gulp"
|
|
||||||
],
|
|
||||||
"use_celery": "n",
|
"use_celery": "n",
|
||||||
"use_mailhog": "n",
|
"use_mailhog": "n",
|
||||||
"use_sentry": "n",
|
"use_sentry": "n",
|
||||||
"use_whitenoise": "n",
|
"use_whitenoise": "n",
|
||||||
"use_heroku": "n",
|
"use_heroku": "n",
|
||||||
"ci_tool": [
|
"ci_tool": ["None", "Travis", "Gitlab", "Github"],
|
||||||
"None",
|
|
||||||
"Travis",
|
|
||||||
"Gitlab",
|
|
||||||
"Github"
|
|
||||||
],
|
|
||||||
"keep_local_envs_in_vcs": "y",
|
"keep_local_envs_in_vcs": "y",
|
||||||
"debug": "n"
|
"debug": "n"
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,13 +23,13 @@ now = datetime.now()
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = []
|
extensions = ["myst_parser"]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ["_templates"]
|
templates_path = ["_templates"]
|
||||||
|
|
||||||
# The suffix of source filenames.
|
# The suffix of source filenames.
|
||||||
source_suffix = ".rst"
|
source_suffix = [".rst", ".md"]
|
||||||
|
|
||||||
# The encoding of source files.
|
# The encoding of source files.
|
||||||
# source_encoding = 'utf-8-sig'
|
# source_encoding = 'utf-8-sig'
|
||||||
|
@ -239,8 +239,7 @@ texinfo_documents = [
|
||||||
"Cookiecutter Django documentation",
|
"Cookiecutter Django documentation",
|
||||||
"Daniel Roy Greenfeld",
|
"Daniel Roy Greenfeld",
|
||||||
"Cookiecutter Django",
|
"Cookiecutter Django",
|
||||||
"A Cookiecutter template for creating production-ready "
|
"A Cookiecutter template for creating production-ready " "Django projects quickly.",
|
||||||
"Django projects quickly.",
|
|
||||||
"Miscellaneous",
|
"Miscellaneous",
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
3
docs/contributing.md
Normal file
3
docs/contributing.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
```{include} ../CONTRIBUTING.md
|
||||||
|
|
||||||
|
```
|
|
@ -12,13 +12,13 @@ Run these commands to deploy the project to Heroku:
|
||||||
|
|
||||||
heroku create --buildpack heroku/python
|
heroku create --buildpack heroku/python
|
||||||
|
|
||||||
heroku addons:create heroku-postgresql:hobby-dev
|
heroku addons:create heroku-postgresql:mini
|
||||||
# On Windows use double quotes for the time zone, e.g.
|
# On Windows use double quotes for the time zone, e.g.
|
||||||
# heroku pg:backups schedule --at "02:00 America/Los_Angeles" DATABASE_URL
|
# heroku pg:backups schedule --at "02:00 America/Los_Angeles" DATABASE_URL
|
||||||
heroku pg:backups schedule --at '02:00 America/Los_Angeles' DATABASE_URL
|
heroku pg:backups schedule --at '02:00 America/Los_Angeles' DATABASE_URL
|
||||||
heroku pg:promote DATABASE_URL
|
heroku pg:promote DATABASE_URL
|
||||||
|
|
||||||
heroku addons:create heroku-redis:hobby-dev
|
heroku addons:create heroku-redis:mini
|
||||||
|
|
||||||
# Assuming you chose Mailgun as mail service (see below for others)
|
# Assuming you chose Mailgun as mail service (see below for others)
|
||||||
heroku addons:create mailgun:starter
|
heroku addons:create mailgun:starter
|
||||||
|
@ -109,10 +109,10 @@ Or add the DSN for your account, if you already have one:
|
||||||
.. _Sentry add-on: https://elements.heroku.com/addons/sentry
|
.. _Sentry add-on: https://elements.heroku.com/addons/sentry
|
||||||
|
|
||||||
|
|
||||||
Gulp & Bootstrap compilation
|
Gulp or Webpack
|
||||||
++++++++++++++++++++++++++++
|
+++++++++++++++
|
||||||
|
|
||||||
If you've opted for Gulp, you'll most likely need to setup
|
If you've opted for Gulp or Webpack as frontend pipeline, you'll most likely need to setup
|
||||||
your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
@ -121,7 +121,7 @@ your app to use `multiple buildpacks`_: one for Python & one for Node.js:
|
||||||
|
|
||||||
At time of writing, this should do the trick: during deployment,
|
At time of writing, this should do the trick: during deployment,
|
||||||
the Heroku should run ``npm install`` and then ``npm build``,
|
the Heroku should run ``npm install`` and then ``npm build``,
|
||||||
which runs Gulp in cookiecutter-django.
|
which run the SASS compilation & JS bundling.
|
||||||
|
|
||||||
If things don't work, please refer to the Heroku docs.
|
If things don't work, please refer to the Heroku docs.
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ Make sure your project is fully committed and pushed up to Bitbucket or Github o
|
||||||
mkvirtualenv --python=/usr/bin/python3.10 my-project-name
|
mkvirtualenv --python=/usr/bin/python3.10 my-project-name
|
||||||
pip install -r requirements/production.txt # may take a few minutes
|
pip install -r requirements/production.txt # may take a few minutes
|
||||||
|
|
||||||
|
.. note:: We're creating the virtualenv using Python 3.10 (``--python=/usr/bin/python3.10```), although Cookiecutter Django generates a project for Python 3.11. This is because, at time of writing, PythonAnywhere only supports Python 3.10. It shouldn't be a problem, but if is, you may try changing the Python version to 3.11 and see if it works. If it does, please let us know, or even better, submit a pull request to update this section.
|
||||||
|
|
||||||
Setting environment variables in the console
|
Setting environment variables in the console
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
|
@ -84,6 +84,32 @@ You can read more about this feature and how to configure it, at `Automatic HTTP
|
||||||
|
|
||||||
.. _Automatic HTTPS: https://docs.traefik.io/https/acme/
|
.. _Automatic HTTPS: https://docs.traefik.io/https/acme/
|
||||||
|
|
||||||
|
.. _webpack-whitenoise-limitation:
|
||||||
|
|
||||||
|
Webpack without Whitenoise limitation
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
If you opt for Webpack without Whitenoise, Webpack needs to know the static URL at build time, when running ``docker-compose build`` (See ``webpack/prod.config.js``). Depending on your setup, this URL may come from the following environment variables:
|
||||||
|
|
||||||
|
- ``AWS_STORAGE_BUCKET_NAME``
|
||||||
|
- ``DJANGO_AWS_S3_CUSTOM_DOMAIN``
|
||||||
|
- ``DJANGO_GCP_STORAGE_BUCKET_NAME``
|
||||||
|
- ``DJANGO_AZURE_CONTAINER_NAME``
|
||||||
|
|
||||||
|
The Django settings are getting these values at runtime via the ``.envs/.production/.django`` file , but Docker does not read this file at build time, it only look for a ``.env`` in the root of the project. Failing to pass the values correctly will result in a page without CSS styles nor javascript.
|
||||||
|
|
||||||
|
To solve this, you can either:
|
||||||
|
|
||||||
|
1. merge all the env files into ``.env`` by running::
|
||||||
|
|
||||||
|
merge_production_dotenvs_in_dotenv.py
|
||||||
|
|
||||||
|
2. create a ``.env`` file in the root of the project with just variables you need. You'll need to also define them in ``.envs/.production/.django`` (hence duplicating them).
|
||||||
|
3. set these variables when running the build command::
|
||||||
|
|
||||||
|
DJANGO_AWS_S3_CUSTOM_DOMAIN=example.com docker-compose -f production.yml build``.
|
||||||
|
|
||||||
|
None of these options are ideal, we're open to suggestions on how to improve this. If you think you have one, please open an issue or a pull request.
|
||||||
|
|
||||||
(Optional) Postgres Data Volume Modifications
|
(Optional) Postgres Data Volume Modifications
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -161,3 +187,7 @@ For status check, run::
|
||||||
|
|
||||||
supervisorctl status
|
supervisorctl status
|
||||||
|
|
||||||
|
Media files without cloud provider
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
If you chose no cloud provider and Docker, the media files will be served by an nginx service, from a ``production_django_media`` volume. Make sure to keep this around to avoid losing any media files.
|
||||||
|
|
|
@ -144,6 +144,19 @@ This tells our computer that all future commands are specifically for the dev1 m
|
||||||
|
|
||||||
$ eval "$(docker-machine env dev1)"
|
$ eval "$(docker-machine env dev1)"
|
||||||
|
|
||||||
|
Add 3rd party python packages
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To install a new 3rd party python package, you cannot use ``pip install <package_name>``, that would only add the package to the container. The container is ephemeral, so that new library won't be persisted if you run another container. Instead, you should modify the Docker image:
|
||||||
|
You have to modify the relevant requirement file: base, local or production by adding: ::
|
||||||
|
|
||||||
|
<package_name>==<package_version>
|
||||||
|
|
||||||
|
To get this change picked up, you'll need to rebuild the image(s) and restart the running container: ::
|
||||||
|
|
||||||
|
docker-compose -f local.yml build
|
||||||
|
docker-compose -f local.yml up
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
|
@ -213,6 +226,11 @@ By default, it's enabled both in local and production environments (``local.yml`
|
||||||
|
|
||||||
.. _`Flower`: https://github.com/mher/flower
|
.. _`Flower`: https://github.com/mher/flower
|
||||||
|
|
||||||
|
Using Webpack or Gulp
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
When using Webpack or Gulp as the ``frontend_pipeline`` option, you should access your application at the address of the ``node`` service in order to see your correct styles. This is http://localhost:3000 by default. When using any of the other ``frontend_pipeline`` options, you should use the address of the ``django`` service, http://localhost:8000.
|
||||||
|
|
||||||
Developing locally with HTTPS
|
Developing locally with HTTPS
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ Setting Up Development Environment
|
||||||
|
|
||||||
Make sure to have the following on your host:
|
Make sure to have the following on your host:
|
||||||
|
|
||||||
* Python 3.10
|
* Python 3.11
|
||||||
* PostgreSQL_.
|
* PostgreSQL_.
|
||||||
* Redis_, if using Celery
|
* Redis_, if using Celery
|
||||||
* Cookiecutter_
|
* Cookiecutter_
|
||||||
|
@ -18,7 +18,7 @@ First things first.
|
||||||
|
|
||||||
#. Create a virtualenv: ::
|
#. Create a virtualenv: ::
|
||||||
|
|
||||||
$ python3.10 -m venv <virtual env path>
|
$ python3.11 -m venv <virtual env path>
|
||||||
|
|
||||||
#. Activate the virtualenv you have just created: ::
|
#. Activate the virtualenv you have just created: ::
|
||||||
|
|
||||||
|
@ -172,9 +172,9 @@ You can also use Django admin to queue up tasks, thanks to the `django-celerybea
|
||||||
Sass Compilation & Live Reloading
|
Sass Compilation & Live Reloading
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
If you've opted for Gulp as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
|
If you've opted for Gulp or Webpack as front-end pipeline, the project comes configured with `Sass`_ compilation and `live reloading`_. As you change you Sass/JS source files, the task runner will automatically rebuild the corresponding CSS and JS assets and reload them in your browser without refreshing the page.
|
||||||
|
|
||||||
#. Make sure that `Node.js`_ v16 is installed on your machine.
|
#. Make sure that `Node.js`_ v18 is installed on your machine.
|
||||||
#. In the project root, install the JS dependencies with::
|
#. In the project root, install the JS dependencies with::
|
||||||
|
|
||||||
$ npm install
|
$ npm install
|
||||||
|
|
|
@ -4,4 +4,3 @@ Generate a new cookiecutter-django project: ::
|
||||||
|
|
||||||
For more information refer to
|
For more information refer to
|
||||||
:ref:`Project Generation Options <template-options>`.
|
:ref:`Project Generation Options <template-options>`.
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ Contents
|
||||||
websocket
|
websocket
|
||||||
faq
|
faq
|
||||||
troubleshooting
|
troubleshooting
|
||||||
|
contributing
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
------------------
|
------------------
|
||||||
|
|
|
@ -24,6 +24,13 @@ author_name:
|
||||||
email:
|
email:
|
||||||
The email address you want to identify yourself in the project.
|
The email address you want to identify yourself in the project.
|
||||||
|
|
||||||
|
username_type:
|
||||||
|
The type of username you want to use in the project. This can be either
|
||||||
|
``username`` or ``email``. If you choose ``username``, the ``email`` field
|
||||||
|
will be included. If you choose ``email``, the ``username`` field will be
|
||||||
|
excluded. It is best practice to always include an email field, so there is
|
||||||
|
no option for having just the ``username`` field.
|
||||||
|
|
||||||
domain_name:
|
domain_name:
|
||||||
The domain name you plan to use for your project once it goes live.
|
The domain name you plan to use for your project once it goes live.
|
||||||
Note that it can be safely changed later on whenever you need to.
|
Note that it can be safely changed later on whenever you need to.
|
||||||
|
@ -46,20 +53,25 @@ timezone:
|
||||||
windows:
|
windows:
|
||||||
Indicates whether the project should be configured for development on Windows.
|
Indicates whether the project should be configured for development on Windows.
|
||||||
|
|
||||||
use_pycharm:
|
editor:
|
||||||
Indicates whether the project should be configured for development with PyCharm_.
|
Select an editor to use. The choices are:
|
||||||
|
|
||||||
|
1. None
|
||||||
|
2. PyCharm_
|
||||||
|
3. `VS Code`_
|
||||||
|
|
||||||
use_docker:
|
use_docker:
|
||||||
Indicates whether the project should be configured to use Docker_ and `Docker Compose`_.
|
Indicates whether the project should be configured to use Docker_, `Docker Compose`_ and `devcontainer`_.
|
||||||
|
|
||||||
postgresql_version:
|
postgresql_version:
|
||||||
Select a PostgreSQL_ version to use. The choices are:
|
Select a PostgreSQL_ version to use. The choices are:
|
||||||
|
|
||||||
1. 14
|
1. 15
|
||||||
2. 13
|
2. 14
|
||||||
3. 12
|
3. 13
|
||||||
4. 11
|
4. 12
|
||||||
5. 10
|
5. 11
|
||||||
|
6. 10
|
||||||
|
|
||||||
cloud_provider:
|
cloud_provider:
|
||||||
Select a cloud provider for static & media files. The choices are:
|
Select a cloud provider for static & media files. The choices are:
|
||||||
|
@ -69,7 +81,7 @@ cloud_provider:
|
||||||
3. Azure_
|
3. Azure_
|
||||||
4. None
|
4. None
|
||||||
|
|
||||||
Note that if you choose no cloud provider, media files won't work.
|
If you choose no cloud provider and docker, the production stack will serve the media files via an nginx Docker service. Without Docker, the media files won't work.
|
||||||
|
|
||||||
mail_service:
|
mail_service:
|
||||||
Select an email service that Django-Anymail provides
|
Select an email service that Django-Anymail provides
|
||||||
|
@ -95,7 +107,10 @@ frontend_pipeline:
|
||||||
|
|
||||||
1. None
|
1. None
|
||||||
2. `Django Compressor`_
|
2. `Django Compressor`_
|
||||||
3. `Gulp`_: support Bootstrap recompilation with real-time variables alteration.
|
3. `Gulp`_
|
||||||
|
4. `Webpack`_
|
||||||
|
|
||||||
|
Both Gulp and Webpack support Bootstrap recompilation with real-time variables alteration.
|
||||||
|
|
||||||
use_celery:
|
use_celery:
|
||||||
Indicates whether the project should be configured to use Celery_.
|
Indicates whether the project should be configured to use Celery_.
|
||||||
|
@ -138,13 +153,16 @@ debug:
|
||||||
.. _Apache Software License 2.0: http://www.apache.org/licenses/LICENSE-2.0
|
.. _Apache Software License 2.0: http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
.. _PyCharm: https://www.jetbrains.com/pycharm/
|
.. _PyCharm: https://www.jetbrains.com/pycharm/
|
||||||
|
.. _VS Code: https://github.com/microsoft/vscode
|
||||||
|
|
||||||
.. _Docker: https://github.com/docker/docker
|
.. _Docker: https://github.com/docker/docker
|
||||||
.. _Docker Compose: https://docs.docker.com/compose/
|
.. _Docker Compose: https://docs.docker.com/compose/
|
||||||
|
.. _devcontainer: https://containers.dev/
|
||||||
|
|
||||||
.. _PostgreSQL: https://www.postgresql.org/docs/
|
.. _PostgreSQL: https://www.postgresql.org/docs/
|
||||||
|
|
||||||
.. _Gulp: https://github.com/gulpjs/gulp
|
.. _Gulp: https://github.com/gulpjs/gulp
|
||||||
|
.. _Webpack: https://webpack.js.org
|
||||||
|
|
||||||
.. _AWS: https://aws.amazon.com/s3/
|
.. _AWS: https://aws.amazon.com/s3/
|
||||||
.. _GCP: https://cloud.google.com/storage/
|
.. _GCP: https://cloud.google.com/storage/
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
sphinx==5.3.0
|
sphinx==6.2.1
|
||||||
sphinx-rtd-theme==1.1.1
|
sphinx-rtd-theme==1.2.2
|
||||||
|
myst-parser==2.0.0
|
||||||
|
|
|
@ -22,7 +22,6 @@ DATABASE_URL DATABASES auto w/ Dock
|
||||||
DJANGO_ADMIN_URL n/a 'admin/' raises error
|
DJANGO_ADMIN_URL n/a 'admin/' raises error
|
||||||
DJANGO_DEBUG DEBUG True False
|
DJANGO_DEBUG DEBUG True False
|
||||||
DJANGO_SECRET_KEY SECRET_KEY auto-generated raises error
|
DJANGO_SECRET_KEY SECRET_KEY auto-generated raises error
|
||||||
DJANGO_SECURE_BROWSER_XSS_FILTER SECURE_BROWSER_XSS_FILTER n/a True
|
|
||||||
DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True
|
DJANGO_SECURE_SSL_REDIRECT SECURE_SSL_REDIRECT n/a True
|
||||||
DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True
|
DJANGO_SECURE_CONTENT_TYPE_NOSNIFF SECURE_CONTENT_TYPE_NOSNIFF n/a True
|
||||||
DJANGO_SECURE_FRAME_DENY SECURE_FRAME_DENY n/a True
|
DJANGO_SECURE_FRAME_DENY SECURE_FRAME_DENY n/a True
|
||||||
|
@ -82,3 +81,6 @@ Other Environment Settings
|
||||||
|
|
||||||
DJANGO_ACCOUNT_ALLOW_REGISTRATION (=True)
|
DJANGO_ACCOUNT_ALLOW_REGISTRATION (=True)
|
||||||
Allow enable or disable user registration through `django-allauth` without disabling other characteristics like authentication and account management. (Django Setting: ACCOUNT_ALLOW_REGISTRATION)
|
Allow enable or disable user registration through `django-allauth` without disabling other characteristics like authentication and account management. (Django Setting: ACCOUNT_ALLOW_REGISTRATION)
|
||||||
|
|
||||||
|
DJANGO_ADMIN_FORCE_ALLAUTH (=False)
|
||||||
|
Force the `admin` sign in process to go through the `django-allauth` workflow.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
Troubleshooting
|
Troubleshooting
|
||||||
=====================================
|
===============
|
||||||
|
|
||||||
This page contains some advice about errors and problems commonly encountered during the development of Cookiecutter Django applications.
|
This page contains some advice about errors and problems commonly encountered during the development of Cookiecutter Django applications.
|
||||||
|
|
||||||
|
@ -38,6 +38,16 @@ To fix this, you can either:
|
||||||
.. _rm: https://docs.docker.com/engine/reference/commandline/volume_rm/
|
.. _rm: https://docs.docker.com/engine/reference/commandline/volume_rm/
|
||||||
.. _prune: https://docs.docker.com/v17.09/engine/reference/commandline/system_prune/
|
.. _prune: https://docs.docker.com/v17.09/engine/reference/commandline/system_prune/
|
||||||
|
|
||||||
|
Variable is not set. Defaulting to a blank string
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
WARN[0000] The "DJANGO_AWS_STORAGE_BUCKET_NAME" variable is not set. Defaulting to a blank string.
|
||||||
|
WARN[0000] The "DJANGO_AWS_S3_CUSTOM_DOMAIN" variable is not set. Defaulting to a blank string.
|
||||||
|
|
||||||
|
You have probably opted for Docker + Webpack without Whitenoise. This is a know limitation of the combination, which needs a little bit of manual intervention. See the :ref:`dedicated section about it <webpack-whitenoise-limitation>`.
|
||||||
|
|
||||||
Others
|
Others
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ TODO: restrict Cookiecutter Django project initialization to
|
||||||
"""
|
"""
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
|
@ -44,6 +45,24 @@ def remove_gplv3_files():
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_custom_user_manager_files():
|
||||||
|
os.remove(
|
||||||
|
os.path.join(
|
||||||
|
"{{cookiecutter.project_slug}}",
|
||||||
|
"users",
|
||||||
|
"managers.py",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
os.remove(
|
||||||
|
os.path.join(
|
||||||
|
"{{cookiecutter.project_slug}}",
|
||||||
|
"users",
|
||||||
|
"tests",
|
||||||
|
"test_managers.py",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def remove_pycharm_files():
|
def remove_pycharm_files():
|
||||||
idea_dir_path = ".idea"
|
idea_dir_path = ".idea"
|
||||||
if os.path.exists(idea_dir_path):
|
if os.path.exists(idea_dir_path):
|
||||||
|
@ -55,12 +74,13 @@ def remove_pycharm_files():
|
||||||
|
|
||||||
|
|
||||||
def remove_docker_files():
|
def remove_docker_files():
|
||||||
|
shutil.rmtree(".devcontainer")
|
||||||
shutil.rmtree("compose")
|
shutil.rmtree("compose")
|
||||||
|
|
||||||
file_names = ["local.yml", "production.yml", ".dockerignore"]
|
file_names = ["local.yml", "production.yml", ".dockerignore"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
if "{{ cookiecutter.use_pycharm }}".lower() == "y":
|
if "{{ cookiecutter.editor }}".lower() == "PyCharm":
|
||||||
file_names = ["docker_compose_up_django.xml", "docker_compose_up_docs.xml"]
|
file_names = ["docker_compose_up_django.xml", "docker_compose_up_docs.xml"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
os.remove(os.path.join(".idea", "runConfigurations", file_name))
|
os.remove(os.path.join(".idea", "runConfigurations", file_name))
|
||||||
|
@ -73,29 +93,37 @@ def remove_utility_files():
|
||||||
def remove_heroku_files():
|
def remove_heroku_files():
|
||||||
file_names = ["Procfile", "runtime.txt", "requirements.txt"]
|
file_names = ["Procfile", "runtime.txt", "requirements.txt"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
if (
|
if file_name == "requirements.txt" and "{{ cookiecutter.ci_tool }}".lower() == "travis":
|
||||||
file_name == "requirements.txt"
|
|
||||||
and "{{ cookiecutter.ci_tool }}".lower() == "travis"
|
|
||||||
):
|
|
||||||
# don't remove the file if we are using travisci but not using heroku
|
# don't remove the file if we are using travisci but not using heroku
|
||||||
continue
|
continue
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
remove_heroku_build_hooks()
|
|
||||||
|
|
||||||
|
|
||||||
def remove_heroku_build_hooks():
|
|
||||||
shutil.rmtree("bin")
|
shutil.rmtree("bin")
|
||||||
|
|
||||||
|
|
||||||
|
def remove_sass_files():
|
||||||
|
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass"))
|
||||||
|
|
||||||
|
|
||||||
def remove_gulp_files():
|
def remove_gulp_files():
|
||||||
file_names = ["gulpfile.js"]
|
file_names = ["gulpfile.js"]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
remove_sass_files()
|
|
||||||
|
|
||||||
|
|
||||||
def remove_sass_files():
|
def remove_webpack_files():
|
||||||
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "static", "sass"))
|
shutil.rmtree("webpack")
|
||||||
|
remove_vendors_js()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_vendors_js():
|
||||||
|
vendors_js_path = os.path.join(
|
||||||
|
"{{ cookiecutter.project_slug }}",
|
||||||
|
"static",
|
||||||
|
"js",
|
||||||
|
"vendors.js",
|
||||||
|
)
|
||||||
|
if os.path.exists(vendors_js_path):
|
||||||
|
os.remove(vendors_js_path)
|
||||||
|
|
||||||
|
|
||||||
def remove_packagejson_file():
|
def remove_packagejson_file():
|
||||||
|
@ -104,13 +132,86 @@ def remove_packagejson_file():
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
|
||||||
|
|
||||||
|
def update_package_json(remove_dev_deps=None, remove_keys=None, scripts=None):
|
||||||
|
remove_dev_deps = remove_dev_deps or []
|
||||||
|
remove_keys = remove_keys or []
|
||||||
|
scripts = scripts or {}
|
||||||
|
with open("package.json", mode="r") as fd:
|
||||||
|
content = json.load(fd)
|
||||||
|
for package_name in remove_dev_deps:
|
||||||
|
content["devDependencies"].pop(package_name)
|
||||||
|
for key in remove_keys:
|
||||||
|
content.pop(key)
|
||||||
|
content["scripts"].update(scripts)
|
||||||
|
with open("package.json", mode="w") as fd:
|
||||||
|
json.dump(content, fd, ensure_ascii=False, indent=2)
|
||||||
|
fd.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
def handle_js_runner(choice, use_docker, use_async):
|
||||||
|
if choice == "Gulp":
|
||||||
|
update_package_json(
|
||||||
|
remove_dev_deps=[
|
||||||
|
"@babel/core",
|
||||||
|
"@babel/preset-env",
|
||||||
|
"babel-loader",
|
||||||
|
"concurrently",
|
||||||
|
"css-loader",
|
||||||
|
"mini-css-extract-plugin",
|
||||||
|
"postcss-loader",
|
||||||
|
"postcss-preset-env",
|
||||||
|
"sass-loader",
|
||||||
|
"webpack",
|
||||||
|
"webpack-bundle-tracker",
|
||||||
|
"webpack-cli",
|
||||||
|
"webpack-dev-server",
|
||||||
|
"webpack-merge",
|
||||||
|
],
|
||||||
|
remove_keys=["babel"],
|
||||||
|
scripts={
|
||||||
|
"dev": "gulp",
|
||||||
|
"build": "gulp generate-assets",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
remove_webpack_files()
|
||||||
|
elif choice == "Webpack":
|
||||||
|
scripts = {
|
||||||
|
"dev": "webpack serve --config webpack/dev.config.js",
|
||||||
|
"build": "webpack --config webpack/prod.config.js",
|
||||||
|
}
|
||||||
|
remove_dev_deps = [
|
||||||
|
"browser-sync",
|
||||||
|
"cssnano",
|
||||||
|
"gulp",
|
||||||
|
"gulp-imagemin",
|
||||||
|
"gulp-plumber",
|
||||||
|
"gulp-postcss",
|
||||||
|
"gulp-rename",
|
||||||
|
"gulp-sass",
|
||||||
|
"gulp-uglify-es",
|
||||||
|
]
|
||||||
|
if not use_docker:
|
||||||
|
dev_django_cmd = (
|
||||||
|
"uvicorn config.asgi:application --reload" if use_async else "python manage.py runserver_plus"
|
||||||
|
)
|
||||||
|
scripts.update(
|
||||||
|
{
|
||||||
|
"dev": "concurrently npm:dev:*",
|
||||||
|
"dev:webpack": "webpack serve --config webpack/dev.config.js",
|
||||||
|
"dev:django": dev_django_cmd,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
remove_dev_deps.append("concurrently")
|
||||||
|
update_package_json(remove_dev_deps=remove_dev_deps, scripts=scripts)
|
||||||
|
remove_gulp_files()
|
||||||
|
|
||||||
|
|
||||||
def remove_celery_files():
|
def remove_celery_files():
|
||||||
file_names = [
|
file_names = [
|
||||||
os.path.join("config", "celery_app.py"),
|
os.path.join("config", "celery_app.py"),
|
||||||
os.path.join("{{ cookiecutter.project_slug }}", "users", "tasks.py"),
|
os.path.join("{{ cookiecutter.project_slug }}", "users", "tasks.py"),
|
||||||
os.path.join(
|
os.path.join("{{ cookiecutter.project_slug }}", "users", "tests", "test_tasks.py"),
|
||||||
"{{ cookiecutter.project_slug }}", "users", "tests", "test_tasks.py"
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
for file_name in file_names:
|
for file_name in file_names:
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
@ -137,9 +238,7 @@ def remove_dotgithub_folder():
|
||||||
shutil.rmtree(".github")
|
shutil.rmtree(".github")
|
||||||
|
|
||||||
|
|
||||||
def generate_random_string(
|
def generate_random_string(length, using_digits=False, using_ascii_letters=False, using_punctuation=False):
|
||||||
length, using_digits=False, using_ascii_letters=False, using_punctuation=False
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Example:
|
Example:
|
||||||
opting out for 50 symbol-long, [a-z][A-Z][0-9] string
|
opting out for 50 symbol-long, [a-z][A-Z][0-9] string
|
||||||
|
@ -233,9 +332,7 @@ def set_postgres_password(file_path, value=None):
|
||||||
|
|
||||||
|
|
||||||
def set_celery_flower_user(file_path, value):
|
def set_celery_flower_user(file_path, value):
|
||||||
celery_flower_user = set_flag(
|
celery_flower_user = set_flag(file_path, "!!!SET CELERY_FLOWER_USER!!!", value=value)
|
||||||
file_path, "!!!SET CELERY_FLOWER_USER!!!", value=value
|
|
||||||
)
|
|
||||||
return celery_flower_user
|
return celery_flower_user
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,22 +364,14 @@ def set_flags_in_envs(postgres_user, celery_flower_user, debug=False):
|
||||||
set_django_admin_url(production_django_envs_path)
|
set_django_admin_url(production_django_envs_path)
|
||||||
|
|
||||||
set_postgres_user(local_postgres_envs_path, value=postgres_user)
|
set_postgres_user(local_postgres_envs_path, value=postgres_user)
|
||||||
set_postgres_password(
|
set_postgres_password(local_postgres_envs_path, value=DEBUG_VALUE if debug else None)
|
||||||
local_postgres_envs_path, value=DEBUG_VALUE if debug else None
|
|
||||||
)
|
|
||||||
set_postgres_user(production_postgres_envs_path, value=postgres_user)
|
set_postgres_user(production_postgres_envs_path, value=postgres_user)
|
||||||
set_postgres_password(
|
set_postgres_password(production_postgres_envs_path, value=DEBUG_VALUE if debug else None)
|
||||||
production_postgres_envs_path, value=DEBUG_VALUE if debug else None
|
|
||||||
)
|
|
||||||
|
|
||||||
set_celery_flower_user(local_django_envs_path, value=celery_flower_user)
|
set_celery_flower_user(local_django_envs_path, value=celery_flower_user)
|
||||||
set_celery_flower_password(
|
set_celery_flower_password(local_django_envs_path, value=DEBUG_VALUE if debug else None)
|
||||||
local_django_envs_path, value=DEBUG_VALUE if debug else None
|
|
||||||
)
|
|
||||||
set_celery_flower_user(production_django_envs_path, value=celery_flower_user)
|
set_celery_flower_user(production_django_envs_path, value=celery_flower_user)
|
||||||
set_celery_flower_password(
|
set_celery_flower_password(production_django_envs_path, value=DEBUG_VALUE if debug else None)
|
||||||
production_django_envs_path, value=DEBUG_VALUE if debug else None
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def set_flags_in_settings_files():
|
def set_flags_in_settings_files():
|
||||||
|
@ -293,6 +382,7 @@ def set_flags_in_settings_files():
|
||||||
def remove_envs_and_associated_files():
|
def remove_envs_and_associated_files():
|
||||||
shutil.rmtree(".envs")
|
shutil.rmtree(".envs")
|
||||||
os.remove("merge_production_dotenvs_in_dotenv.py")
|
os.remove("merge_production_dotenvs_in_dotenv.py")
|
||||||
|
shutil.rmtree("tests")
|
||||||
|
|
||||||
|
|
||||||
def remove_celery_compose_dirs():
|
def remove_celery_compose_dirs():
|
||||||
|
@ -311,21 +401,9 @@ def remove_aws_dockerfile():
|
||||||
def remove_drf_starter_files():
|
def remove_drf_starter_files():
|
||||||
os.remove(os.path.join("config", "api_router.py"))
|
os.remove(os.path.join("config", "api_router.py"))
|
||||||
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "users", "api"))
|
shutil.rmtree(os.path.join("{{cookiecutter.project_slug}}", "users", "api"))
|
||||||
os.remove(
|
os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_drf_urls.py"))
|
||||||
os.path.join(
|
os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_drf_views.py"))
|
||||||
"{{cookiecutter.project_slug}}", "users", "tests", "test_drf_urls.py"
|
os.remove(os.path.join("{{cookiecutter.project_slug}}", "users", "tests", "test_swagger.py"))
|
||||||
)
|
|
||||||
)
|
|
||||||
os.remove(
|
|
||||||
os.path.join(
|
|
||||||
"{{cookiecutter.project_slug}}", "users", "tests", "test_drf_views.py"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
os.remove(
|
|
||||||
os.path.join(
|
|
||||||
"{{cookiecutter.project_slug}}", "users", "tests", "test_swagger.py"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def remove_storages_module():
|
def remove_storages_module():
|
||||||
|
@ -347,7 +425,10 @@ def main():
|
||||||
if "{{ cookiecutter.open_source_license}}" != "GPLv3":
|
if "{{ cookiecutter.open_source_license}}" != "GPLv3":
|
||||||
remove_gplv3_files()
|
remove_gplv3_files()
|
||||||
|
|
||||||
if "{{ cookiecutter.use_pycharm }}".lower() == "n":
|
if "{{ cookiecutter.username_type }}" == "username":
|
||||||
|
remove_custom_user_manager_files()
|
||||||
|
|
||||||
|
if "{{ cookiecutter.editor }}".lower() != "PyCharm":
|
||||||
remove_pycharm_files()
|
remove_pycharm_files()
|
||||||
|
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
|
@ -355,26 +436,18 @@ def main():
|
||||||
else:
|
else:
|
||||||
remove_docker_files()
|
remove_docker_files()
|
||||||
|
|
||||||
if (
|
if "{{ cookiecutter.use_docker }}".lower() == "y" and "{{ cookiecutter.cloud_provider}}" != "AWS":
|
||||||
"{{ cookiecutter.use_docker }}".lower() == "y"
|
|
||||||
and "{{ cookiecutter.cloud_provider}}" != "AWS"
|
|
||||||
):
|
|
||||||
remove_aws_dockerfile()
|
remove_aws_dockerfile()
|
||||||
|
|
||||||
if "{{ cookiecutter.use_heroku }}".lower() == "n":
|
if "{{ cookiecutter.use_heroku }}".lower() == "n":
|
||||||
remove_heroku_files()
|
remove_heroku_files()
|
||||||
elif "{{ cookiecutter.frontend_pipeline }}" != "Django Compressor":
|
|
||||||
remove_heroku_build_hooks()
|
|
||||||
|
|
||||||
if (
|
if "{{ cookiecutter.use_docker }}".lower() == "n" and "{{ cookiecutter.use_heroku }}".lower() == "n":
|
||||||
"{{ cookiecutter.use_docker }}".lower() == "n"
|
|
||||||
and "{{ cookiecutter.use_heroku }}".lower() == "n"
|
|
||||||
):
|
|
||||||
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
||||||
print(
|
print(
|
||||||
INFO + ".env(s) are only utilized when Docker Compose and/or "
|
INFO + ".env(s) are only utilized when Docker Compose and/or "
|
||||||
"Heroku support is enabled so keeping them does not "
|
"Heroku support is enabled so keeping them does not make sense "
|
||||||
"make sense given your current setup." + TERMINATOR
|
"given your current setup." + TERMINATOR
|
||||||
)
|
)
|
||||||
remove_envs_and_associated_files()
|
remove_envs_and_associated_files()
|
||||||
else:
|
else:
|
||||||
|
@ -383,15 +456,23 @@ def main():
|
||||||
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
if "{{ cookiecutter.keep_local_envs_in_vcs }}".lower() == "y":
|
||||||
append_to_gitignore_file("!.envs/.local/")
|
append_to_gitignore_file("!.envs/.local/")
|
||||||
|
|
||||||
if "{{ cookiecutter.frontend_pipeline }}" != "Gulp":
|
if "{{ cookiecutter.frontend_pipeline }}" in ["None", "Django Compressor"]:
|
||||||
remove_gulp_files()
|
remove_gulp_files()
|
||||||
|
remove_webpack_files()
|
||||||
|
remove_sass_files()
|
||||||
remove_packagejson_file()
|
remove_packagejson_file()
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
if "{{ cookiecutter.use_docker }}".lower() == "y":
|
||||||
remove_node_dockerfile()
|
remove_node_dockerfile()
|
||||||
|
else:
|
||||||
|
handle_js_runner(
|
||||||
|
"{{ cookiecutter.frontend_pipeline }}",
|
||||||
|
use_docker=("{{ cookiecutter.use_docker }}".lower() == "y"),
|
||||||
|
use_async=("{{ cookiecutter.use_async }}".lower() == "y"),
|
||||||
|
)
|
||||||
|
|
||||||
if "{{ cookiecutter.cloud_provider}}" == "None":
|
if "{{ cookiecutter.cloud_provider }}" == "None" and "{{ cookiecutter.use_docker }}".lower() == "n":
|
||||||
print(
|
print(
|
||||||
WARNING + "You chose not to use a cloud provider, "
|
WARNING + "You chose to not use any cloud providers nor Docker, "
|
||||||
"media files won't be served in production." + TERMINATOR
|
"media files won't be served in production." + TERMINATOR
|
||||||
)
|
)
|
||||||
remove_storages_module()
|
remove_storages_module()
|
||||||
|
|
|
@ -17,26 +17,28 @@ INFO = "\x1b[1;33m [INFO]: "
|
||||||
HINT = "\x1b[3;33m"
|
HINT = "\x1b[3;33m"
|
||||||
SUCCESS = "\x1b[1;32m [SUCCESS]: "
|
SUCCESS = "\x1b[1;32m [SUCCESS]: "
|
||||||
|
|
||||||
|
# The content of this string is evaluated by Jinja, and plays an important role.
|
||||||
|
# It updates the cookiecutter context to trim leading and trailing spaces
|
||||||
|
# from domain/email values
|
||||||
|
"""
|
||||||
|
{{ cookiecutter.update({ "domain_name": cookiecutter.domain_name | trim }) }}
|
||||||
|
{{ cookiecutter.update({ "email": cookiecutter.email | trim }) }}
|
||||||
|
"""
|
||||||
|
|
||||||
project_slug = "{{ cookiecutter.project_slug }}"
|
project_slug = "{{ cookiecutter.project_slug }}"
|
||||||
if hasattr(project_slug, "isidentifier"):
|
if hasattr(project_slug, "isidentifier"):
|
||||||
assert (
|
assert project_slug.isidentifier(), "'{}' project slug is not a valid Python identifier.".format(project_slug)
|
||||||
project_slug.isidentifier()
|
|
||||||
), "'{}' project slug is not a valid Python identifier.".format(project_slug)
|
|
||||||
|
|
||||||
assert (
|
assert project_slug == project_slug.lower(), "'{}' project slug should be all lowercase".format(project_slug)
|
||||||
project_slug == project_slug.lower()
|
|
||||||
), "'{}' project slug should be all lowercase".format(project_slug)
|
|
||||||
|
|
||||||
assert (
|
assert "\\" not in "{{ cookiecutter.author_name }}", "Don't include backslashes in author name."
|
||||||
"\\" not in "{{ cookiecutter.author_name }}"
|
|
||||||
), "Don't include backslashes in author name."
|
|
||||||
|
|
||||||
if "{{ cookiecutter.use_docker }}".lower() == "n":
|
if "{{ cookiecutter.use_docker }}".lower() == "n":
|
||||||
python_major_version = sys.version_info[0]
|
python_major_version = sys.version_info[0]
|
||||||
if python_major_version == 2:
|
if python_major_version == 2:
|
||||||
print(
|
print(
|
||||||
WARNING + "You're running cookiecutter under Python 2, but the generated "
|
WARNING + "You're running cookiecutter under Python 2, but the generated "
|
||||||
"project requires Python 3.10+. Do you want to proceed (y/n)? " + TERMINATOR
|
"project requires Python 3.11+. Do you want to proceed (y/n)? " + TERMINATOR
|
||||||
)
|
)
|
||||||
yes_options, no_options = frozenset(["y"]), frozenset(["n"])
|
yes_options, no_options = frozenset(["y"]), frozenset(["n"])
|
||||||
while True:
|
while True:
|
||||||
|
@ -51,32 +53,16 @@ if "{{ cookiecutter.use_docker }}".lower() == "n":
|
||||||
print(
|
print(
|
||||||
HINT
|
HINT
|
||||||
+ "Please respond with {} or {}: ".format(
|
+ "Please respond with {} or {}: ".format(
|
||||||
", ".join(
|
", ".join(["'{}'".format(o) for o in yes_options if not o == ""]),
|
||||||
["'{}'".format(o) for o in yes_options if not o == ""]
|
", ".join(["'{}'".format(o) for o in no_options if not o == ""]),
|
||||||
),
|
|
||||||
", ".join(
|
|
||||||
["'{}'".format(o) for o in no_options if not o == ""]
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
+ TERMINATOR
|
+ TERMINATOR
|
||||||
)
|
)
|
||||||
|
|
||||||
if (
|
if "{{ cookiecutter.use_whitenoise }}".lower() == "n" and "{{ cookiecutter.cloud_provider }}" == "None":
|
||||||
"{{ cookiecutter.use_whitenoise }}".lower() == "n"
|
print("You should either use Whitenoise or select a " "Cloud Provider to serve static files")
|
||||||
and "{{ cookiecutter.cloud_provider }}" == "None"
|
|
||||||
):
|
|
||||||
print(
|
|
||||||
"You should either use Whitenoise or select a "
|
|
||||||
"Cloud Provider to serve static files"
|
|
||||||
)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if (
|
if "{{ cookiecutter.mail_service }}" == "Amazon SES" and "{{ cookiecutter.cloud_provider }}" != "AWS":
|
||||||
"{{ cookiecutter.mail_service }}" == "Amazon SES"
|
print("You should either use AWS or select a different " "Mail Service for sending emails.")
|
||||||
and "{{ cookiecutter.cloud_provider }}" != "AWS"
|
|
||||||
):
|
|
||||||
print(
|
|
||||||
"You should either use AWS or select a different "
|
|
||||||
"Mail Service for sending emails."
|
|
||||||
)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
50
pyproject.toml
Normal file
50
pyproject.toml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# ==== pytest ====
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
addopts = "-v --tb=short"
|
||||||
|
norecursedirs = [
|
||||||
|
".tox",
|
||||||
|
".git",
|
||||||
|
"*/migrations/*",
|
||||||
|
"*/static/*",
|
||||||
|
"docs",
|
||||||
|
"venv",
|
||||||
|
"*/{{cookiecutter.project_slug}}/*",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ==== black ====
|
||||||
|
[tool.black]
|
||||||
|
line-length = 119
|
||||||
|
target-version = ['py311']
|
||||||
|
|
||||||
|
|
||||||
|
# ==== isort ====
|
||||||
|
[tool.isort]
|
||||||
|
profile = "black"
|
||||||
|
line_length = 119
|
||||||
|
known_first_party = [
|
||||||
|
"tests",
|
||||||
|
"scripts",
|
||||||
|
"hooks",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ==== djLint ====
|
||||||
|
[tool.djlint]
|
||||||
|
blank_line_after_tag = "load,extends"
|
||||||
|
close_void_tags = true
|
||||||
|
format_css = true
|
||||||
|
format_js = true
|
||||||
|
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687
|
||||||
|
ignore = "H006,H030,H031,T002,T028"
|
||||||
|
ignore_blocks = "raw"
|
||||||
|
include = "H017,H035"
|
||||||
|
indent = 2
|
||||||
|
max_line_length = 119
|
||||||
|
profile = "jinja"
|
||||||
|
|
||||||
|
[tool.djlint.css]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[tool.djlint.js]
|
||||||
|
indent_size = 2
|
|
@ -1,3 +0,0 @@
|
||||||
[pytest]
|
|
||||||
addopts = -v --tb=short
|
|
||||||
norecursedirs = .tox .git */migrations/* */static/* docs venv */{{cookiecutter.project_slug}}/*
|
|
|
@ -1,26 +1,28 @@
|
||||||
cookiecutter==2.1.1
|
cookiecutter==2.1.1
|
||||||
sh==1.14.3; sys_platform != "win32"
|
sh==2.0.4; sys_platform != "win32"
|
||||||
binaryornot==0.4.4
|
binaryornot==0.4.4
|
||||||
|
|
||||||
# Code quality
|
# Code quality
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
black==22.12.0
|
black==23.3.0
|
||||||
isort==5.11.4
|
isort==5.12.0
|
||||||
flake8==6.0.0
|
flake8==6.0.0
|
||||||
flake8-isort==6.0.0
|
django-upgrade==1.14.0
|
||||||
pre-commit==2.21.0
|
djlint==1.31.1
|
||||||
|
pre-commit==3.3.3
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
tox==4.2.6
|
tox==4.6.3
|
||||||
pytest==7.2.0
|
pytest==7.4.0
|
||||||
pytest-cookies==0.6.1
|
pytest-xdist==3.3.1
|
||||||
pytest-instafail==0.4.2
|
pytest-cookies==0.7.0
|
||||||
|
pytest-instafail==0.5.0
|
||||||
pyyaml==6.0
|
pyyaml==6.0
|
||||||
|
|
||||||
# Scripting
|
# Scripting
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
PyGithub==1.57
|
PyGithub==1.59.0
|
||||||
gitpython==3.1.30
|
gitpython==3.1.31
|
||||||
jinja2==3.1.2
|
jinja2==3.1.2
|
||||||
requests==2.28.1
|
requests==2.31.0
|
||||||
|
|
|
@ -141,9 +141,7 @@ class GitHubManager:
|
||||||
self.requirements_files = ["base", "local", "production"]
|
self.requirements_files = ["base", "local", "production"]
|
||||||
# Format:
|
# Format:
|
||||||
# requirement file name: {package name: (master_version, package_info)}
|
# requirement file name: {package name: (master_version, package_info)}
|
||||||
self.requirements: dict[str, dict[str, tuple[str, dict]]] = {
|
self.requirements: dict[str, dict[str, tuple[str, dict]]] = {x: {} for x in self.requirements_files}
|
||||||
x: {} for x in self.requirements_files
|
|
||||||
}
|
|
||||||
|
|
||||||
def setup(self) -> None:
|
def setup(self) -> None:
|
||||||
self.load_requirements()
|
self.load_requirements()
|
||||||
|
@ -177,11 +175,7 @@ class GitHubManager:
|
||||||
"is": "issue",
|
"is": "issue",
|
||||||
"in": "title",
|
"in": "title",
|
||||||
}
|
}
|
||||||
issues = list(
|
issues = list(self.github.search_issues("[Django Update]", "created", "desc", **qualifiers))
|
||||||
self.github.search_issues(
|
|
||||||
"[Django Update]", "created", "desc", **qualifiers
|
|
||||||
)
|
|
||||||
)
|
|
||||||
print(f"Found {len(issues)} issues matching search")
|
print(f"Found {len(issues)} issues matching search")
|
||||||
for issue in issues:
|
for issue in issues:
|
||||||
matches = re.match(r"\[Update Django] Django (\d+.\d+)$", issue.title)
|
matches = re.match(r"\[Update Django] Django (\d+.\d+)$", issue.title)
|
||||||
|
@ -194,9 +188,7 @@ class GitHubManager:
|
||||||
else:
|
else:
|
||||||
self.existing_issues[issue_version] = issue
|
self.existing_issues[issue_version] = issue
|
||||||
|
|
||||||
def get_compatibility(
|
def get_compatibility(self, package_name: str, package_info: dict, needed_dj_version: DjVersion):
|
||||||
self, package_name: str, package_info: dict, needed_dj_version: DjVersion
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Verify compatibility via setup.py classifiers. If Django is not in the
|
Verify compatibility via setup.py classifiers. If Django is not in the
|
||||||
classifiers, then default compatibility is n/a and OK is ✅.
|
classifiers, then default compatibility is n/a and OK is ✅.
|
||||||
|
@ -209,9 +201,7 @@ class GitHubManager:
|
||||||
# updated packages, or known releases that will happen but haven't yet
|
# updated packages, or known releases that will happen but haven't yet
|
||||||
if issue := self.existing_issues.get(needed_dj_version):
|
if issue := self.existing_issues.get(needed_dj_version):
|
||||||
if index := issue.body.find(package_name):
|
if index := issue.body.find(package_name):
|
||||||
name, _current, prev_compat, ok = (
|
name, _current, prev_compat, ok = (s.strip() for s in issue.body[index:].split("|", 4)[:4])
|
||||||
s.strip() for s in issue.body[index:].split("|", 4)[:4]
|
|
||||||
)
|
|
||||||
if ok in ("✅", "❓", "🕒"):
|
if ok in ("✅", "❓", "🕒"):
|
||||||
return prev_compat, ok
|
return prev_compat, ok
|
||||||
|
|
||||||
|
@ -248,9 +238,7 @@ class GitHubManager:
|
||||||
]
|
]
|
||||||
|
|
||||||
def _get_md_home_page_url(self, package_info: dict):
|
def _get_md_home_page_url(self, package_info: dict):
|
||||||
urls = [
|
urls = [package_info["info"].get(url_key) for url_key in self.HOME_PAGE_URL_KEYS]
|
||||||
package_info["info"].get(url_key) for url_key in self.HOME_PAGE_URL_KEYS
|
|
||||||
]
|
|
||||||
try:
|
try:
|
||||||
return f"[{{}}]({next(item for item in urls if item)})"
|
return f"[{{}}]({next(item for item in urls if item)})"
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
@ -259,13 +247,9 @@ class GitHubManager:
|
||||||
def generate_markdown(self, needed_dj_version: DjVersion):
|
def generate_markdown(self, needed_dj_version: DjVersion):
|
||||||
requirements = f"{needed_dj_version} requirements tables\n\n"
|
requirements = f"{needed_dj_version} requirements tables\n\n"
|
||||||
for _file in self.requirements_files:
|
for _file in self.requirements_files:
|
||||||
requirements += _TABLE_HEADER.format_map(
|
requirements += _TABLE_HEADER.format_map({"file": _file, "dj_version": needed_dj_version})
|
||||||
{"file": _file, "dj_version": needed_dj_version}
|
|
||||||
)
|
|
||||||
for package_name, (version, info) in self.requirements[_file].items():
|
for package_name, (version, info) in self.requirements[_file].items():
|
||||||
compat_version, icon = self.get_compatibility(
|
compat_version, icon = self.get_compatibility(package_name, info, needed_dj_version)
|
||||||
package_name, info, needed_dj_version
|
|
||||||
)
|
|
||||||
requirements += (
|
requirements += (
|
||||||
f"| {self._get_md_home_page_url(info).format(package_name)} "
|
f"| {self._get_md_home_page_url(info).format(package_name)} "
|
||||||
f"| {version.strip()} "
|
f"| {version.strip()} "
|
||||||
|
@ -282,9 +266,7 @@ class GitHubManager:
|
||||||
issue.edit(body=description)
|
issue.edit(body=description)
|
||||||
else:
|
else:
|
||||||
print(f"Creating new issue for Django {needed_dj_version}")
|
print(f"Creating new issue for Django {needed_dj_version}")
|
||||||
issue = self.repo.create_issue(
|
issue = self.repo.create_issue(f"[Update Django] Django {needed_dj_version}", description)
|
||||||
f"[Update Django] Django {needed_dj_version}", description
|
|
||||||
)
|
|
||||||
issue.add_to_labels(f"django{needed_dj_version}")
|
issue.add_to_labels(f"django{needed_dj_version}")
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
|
@ -297,9 +279,7 @@ class GitHubManager:
|
||||||
|
|
||||||
def main(django_max_version=None) -> None:
|
def main(django_max_version=None) -> None:
|
||||||
# Check if there are any djs
|
# Check if there are any djs
|
||||||
current_dj, latest_djs = get_all_latest_django_versions(
|
current_dj, latest_djs = get_all_latest_django_versions(django_max_version=django_max_version)
|
||||||
django_max_version=django_max_version
|
|
||||||
)
|
|
||||||
if not latest_djs:
|
if not latest_djs:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
manager = GitHubManager(current_dj, latest_djs)
|
manager = GitHubManager(current_dj, latest_djs)
|
||||||
|
@ -309,9 +289,7 @@ def main(django_max_version=None) -> None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if GITHUB_REPO is None:
|
if GITHUB_REPO is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY")
|
||||||
"No github repo, please set the environment variable GITHUB_REPOSITORY"
|
|
||||||
)
|
|
||||||
max_version = None
|
max_version = None
|
||||||
last_arg = sys.argv[-1]
|
last_arg = sys.argv[-1]
|
||||||
if CURRENT_FILE.name not in last_arg:
|
if CURRENT_FILE.name not in last_arg:
|
||||||
|
|
|
@ -82,14 +82,20 @@ def group_pulls_by_change_type(
|
||||||
grouped_pulls = {
|
grouped_pulls = {
|
||||||
"Changed": [],
|
"Changed": [],
|
||||||
"Fixed": [],
|
"Fixed": [],
|
||||||
|
"Documentation": [],
|
||||||
"Updated": [],
|
"Updated": [],
|
||||||
}
|
}
|
||||||
for pull in pull_requests_list:
|
for pull in pull_requests_list:
|
||||||
label_names = {label.name for label in pull.labels}
|
label_names = {label.name for label in pull.labels}
|
||||||
|
if "project infrastructure" in label_names:
|
||||||
|
# Don't mention it in the changelog
|
||||||
|
continue
|
||||||
if "update" in label_names:
|
if "update" in label_names:
|
||||||
group_name = "Updated"
|
group_name = "Updated"
|
||||||
elif "bug" in label_names:
|
elif "bug" in label_names:
|
||||||
group_name = "Fixed"
|
group_name = "Fixed"
|
||||||
|
elif "docs" in label_names:
|
||||||
|
group_name = "Documentation"
|
||||||
else:
|
else:
|
||||||
group_name = "Changed"
|
group_name = "Changed"
|
||||||
grouped_pulls[group_name].append(pull)
|
grouped_pulls[group_name].append(pull)
|
||||||
|
@ -148,11 +154,7 @@ def update_git_repo(paths: list[Path], release: str) -> None:
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if GITHUB_REPO is None:
|
if GITHUB_REPO is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY")
|
||||||
"No github repo, please set the environment variable GITHUB_REPOSITORY"
|
|
||||||
)
|
|
||||||
if GIT_BRANCH is None:
|
if GIT_BRANCH is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError("No git branch set, please set the GITHUB_REF_NAME environment variable")
|
||||||
"No git branch set, please set the GITHUB_REF_NAME environment variable"
|
|
||||||
)
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -44,15 +44,9 @@ def iter_recent_authors():
|
||||||
git CLI to work with Github usernames.
|
git CLI to work with Github usernames.
|
||||||
"""
|
"""
|
||||||
repo = Github(login_or_token=GITHUB_TOKEN, per_page=5).get_repo(GITHUB_REPO)
|
repo = Github(login_or_token=GITHUB_TOKEN, per_page=5).get_repo(GITHUB_REPO)
|
||||||
recent_pulls = repo.get_pulls(
|
recent_pulls = repo.get_pulls(state="closed", sort="updated", direction="desc").get_page(0)
|
||||||
state="closed", sort="updated", direction="desc"
|
|
||||||
).get_page(0)
|
|
||||||
for pull in recent_pulls:
|
for pull in recent_pulls:
|
||||||
if (
|
if pull.merged and pull.user.type == "User" and pull.user.login not in BOT_LOGINS:
|
||||||
pull.merged
|
|
||||||
and pull.user.type == "User"
|
|
||||||
and pull.user.login not in BOT_LOGINS
|
|
||||||
):
|
|
||||||
yield pull.user
|
yield pull.user
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,9 +90,7 @@ def write_md_file(contributors):
|
||||||
core_contributors = [c for c in contributors if c.get("is_core", False)]
|
core_contributors = [c for c in contributors if c.get("is_core", False)]
|
||||||
other_contributors = (c for c in contributors if not c.get("is_core", False))
|
other_contributors = (c for c in contributors if not c.get("is_core", False))
|
||||||
other_contributors = sorted(other_contributors, key=lambda c: c["name"].lower())
|
other_contributors = sorted(other_contributors, key=lambda c: c["name"].lower())
|
||||||
content = template.render(
|
content = template.render(core_contributors=core_contributors, other_contributors=other_contributors)
|
||||||
core_contributors=core_contributors, other_contributors=other_contributors
|
|
||||||
)
|
|
||||||
|
|
||||||
file_path = ROOT / "CONTRIBUTORS.md"
|
file_path = ROOT / "CONTRIBUTORS.md"
|
||||||
file_path.write_text(content)
|
file_path.write_text(content)
|
||||||
|
@ -106,7 +98,5 @@ def write_md_file(contributors):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if GITHUB_REPO is None:
|
if GITHUB_REPO is None:
|
||||||
raise RuntimeError(
|
raise RuntimeError("No github repo, please set the environment variable GITHUB_REPOSITORY")
|
||||||
"No github repo, please set the environment variable GITHUB_REPOSITORY"
|
|
||||||
)
|
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
[flake8]
|
|
||||||
exclude = docs
|
|
||||||
max-line-length = 88
|
|
||||||
|
|
||||||
[isort]
|
|
||||||
profile = black
|
|
||||||
known_first_party = tests,scripts,hooks
|
|
11
setup.py
11
setup.py
|
@ -5,7 +5,7 @@ except ImportError:
|
||||||
from distutils.core import setup
|
from distutils.core import setup
|
||||||
|
|
||||||
# We use calendar versioning
|
# We use calendar versioning
|
||||||
version = "2023.01.10"
|
version = "2023.07.04"
|
||||||
|
|
||||||
with open("README.rst") as readme_file:
|
with open("README.rst") as readme_file:
|
||||||
long_description = readme_file.read()
|
long_description = readme_file.read()
|
||||||
|
@ -13,10 +13,7 @@ with open("README.rst") as readme_file:
|
||||||
setup(
|
setup(
|
||||||
name="cookiecutter-django",
|
name="cookiecutter-django",
|
||||||
version=version,
|
version=version,
|
||||||
description=(
|
description=("A Cookiecutter template for creating production-ready " "Django projects quickly."),
|
||||||
"A Cookiecutter template for creating production-ready "
|
|
||||||
"Django projects quickly."
|
|
||||||
),
|
|
||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
author="Daniel Roy Greenfeld",
|
author="Daniel Roy Greenfeld",
|
||||||
author_email="pydanny@gmail.com",
|
author_email="pydanny@gmail.com",
|
||||||
|
@ -27,13 +24,13 @@ setup(
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Development Status :: 4 - Beta",
|
"Development Status :: 4 - Beta",
|
||||||
"Environment :: Console",
|
"Environment :: Console",
|
||||||
"Framework :: Django :: 4.0",
|
"Framework :: Django :: 4.2",
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"Natural Language :: English",
|
"Natural Language :: English",
|
||||||
"License :: OSI Approved :: BSD License",
|
"License :: OSI Approved :: BSD License",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.11",
|
||||||
"Programming Language :: Python :: Implementation :: CPython",
|
"Programming Language :: Python :: Implementation :: CPython",
|
||||||
"Topic :: Software Development",
|
"Topic :: Software Development",
|
||||||
],
|
],
|
||||||
|
|
|
@ -20,25 +20,17 @@ sudo utility/install_os_dependencies.sh install
|
||||||
# Install Python deps
|
# Install Python deps
|
||||||
pip install -r requirements/local.txt
|
pip install -r requirements/local.txt
|
||||||
|
|
||||||
# Lint by running pre-commit on all files
|
|
||||||
# Needs a git repo to find the project root
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
pre-commit run --show-diff-on-failure -a
|
|
||||||
|
|
||||||
# run the project's tests
|
# run the project's tests
|
||||||
pytest
|
pytest
|
||||||
|
|
||||||
# Make sure the check doesn't raise any warnings
|
# Make sure the check doesn't raise any warnings
|
||||||
python manage.py check --fail-level WARNING
|
python manage.py check --fail-level WARNING
|
||||||
|
|
||||||
|
# Run npm build script if package.json is present
|
||||||
if [ -f "package.json" ]
|
if [ -f "package.json" ]
|
||||||
then
|
then
|
||||||
npm install
|
npm install
|
||||||
if [ -f "gulpfile.js" ]
|
|
||||||
then
|
|
||||||
npm run build
|
npm run build
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Generate the HTML for the documentation
|
# Generate the HTML for the documentation
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import glob
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
@ -20,6 +21,12 @@ if sys.platform.startswith("win"):
|
||||||
elif sys.platform.startswith("darwin") and os.getenv("CI"):
|
elif sys.platform.startswith("darwin") and os.getenv("CI"):
|
||||||
pytest.skip("skipping slow macOS tests on CI", allow_module_level=True)
|
pytest.skip("skipping slow macOS tests on CI", allow_module_level=True)
|
||||||
|
|
||||||
|
# Run auto-fixable styles checks - skipped on CI by default. These can be fixed
|
||||||
|
# automatically by running pre-commit after generation however they are tedious
|
||||||
|
# to fix in the template, so we don't insist too much in fixing them.
|
||||||
|
AUTOFIXABLE_STYLES = os.getenv("AUTOFIXABLE_STYLES") == "1"
|
||||||
|
auto_fixable = pytest.mark.skipif(not AUTOFIXABLE_STYLES, reason="auto-fixable")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def context():
|
def context():
|
||||||
|
@ -36,6 +43,8 @@ def context():
|
||||||
|
|
||||||
|
|
||||||
SUPPORTED_COMBINATIONS = [
|
SUPPORTED_COMBINATIONS = [
|
||||||
|
{"username_type": "username"},
|
||||||
|
{"username_type": "email"},
|
||||||
{"open_source_license": "MIT"},
|
{"open_source_license": "MIT"},
|
||||||
{"open_source_license": "BSD"},
|
{"open_source_license": "BSD"},
|
||||||
{"open_source_license": "GPLv3"},
|
{"open_source_license": "GPLv3"},
|
||||||
|
@ -43,10 +52,12 @@ SUPPORTED_COMBINATIONS = [
|
||||||
{"open_source_license": "Not open source"},
|
{"open_source_license": "Not open source"},
|
||||||
{"windows": "y"},
|
{"windows": "y"},
|
||||||
{"windows": "n"},
|
{"windows": "n"},
|
||||||
{"use_pycharm": "y"},
|
{"editor": "None"},
|
||||||
{"use_pycharm": "n"},
|
{"editor": "PyCharm"},
|
||||||
|
{"editor": "VS Code"},
|
||||||
{"use_docker": "y"},
|
{"use_docker": "y"},
|
||||||
{"use_docker": "n"},
|
{"use_docker": "n"},
|
||||||
|
{"postgresql_version": "15"},
|
||||||
{"postgresql_version": "14"},
|
{"postgresql_version": "14"},
|
||||||
{"postgresql_version": "13"},
|
{"postgresql_version": "13"},
|
||||||
{"postgresql_version": "12"},
|
{"postgresql_version": "12"},
|
||||||
|
@ -101,6 +112,7 @@ SUPPORTED_COMBINATIONS = [
|
||||||
{"frontend_pipeline": "None"},
|
{"frontend_pipeline": "None"},
|
||||||
{"frontend_pipeline": "Django Compressor"},
|
{"frontend_pipeline": "Django Compressor"},
|
||||||
{"frontend_pipeline": "Gulp"},
|
{"frontend_pipeline": "Gulp"},
|
||||||
|
{"frontend_pipeline": "Webpack"},
|
||||||
{"use_celery": "y"},
|
{"use_celery": "y"},
|
||||||
{"use_celery": "n"},
|
{"use_celery": "n"},
|
||||||
{"use_mailhog": "y"},
|
{"use_mailhog": "y"},
|
||||||
|
@ -134,13 +146,9 @@ def _fixture_id(ctx):
|
||||||
return "-".join(f"{key}:{value}" for key, value in ctx.items())
|
return "-".join(f"{key}:{value}" for key, value in ctx.items())
|
||||||
|
|
||||||
|
|
||||||
def build_files_list(root_dir):
|
def build_files_list(base_dir):
|
||||||
"""Build a list containing absolute paths to the generated files."""
|
"""Build a list containing absolute paths to the generated files."""
|
||||||
return [
|
return [os.path.join(dirpath, file_path) for dirpath, subdirs, files in os.walk(base_dir) for file_path in files]
|
||||||
os.path.join(dirpath, file_path)
|
|
||||||
for dirpath, subdirs, files in os.walk(root_dir)
|
|
||||||
for file_path in files
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def check_paths(paths):
|
def check_paths(paths):
|
||||||
|
@ -181,9 +189,10 @@ def test_flake8_passes(cookies, context_override):
|
||||||
pytest.fail(e.stdout.decode())
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
|
@auto_fixable
|
||||||
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
def test_black_passes(cookies, context_override):
|
def test_black_passes(cookies, context_override):
|
||||||
"""Generated project should pass black."""
|
"""Check whether generated project passes black style."""
|
||||||
result = cookies.bake(extra_context=context_override)
|
result = cookies.bake(extra_context=context_override)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -199,6 +208,65 @@ def test_black_passes(cookies, context_override):
|
||||||
pytest.fail(e.stdout.decode())
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
|
@auto_fixable
|
||||||
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
|
def test_isort_passes(cookies, context_override):
|
||||||
|
"""Check whether generated project passes isort style."""
|
||||||
|
result = cookies.bake(extra_context=context_override)
|
||||||
|
|
||||||
|
try:
|
||||||
|
sh.isort(_cwd=str(result.project_path))
|
||||||
|
except sh.ErrorReturnCode as e:
|
||||||
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
|
@auto_fixable
|
||||||
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
|
def test_django_upgrade_passes(cookies, context_override):
|
||||||
|
"""Check whether generated project passes django-upgrade."""
|
||||||
|
result = cookies.bake(extra_context=context_override)
|
||||||
|
|
||||||
|
python_files = [
|
||||||
|
file_path.removeprefix(f"{result.project_path}/")
|
||||||
|
for file_path in glob.glob(str(result.project_path / "**" / "*.py"), recursive=True)
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
sh.django_upgrade(
|
||||||
|
"--target-version",
|
||||||
|
"4.2",
|
||||||
|
*python_files,
|
||||||
|
_cwd=str(result.project_path),
|
||||||
|
)
|
||||||
|
except sh.ErrorReturnCode as e:
|
||||||
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
|
def test_djlint_lint_passes(cookies, context_override):
|
||||||
|
"""Check whether generated project passes djLint --lint."""
|
||||||
|
result = cookies.bake(extra_context=context_override)
|
||||||
|
|
||||||
|
autofixable_rules = "H014,T001"
|
||||||
|
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687
|
||||||
|
ignored_rules = "H006,H030,H031,T002"
|
||||||
|
try:
|
||||||
|
sh.djlint("--lint", "--ignore", f"{autofixable_rules},{ignored_rules}", ".", _cwd=str(result.project_path))
|
||||||
|
except sh.ErrorReturnCode as e:
|
||||||
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
|
@auto_fixable
|
||||||
|
@pytest.mark.parametrize("context_override", SUPPORTED_COMBINATIONS, ids=_fixture_id)
|
||||||
|
def test_djlint_check_passes(cookies, context_override):
|
||||||
|
"""Check whether generated project passes djLint --check."""
|
||||||
|
result = cookies.bake(extra_context=context_override)
|
||||||
|
|
||||||
|
try:
|
||||||
|
sh.djlint("--check", ".", _cwd=str(result.project_path))
|
||||||
|
except sh.ErrorReturnCode as e:
|
||||||
|
pytest.fail(e.stdout.decode())
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
["use_docker", "expected_test_script"],
|
["use_docker", "expected_test_script"],
|
||||||
[
|
[
|
||||||
|
@ -231,9 +299,7 @@ def test_travis_invokes_pytest(cookies, context, use_docker, expected_test_scrip
|
||||||
("y", "docker-compose -f local.yml run django pytest"),
|
("y", "docker-compose -f local.yml run django pytest"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_gitlab_invokes_flake8_and_pytest(
|
def test_gitlab_invokes_precommit_and_pytest(cookies, context, use_docker, expected_test_script):
|
||||||
cookies, context, use_docker, expected_test_script
|
|
||||||
):
|
|
||||||
context.update({"ci_tool": "Gitlab", "use_docker": use_docker})
|
context.update({"ci_tool": "Gitlab", "use_docker": use_docker})
|
||||||
result = cookies.bake(extra_context=context)
|
result = cookies.bake(extra_context=context)
|
||||||
|
|
||||||
|
@ -245,7 +311,9 @@ def test_gitlab_invokes_flake8_and_pytest(
|
||||||
with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml:
|
with open(f"{result.project_path}/.gitlab-ci.yml") as gitlab_yml:
|
||||||
try:
|
try:
|
||||||
gitlab_config = yaml.safe_load(gitlab_yml)
|
gitlab_config = yaml.safe_load(gitlab_yml)
|
||||||
assert gitlab_config["flake8"]["script"] == ["flake8"]
|
assert gitlab_config["precommit"]["script"] == [
|
||||||
|
"pre-commit run --show-diff-on-failure --color=always --all-files"
|
||||||
|
]
|
||||||
assert gitlab_config["pytest"]["script"] == [expected_test_script]
|
assert gitlab_config["pytest"]["script"] == [expected_test_script]
|
||||||
except yaml.YAMLError as e:
|
except yaml.YAMLError as e:
|
||||||
pytest.fail(e)
|
pytest.fail(e)
|
||||||
|
@ -258,9 +326,7 @@ def test_gitlab_invokes_flake8_and_pytest(
|
||||||
("y", "docker-compose -f local.yml run django pytest"),
|
("y", "docker-compose -f local.yml run django pytest"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_github_invokes_linter_and_pytest(
|
def test_github_invokes_linter_and_pytest(cookies, context, use_docker, expected_test_script):
|
||||||
cookies, context, use_docker, expected_test_script
|
|
||||||
):
|
|
||||||
context.update({"ci_tool": "Github", "use_docker": use_docker})
|
context.update({"ci_tool": "Github", "use_docker": use_docker})
|
||||||
result = cookies.bake(extra_context=context)
|
result = cookies.bake(extra_context=context)
|
||||||
|
|
||||||
|
@ -309,17 +375,37 @@ def test_error_if_incompatible(cookies, context, invalid_context):
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
["use_pycharm", "pycharm_docs_exist"],
|
["editor", "pycharm_docs_exist"],
|
||||||
[
|
[
|
||||||
("n", False),
|
("None", False),
|
||||||
("y", True),
|
("PyCharm", True),
|
||||||
|
("VS Code", False),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def test_pycharm_docs_removed(cookies, context, use_pycharm, pycharm_docs_exist):
|
def test_pycharm_docs_removed(cookies, context, editor, pycharm_docs_exist):
|
||||||
"""."""
|
context.update({"editor": editor})
|
||||||
context.update({"use_pycharm": use_pycharm})
|
|
||||||
result = cookies.bake(extra_context=context)
|
result = cookies.bake(extra_context=context)
|
||||||
|
|
||||||
with open(f"{result.project_path}/docs/index.rst") as f:
|
with open(f"{result.project_path}/docs/index.rst") as f:
|
||||||
has_pycharm_docs = "pycharm/configuration" in f.read()
|
has_pycharm_docs = "pycharm/configuration" in f.read()
|
||||||
assert has_pycharm_docs is pycharm_docs_exist
|
assert has_pycharm_docs is pycharm_docs_exist
|
||||||
|
|
||||||
|
|
||||||
|
def test_trim_domain_email(cookies, context):
|
||||||
|
"""Check that leading and trailing spaces are trimmed in domain and email."""
|
||||||
|
context.update(
|
||||||
|
{
|
||||||
|
"use_docker": "y",
|
||||||
|
"domain_name": " example.com ",
|
||||||
|
"email": " me@example.com ",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
result = cookies.bake(extra_context=context)
|
||||||
|
|
||||||
|
assert result.exit_code == 0
|
||||||
|
|
||||||
|
prod_django_env = result.project_path / ".envs" / ".production" / ".django"
|
||||||
|
assert "DJANGO_ALLOWED_HOSTS=.example.com" in prod_django_env.read_text()
|
||||||
|
|
||||||
|
base_settings = result.project_path / "config" / "settings" / "base.py"
|
||||||
|
assert '"me@example.com"' in base_settings.read_text()
|
||||||
|
|
|
@ -14,13 +14,6 @@ cd .cache/docker
|
||||||
cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@"
|
cookiecutter ../../ --no-input --overwrite-if-exists use_docker=y "$@"
|
||||||
cd my_awesome_project
|
cd my_awesome_project
|
||||||
|
|
||||||
# Lint by running pre-commit on all files
|
|
||||||
# Needs a git repo to find the project root
|
|
||||||
# We don't have git inside Docker, so run it outside
|
|
||||||
git init
|
|
||||||
git add .
|
|
||||||
pre-commit run --show-diff-on-failure -a
|
|
||||||
|
|
||||||
# make sure all images build
|
# make sure all images build
|
||||||
docker-compose -f local.yml build
|
docker-compose -f local.yml build
|
||||||
|
|
||||||
|
@ -41,3 +34,9 @@ docker-compose -f local.yml run django python manage.py check --fail-level WARNI
|
||||||
|
|
||||||
# Generate the HTML for the documentation
|
# Generate the HTML for the documentation
|
||||||
docker-compose -f local.yml run docs make html
|
docker-compose -f local.yml run docs make html
|
||||||
|
|
||||||
|
# Run npm build script if package.json is present
|
||||||
|
if [ -f "package.json" ]
|
||||||
|
then
|
||||||
|
docker-compose -f local.yml run node npm run build
|
||||||
|
fi
|
||||||
|
|
|
@ -22,7 +22,5 @@ def test_append_to_gitignore_file(working_directory):
|
||||||
gitignore_file.write_text("node_modules/\n")
|
gitignore_file.write_text("node_modules/\n")
|
||||||
append_to_gitignore_file(".envs/*")
|
append_to_gitignore_file(".envs/*")
|
||||||
linesep = os.linesep.encode()
|
linesep = os.linesep.encode()
|
||||||
assert (
|
assert gitignore_file.read_bytes() == b"node_modules/" + linesep + b".envs/*" + linesep
|
||||||
gitignore_file.read_bytes() == b"node_modules/" + linesep + b".envs/*" + linesep
|
|
||||||
)
|
|
||||||
assert gitignore_file.read_text() == "node_modules/\n.envs/*\n"
|
assert gitignore_file.read_text() == "node_modules/\n.envs/*\n"
|
||||||
|
|
5
tox.ini
5
tox.ini
|
@ -1,10 +1,11 @@
|
||||||
[tox]
|
[tox]
|
||||||
skipsdist = true
|
skipsdist = true
|
||||||
envlist = py310,black-template
|
envlist = py311,black-template
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps = -rrequirements.txt
|
deps = -rrequirements.txt
|
||||||
commands = pytest {posargs:./tests}
|
passenv = AUTOFIXABLE_STYLES
|
||||||
|
commands = pytest -n auto {posargs:./tests}
|
||||||
|
|
||||||
[testenv:black-template]
|
[testenv:black-template]
|
||||||
deps = black
|
deps = black
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
#
|
||||||
|
# .bashrc.override.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
# persistent bash history
|
||||||
|
HISTFILE=~/.bash_history
|
||||||
|
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
|
||||||
|
|
||||||
|
# set some django env vars
|
||||||
|
source /entrypoint
|
||||||
|
|
||||||
|
# restore default shell options
|
||||||
|
set +o errexit
|
||||||
|
set +o pipefail
|
||||||
|
set +o nounset
|
||||||
|
|
||||||
|
# start ssh-agent
|
||||||
|
# https://code.visualstudio.com/docs/remote/troubleshooting
|
||||||
|
eval "$(ssh-agent -s)"
|
|
@ -0,0 +1,87 @@
|
||||||
|
// For format details, see https://containers.dev/implementors/json_reference/
|
||||||
|
{
|
||||||
|
"name": "{{cookiecutter.project_slug}}_dev",
|
||||||
|
"dockerComposeFile": [
|
||||||
|
"../local.yml"
|
||||||
|
],
|
||||||
|
"init": true,
|
||||||
|
"mounts": [
|
||||||
|
{
|
||||||
|
"source": "./.devcontainer/bash_history",
|
||||||
|
"target": "/home/dev-user/.bash_history",
|
||||||
|
"type": "bind"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "~/.ssh",
|
||||||
|
"target": "/tmp",
|
||||||
|
"type": "bind"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "~/.ssh",
|
||||||
|
"target": "/home/dev-user/.ssh",
|
||||||
|
"type": "bind"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
// 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,
|
||||||
|
"service": "django",
|
||||||
|
// "remoteEnv": {"PATH": "/home/dev-user/.local/bin:${containerEnv:PATH}"},
|
||||||
|
"remoteUser": "dev-user",
|
||||||
|
"workspaceFolder": "/app",
|
||||||
|
// Set *default* container specific settings.json values on container create.
|
||||||
|
"customizations": {
|
||||||
|
{%- if cookiecutter.editor == "VS Code" %}
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"[python]": {
|
||||||
|
"analysis.autoImportCompletions": true,
|
||||||
|
"analysis.typeCheckingMode": "basic",
|
||||||
|
"defaultInterpreterPath": "/usr/local/bin/python",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports": true
|
||||||
|
},
|
||||||
|
// Uncomment when fixed
|
||||||
|
// https://github.com/microsoft/vscode-remote-release/issues/8474
|
||||||
|
// "editor.defaultFormatter": "ms-python.black-formatter",
|
||||||
|
"formatting.blackPath": "/usr/local/bin/black",
|
||||||
|
"formatting.provider": "black",
|
||||||
|
"languageServer": "Pylance",
|
||||||
|
// "linting.banditPath": "/usr/local/py-utils/bin/bandit",
|
||||||
|
"linting.enabled": true,
|
||||||
|
"linting.flake8Enabled": true,
|
||||||
|
"linting.flake8Path": "/usr/local/bin/flake8",
|
||||||
|
"linting.mypyEnabled": true,
|
||||||
|
"linting.mypyPath": "/usr/local/bin/mypy",
|
||||||
|
"linting.pycodestylePath": "/usr/local/bin/pycodestyle",
|
||||||
|
// "linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
|
||||||
|
"linting.pylintEnabled": true,
|
||||||
|
"linting.pylintPath": "/usr/local/bin/pylint"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// https://code.visualstudio.com/docs/remote/devcontainerjson-reference#_vs-code-specific-properties
|
||||||
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
|
"extensions": [
|
||||||
|
"davidanson.vscode-markdownlint",
|
||||||
|
"mrmlnc.vscode-duplicate",
|
||||||
|
"visualstudioexptteam.vscodeintellicode",
|
||||||
|
"visualstudioexptteam.intellicode-api-usage-examples",
|
||||||
|
// python
|
||||||
|
"ms-python.python",
|
||||||
|
"ms-python.vscode-pylance",
|
||||||
|
"ms-python.isort",
|
||||||
|
"ms-python.black-formatter",
|
||||||
|
// django
|
||||||
|
"batisteo.vscode-django"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
{%- endif %}
|
||||||
|
},
|
||||||
|
// Uncomment the next line if you want start specific services in your Docker Compose config.
|
||||||
|
// "runServices": [],
|
||||||
|
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
|
||||||
|
// "shutdownAction": "none",
|
||||||
|
// Uncomment the next line to run commands after the container is created.
|
||||||
|
"postCreateCommand": "cat .devcontainer/bashrc.override.sh >> ~/.bashrc"
|
||||||
|
}
|
|
@ -22,6 +22,6 @@ trim_trailing_whitespace = false
|
||||||
[Makefile]
|
[Makefile]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
|
|
||||||
[nginx.conf]
|
[default.conf]
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
106
{{cookiecutter.project_slug}}/.github/dependabot.yml
vendored
106
{{cookiecutter.project_slug}}/.github/dependabot.yml
vendored
|
@ -4,11 +4,11 @@
|
||||||
version: 2
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
# Update GitHub actions in workflows
|
# Update GitHub actions in workflows
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: 'github-actions'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
|
|
||||||
|
@ -16,80 +16,92 @@ updates:
|
||||||
# We need to specify each Dockerfile in a separate entry because Dependabot doesn't
|
# We need to specify each Dockerfile in a separate entry because Dependabot doesn't
|
||||||
# support wildcards or recursively checking subdirectories. Check this issue for updates:
|
# support wildcards or recursively checking subdirectories. Check this issue for updates:
|
||||||
# https://github.com/dependabot/dependabot-core/issues/2178
|
# https://github.com/dependabot/dependabot-core/issues/2178
|
||||||
- package-ecosystem: "docker"
|
- package-ecosystem: 'docker'
|
||||||
# Look for a `Dockerfile` in the `compose/local/django` directory
|
# Look for a `Dockerfile` in the `compose/local/django` directory
|
||||||
directory: "compose/local/django/"
|
directory: 'compose/local/django/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
# Ignore minor version updates (3.10 -> 3.11) but update patch versions
|
||||||
|
ignore:
|
||||||
|
- dependency-name: '*'
|
||||||
|
update-types:
|
||||||
|
- 'version-update:semver-major'
|
||||||
|
- 'version-update:semver-minor'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/local/docs` directory
|
# Look for a `Dockerfile` in the `compose/local/docs` directory
|
||||||
directory: "compose/local/docs/"
|
directory: 'compose/local/docs/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
# Ignore minor version updates (3.10 -> 3.11) but update patch versions
|
||||||
|
ignore:
|
||||||
|
- dependency-name: '*'
|
||||||
|
update-types:
|
||||||
|
- 'version-update:semver-major'
|
||||||
|
- 'version-update:semver-minor'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/local/node` directory
|
# Look for a `Dockerfile` in the `compose/local/node` directory
|
||||||
directory: "compose/local/node/"
|
directory: 'compose/local/node/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/production/aws` directory
|
# Look for a `Dockerfile` in the `compose/production/aws` directory
|
||||||
directory: "compose/production/aws/"
|
directory: 'compose/production/aws/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/production/django` directory
|
# Look for a `Dockerfile` in the `compose/production/django` directory
|
||||||
directory: "compose/production/django/"
|
directory: 'compose/production/django/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
# Ignore minor version updates (3.10 -> 3.11) but update patch versions
|
||||||
|
ignore:
|
||||||
|
- dependency-name: '*'
|
||||||
|
update-types:
|
||||||
|
- 'version-update:semver-major'
|
||||||
|
- 'version-update:semver-minor'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/production/postgres` directory
|
# Look for a `Dockerfile` in the `compose/production/postgres` directory
|
||||||
directory: "compose/production/postgres/"
|
directory: 'compose/production/postgres/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
# Enable version updates for Docker
|
- package-ecosystem: 'docker'
|
||||||
- package-ecosystem: "docker"
|
|
||||||
# Look for a `Dockerfile` in the `compose/production/traefik` directory
|
# Look for a `Dockerfile` in the `compose/production/traefik` directory
|
||||||
directory: "compose/production/traefik/"
|
directory: 'compose/production/traefik/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# Enable version updates for Python/Pip - Production
|
# Enable version updates for Python/Pip - Production
|
||||||
- package-ecosystem: "pip"
|
- package-ecosystem: 'pip'
|
||||||
# Look for a `requirements.txt` in the `root` directory
|
# Look for a `requirements.txt` in the `root` directory
|
||||||
# also 'setup.cfg', 'runtime.txt' and 'requirements/*.txt'
|
# also 'setup.cfg', 'runtime.txt' and 'requirements/*.txt'
|
||||||
directory: "/"
|
directory: '/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
||||||
|
|
||||||
# Enable version updates for javascript/npm
|
# Enable version updates for javascript/npm
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: 'npm'
|
||||||
# Look for a `packages.json' in the `root` directory
|
# Look for a `packages.json` in the `root` directory
|
||||||
directory: "/"
|
directory: '/'
|
||||||
# Check for updates to GitHub Actions every weekday
|
# Every weekday
|
||||||
schedule:
|
schedule:
|
||||||
interval: "daily"
|
interval: 'daily'
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -7,12 +7,12 @@ env:
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ "master", "main" ]
|
branches: ['master', 'main']
|
||||||
paths-ignore: [ "docs/**" ]
|
paths-ignore: ['docs/**']
|
||||||
|
|
||||||
push:
|
push:
|
||||||
branches: [ "master", "main" ]
|
branches: ['master', 'main']
|
||||||
paths-ignore: [ "docs/**" ]
|
paths-ignore: ['docs/**']
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: {% raw %}${{ github.head_ref || github.run_id }}{% endraw %}
|
group: {% raw %}${{ github.head_ref || github.run_id }}{% endraw %}
|
||||||
|
@ -22,21 +22,19 @@ jobs:
|
||||||
linter:
|
linter:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout Code Repository
|
- name: Checkout Code Repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v3
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: '3.11'
|
||||||
cache: pip
|
|
||||||
cache-dependency-path: |
|
|
||||||
requirements/base.txt
|
|
||||||
requirements/local.txt
|
|
||||||
|
|
||||||
|
{%- if cookiecutter.open_source_license != 'Not open source' %}
|
||||||
|
# Consider using pre-commit.ci for open source project
|
||||||
|
{%- endif %}
|
||||||
- name: Run pre-commit
|
- name: Run pre-commit
|
||||||
uses: pre-commit/action@v2.0.3
|
uses: pre-commit/action@v3.0.0
|
||||||
|
|
||||||
# With no caching at all the entire ci process takes 4m 30s to complete!
|
# With no caching at all the entire ci process takes 4m 30s to complete!
|
||||||
pytest:
|
pytest:
|
||||||
|
@ -51,7 +49,7 @@ jobs:
|
||||||
- 6379:6379
|
- 6379:6379
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
postgres:
|
postgres:
|
||||||
image: postgres:12
|
image: postgres:{{ cookiecutter.postgresql_version }}
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
env:
|
env:
|
||||||
|
@ -59,14 +57,13 @@ jobs:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
CELERY_BROKER_URL: "redis://localhost:6379/0"
|
CELERY_BROKER_URL: 'redis://localhost:6379/0'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# postgres://user:password@host:port/database
|
# postgres://user:password@host:port/database
|
||||||
DATABASE_URL: "postgres://postgres:postgres@localhost:5432/postgres"
|
DATABASE_URL: 'postgres://postgres:postgres@localhost:5432/postgres'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Checkout Code Repository
|
- name: Checkout Code Repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
|
@ -85,9 +82,9 @@ jobs:
|
||||||
{%- else %}
|
{%- else %}
|
||||||
|
|
||||||
- name: Set up Python
|
- name: Set up Python
|
||||||
uses: actions/setup-python@v3
|
uses: actions/setup-python@v4
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: '3.11'
|
||||||
cache: pip
|
cache: pip
|
||||||
cache-dependency-path: |
|
cache-dependency-path: |
|
||||||
requirements/base.txt
|
requirements/base.txt
|
||||||
|
|
12
{{cookiecutter.project_slug}}/.gitignore
vendored
12
{{cookiecutter.project_slug}}/.gitignore
vendored
|
@ -161,11 +161,10 @@ typings/
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Local History for devcontainer
|
||||||
.history/
|
.devcontainer/bash_history
|
||||||
|
|
||||||
|
{% if cookiecutter.editor == 'PyCharm' -%}
|
||||||
{% if cookiecutter.use_pycharm == 'y' -%}
|
|
||||||
# Provided default Pycharm Run/Debug Configurations should be tracked by git
|
# Provided default Pycharm Run/Debug Configurations should be tracked by git
|
||||||
# In case of local modifications made by Pycharm, use update-index command
|
# In case of local modifications made by Pycharm, use update-index command
|
||||||
# for each changed file, like this:
|
# for each changed file, like this:
|
||||||
|
@ -346,4 +345,9 @@ project.css
|
||||||
project.min.css
|
project.min.css
|
||||||
vendors.js
|
vendors.js
|
||||||
*.min.js
|
*.min.js
|
||||||
|
*.min.js.map
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
{{ cookiecutter.project_slug }}/static/webpack_bundles/
|
||||||
|
webpack-stats.json
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -7,21 +7,26 @@ variables:
|
||||||
POSTGRES_PASSWORD: ''
|
POSTGRES_PASSWORD: ''
|
||||||
POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}'
|
POSTGRES_DB: 'test_{{ cookiecutter.project_slug }}'
|
||||||
POSTGRES_HOST_AUTH_METHOD: trust
|
POSTGRES_HOST_AUTH_METHOD: trust
|
||||||
{% if cookiecutter.use_celery == 'y' -%}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
CELERY_BROKER_URL: 'redis://redis:6379/0'
|
CELERY_BROKER_URL: 'redis://redis:6379/0'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
flake8:
|
precommit:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: python:3.10-alpine
|
image: python:3.11
|
||||||
|
variables:
|
||||||
|
PRE_COMMIT_HOME: ${CI_PROJECT_DIR}/.cache/pre-commit
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- ${PRE_COMMIT_HOME}
|
||||||
before_script:
|
before_script:
|
||||||
- pip install -q flake8
|
- pip install -q pre-commit
|
||||||
script:
|
script:
|
||||||
- flake8
|
- pre-commit run --show-diff-on-failure --color=always --all-files
|
||||||
|
|
||||||
pytest:
|
pytest:
|
||||||
stage: test
|
stage: test
|
||||||
{% if cookiecutter.use_docker == 'y' -%}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
image: docker/compose:1.29.2
|
image: docker/compose:1.29.2
|
||||||
tags:
|
tags:
|
||||||
- docker
|
- docker
|
||||||
|
@ -34,19 +39,16 @@ pytest:
|
||||||
- docker-compose -f local.yml up -d
|
- docker-compose -f local.yml up -d
|
||||||
script:
|
script:
|
||||||
- docker-compose -f local.yml run django pytest
|
- docker-compose -f local.yml run django pytest
|
||||||
{%- else -%}
|
{%- else %}
|
||||||
image: python:3.10
|
image: python:3.11
|
||||||
tags:
|
tags:
|
||||||
- python
|
- python
|
||||||
services:
|
services:
|
||||||
- postgres:{{ cookiecutter.postgresql_version }}
|
- postgres:{{ cookiecutter.postgresql_version }}
|
||||||
variables:
|
variables:
|
||||||
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
|
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- pip install -r requirements/local.txt
|
- pip install -r requirements/local.txt
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- pytest
|
- pytest
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<option value="celeryworker"/>
|
<option value="celeryworker"/>
|
||||||
<option value="celerybeat"/>
|
<option value="celerybeat"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
<option value="node"/>
|
<option value="node"/>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
</list>
|
</list>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
{% if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
<excludeFolder url="file://$MODULE_DIR$/node_modules" />
|
||||||
</content>
|
</content>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
exclude: "^docs/|/migrations/"
|
exclude: '^docs/|/migrations/'
|
||||||
default_stages: [commit]
|
default_stages: [commit]
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
|
@ -7,21 +7,44 @@ repos:
|
||||||
hooks:
|
hooks:
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
|
- id: check-json
|
||||||
|
- id: check-toml
|
||||||
|
- id: check-xml
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
- id: debug-statements
|
||||||
|
- id: check-builtin-literals
|
||||||
|
- 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
|
||||||
|
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'
|
||||||
|
hooks:
|
||||||
|
- id: django-upgrade
|
||||||
|
args: ['--target-version', '4.2']
|
||||||
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v3.3.1
|
rev: v3.7.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args: [--py310-plus]
|
args: [--py311-plus]
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 22.12.0
|
rev: 23.3.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.11.4
|
rev: 5.12.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
|
||||||
|
@ -29,8 +52,12 @@ repos:
|
||||||
rev: 6.0.0
|
rev: 6.0.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
args: ["--config=setup.cfg"]
|
|
||||||
additional_dependencies: [flake8-isort]
|
- repo: https://github.com/Riverside-Healthcare/djLint
|
||||||
|
rev: v1.31.1
|
||||||
|
hooks:
|
||||||
|
- id: djlint-reformat-django
|
||||||
|
- id: djlint-django
|
||||||
|
|
||||||
# sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date
|
# sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date
|
||||||
ci:
|
ci:
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
[MASTER]
|
|
||||||
load-plugins=pylint_django{% if cookiecutter.use_celery == "y" %}, pylint_celery{% endif %}
|
|
||||||
django-settings-module=config.settings.local
|
|
||||||
[FORMAT]
|
|
||||||
max-line-length=120
|
|
||||||
|
|
||||||
[MESSAGES CONTROL]
|
|
||||||
disable=missing-docstring,invalid-name
|
|
||||||
|
|
||||||
[DESIGN]
|
|
||||||
max-parents=13
|
|
||||||
|
|
||||||
[TYPECHECK]
|
|
||||||
generated-members=REQUEST,acl_users,aq_parent,"[a-zA-Z]+_set{1,2}",save,delete
|
|
|
@ -1,12 +1,20 @@
|
||||||
|
# Read the Docs configuration file
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
|
||||||
|
# Required
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
|
# Set the version of Python and other tools you might need
|
||||||
|
build:
|
||||||
|
os: ubuntu-22.04
|
||||||
|
tools:
|
||||||
|
python: '3.11'
|
||||||
|
|
||||||
|
# Build documentation in the docs/ directory with Sphinx
|
||||||
sphinx:
|
sphinx:
|
||||||
configuration: docs/conf.py
|
configuration: docs/conf.py
|
||||||
|
|
||||||
build:
|
# Python requirements required to build your docs
|
||||||
image: testing
|
|
||||||
|
|
||||||
python:
|
python:
|
||||||
version: 3.10
|
|
||||||
install:
|
install:
|
||||||
- requirements: requirements/local.txt
|
- requirements: requirements/local.txt
|
||||||
|
|
|
@ -2,7 +2,7 @@ dist: focal
|
||||||
|
|
||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "3.10"
|
- "3.11"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %}
|
- {% if cookiecutter.use_docker == 'y' %}docker{% else %}postgresql{% endif %}
|
||||||
|
@ -37,7 +37,7 @@ jobs:
|
||||||
- sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm
|
- sudo apt-get install -qq libsqlite3-dev libxml2 libxml2-dev libssl-dev libbz2-dev wget curl llvm
|
||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- "3.10"
|
- "3.11"
|
||||||
install:
|
install:
|
||||||
- pip install -r requirements/local.txt
|
- pip install -r requirements/local.txt
|
||||||
script:
|
script:
|
||||||
|
|
|
@ -56,12 +56,26 @@ This app comes with Celery.
|
||||||
|
|
||||||
To run a celery worker:
|
To run a celery worker:
|
||||||
|
|
||||||
``` bash
|
```bash
|
||||||
cd {{cookiecutter.project_slug}}
|
cd {{cookiecutter.project_slug}}
|
||||||
celery -A config.celery_app worker -l info
|
celery -A config.celery_app worker -l info
|
||||||
```
|
```
|
||||||
|
|
||||||
Please note: For Celery's import magic to work, it is important *where* the celery commands are run. If you are in the same folder with *manage.py*, you should be right.
|
Please note: For Celery's import magic to work, it is important _where_ the celery commands are run. If you are in the same folder with _manage.py_, you should be right.
|
||||||
|
|
||||||
|
To run [periodic tasks](https://docs.celeryq.dev/en/stable/userguide/periodic-tasks.html), you'll need to start the celery beat scheduler service. You can start it as a standalone process:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd {{cookiecutter.project_slug}}
|
||||||
|
celery -A config.celery_app beat
|
||||||
|
```
|
||||||
|
|
||||||
|
or you can embed the beat service inside a worker with the `-B` option (not recommended for production use):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd {{cookiecutter.project_slug}}
|
||||||
|
celery -A config.celery_app worker -B -l info
|
||||||
|
```
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.use_mailhog == "y" %}
|
{%- if cookiecutter.use_mailhog == "y" %}
|
||||||
|
@ -128,13 +142,14 @@ See detailed [cookiecutter-django Heroku documentation](http://cookiecutter-djan
|
||||||
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
|
See detailed [cookiecutter-django Docker documentation](http://cookiecutter-django.readthedocs.io/en/latest/deployment-with-docker.html).
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
|
|
||||||
### Custom Bootstrap Compilation
|
### Custom Bootstrap Compilation
|
||||||
|
|
||||||
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
|
The generated CSS is set up with automatic Bootstrap recompilation with variables of your choice.
|
||||||
Bootstrap v5 is installed using npm and customised by tweaking your variables in `static/sass/custom_bootstrap_vars`.
|
Bootstrap v5 is installed using npm and customised by tweaking your variables in `static/sass/custom_bootstrap_vars`.
|
||||||
|
|
||||||
You can find a list of available variables [in the bootstrap source](https://github.com/twbs/bootstrap/blob/main/scss/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/docs/5.1/customize/sass/).
|
You can find a list of available variables [in the bootstrap source](https://github.com/twbs/bootstrap/blob/v5.1.3/scss/_variables.scss), or get explanations on them in the [Bootstrap docs](https://getbootstrap.com/docs/5.1/customize/sass/).
|
||||||
|
|
||||||
Bootstrap's javascript as well as its dependencies is concatenated into a single file: `static/js/vendors.js`.
|
Bootstrap's javascript as well as its dependencies are concatenated into a single file: `static/js/vendors.js`.
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
{%- if cookiecutter.frontend_pipeline == "Django Compressor" %}
|
||||||
|
|
||||||
compress_enabled() {
|
compress_enabled() {
|
||||||
python << END
|
python << END
|
||||||
|
@ -19,4 +20,7 @@ if compress_enabled
|
||||||
then
|
then
|
||||||
python manage.py compress
|
python manage.py compress
|
||||||
fi
|
fi
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
python manage.py collectstatic --noinput
|
python manage.py collectstatic --noinput
|
||||||
|
python manage.py compilemessages -i site-packages
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
ARG PYTHON_VERSION=3.10-slim-bullseye
|
# define an alias for the specific python version used in this file.
|
||||||
|
FROM python:3.11.4-slim-bullseye as python
|
||||||
# define an alias for the specfic python version used in this file.
|
|
||||||
FROM python:${PYTHON_VERSION} as python
|
|
||||||
|
|
||||||
# Python build stage
|
# Python build stage
|
||||||
FROM python as python-build-stage
|
FROM python as python-build-stage
|
||||||
|
@ -35,6 +33,18 @@ ENV BUILD_ENV ${BUILD_ENVIRONMENT}
|
||||||
|
|
||||||
WORKDIR ${APP_HOME}
|
WORKDIR ${APP_HOME}
|
||||||
|
|
||||||
|
{% if cookiecutter.use_docker == "y" %}
|
||||||
|
# devcontainer dependencies and utils
|
||||||
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
|
sudo git bash-completion nano ssh
|
||||||
|
|
||||||
|
# Create devcontainer user and add it to sudoers
|
||||||
|
RUN groupadd --gid 1000 dev-user \
|
||||||
|
&& useradd --uid 1000 --gid dev-user --shell /bin/bash --create-home dev-user \
|
||||||
|
&& echo dev-user ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/dev-user \
|
||||||
|
&& chmod 0440 /etc/sudoers.d/dev-user
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Install required system dependencies
|
# Install required system dependencies
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
# psycopg2 dependencies
|
# psycopg2 dependencies
|
||||||
|
|
|
@ -5,4 +5,4 @@ set -o nounset
|
||||||
|
|
||||||
|
|
||||||
rm -f './celerybeat.pid'
|
rm -f './celerybeat.pid'
|
||||||
exec watchfiles celery.__main__.main --args '-A config.celery_app beat -l INFO'
|
exec watchfiles --filter python celery.__main__.main --args '-A config.celery_app beat -l INFO'
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
set -o errexit
|
set -o errexit
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
exec watchfiles celery.__main__.main \
|
exec watchfiles --filter python celery.__main__.main \
|
||||||
--args \
|
--args \
|
||||||
"-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\""
|
"-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\""
|
||||||
|
|
|
@ -4,4 +4,4 @@ set -o errexit
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
|
|
||||||
exec watchfiles celery.__main__.main --args '-A config.celery_app worker -l INFO'
|
exec watchfiles --filter python celery.__main__.main --args '-A config.celery_app worker -l INFO'
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
ARG PYTHON_VERSION=3.10-slim-bullseye
|
# define an alias for the specific python version used in this file.
|
||||||
|
FROM python:3.11.4-slim-bullseye as python
|
||||||
# define an alias for the specfic python version used in this file.
|
|
||||||
FROM python:${PYTHON_VERSION} as python
|
|
||||||
|
|
||||||
|
|
||||||
# Python build stage
|
# Python build stage
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM node:16-bullseye-slim
|
FROM node:18-bullseye-slim
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM garland/aws-cli-docker:1.15.47
|
FROM garland/aws-cli-docker:1.16.140
|
||||||
|
|
||||||
COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance
|
COPY ./compose/production/aws/maintenance /usr/local/bin/maintenance
|
||||||
COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced
|
COPY ./compose/production/postgres/maintenance/_sourced /usr/local/bin/maintenance/_sourced
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
ARG PYTHON_VERSION=3.10-slim-bullseye
|
{% if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] -%}
|
||||||
|
FROM node:18-bullseye-slim as client-builder
|
||||||
{% if cookiecutter.frontend_pipeline == 'Gulp' -%}
|
|
||||||
FROM node:16-bullseye-slim as client-builder
|
|
||||||
|
|
||||||
ARG APP_HOME=/app
|
ARG APP_HOME=/app
|
||||||
WORKDIR ${APP_HOME}
|
WORKDIR ${APP_HOME}
|
||||||
|
@ -9,12 +7,25 @@ WORKDIR ${APP_HOME}
|
||||||
COPY ./package.json ${APP_HOME}
|
COPY ./package.json ${APP_HOME}
|
||||||
RUN npm install && npm cache clean --force
|
RUN npm install && npm cache clean --force
|
||||||
COPY . ${APP_HOME}
|
COPY . ${APP_HOME}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' and cookiecutter.use_whitenoise == 'n' %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
|
ARG DJANGO_AWS_STORAGE_BUCKET_NAME
|
||||||
|
ENV DJANGO_AWS_STORAGE_BUCKET_NAME=${DJANGO_AWS_STORAGE_BUCKET_NAME}
|
||||||
|
ARG DJANGO_AWS_S3_CUSTOM_DOMAIN
|
||||||
|
ENV DJANGO_AWS_S3_CUSTOM_DOMAIN=${DJANGO_AWS_S3_CUSTOM_DOMAIN}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'GCP' %}
|
||||||
|
ARG DJANGO_GCP_STORAGE_BUCKET_NAME
|
||||||
|
ENV DJANGO_GCP_STORAGE_BUCKET_NAME=${DJANGO_GCP_STORAGE_BUCKET_NAME}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'Azure' %}
|
||||||
|
ARG DJANGO_AZURE_ACCOUNT_NAME
|
||||||
|
ENV DJANGO_AZURE_ACCOUNT_NAME=${DJANGO_AZURE_ACCOUNT_NAME}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
# define an alias for the specific python version used in this file.
|
||||||
# define an alias for the specfic python version used in this file.
|
FROM python:3.11.4-slim-bullseye as python
|
||||||
FROM python:${PYTHON_VERSION} as python
|
|
||||||
|
|
||||||
# Python build stage
|
# Python build stage
|
||||||
FROM python as python-build-stage
|
FROM python as python-build-stage
|
||||||
|
@ -99,7 +110,7 @@ RUN chmod +x /start-flower
|
||||||
|
|
||||||
|
|
||||||
# copy application code to WORKDIR
|
# copy application code to WORKDIR
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME}
|
COPY --from=client-builder --chown=django:django ${APP_HOME} ${APP_HOME}
|
||||||
{% else %}
|
{% else %}
|
||||||
COPY --chown=django:django . ${APP_HOME}
|
COPY --chown=django:django . ${APP_HOME}
|
||||||
|
@ -110,4 +121,11 @@ RUN chown django:django ${APP_HOME}
|
||||||
|
|
||||||
USER django
|
USER django
|
||||||
|
|
||||||
|
RUN DATABASE_URL="" \
|
||||||
|
{%- if cookiecutter.use_celery == "y" %}
|
||||||
|
CELERY_BROKER_URL="" \
|
||||||
|
{%- endif %}
|
||||||
|
DJANGO_SETTINGS_MODULE="config.settings.test" \
|
||||||
|
python manage.py compilemessages
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint"]
|
ENTRYPOINT ["/entrypoint"]
|
||||||
|
|
|
@ -20,14 +20,14 @@ python << END
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import psycopg2
|
import psycopg
|
||||||
|
|
||||||
suggest_unrecoverable_after = 30
|
suggest_unrecoverable_after = 30
|
||||||
start = time.time()
|
start = time.time()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
psycopg2.connect(
|
psycopg.connect(
|
||||||
dbname="${POSTGRES_DB}",
|
dbname="${POSTGRES_DB}",
|
||||||
user="${POSTGRES_USER}",
|
user="${POSTGRES_USER}",
|
||||||
password="${POSTGRES_PASSWORD}",
|
password="${POSTGRES_PASSWORD}",
|
||||||
|
@ -35,7 +35,7 @@ while True:
|
||||||
port="${POSTGRES_PORT}",
|
port="${POSTGRES_PORT}",
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
except psycopg2.OperationalError as error:
|
except psycopg.OperationalError as error:
|
||||||
sys.stderr.write("Waiting for PostgreSQL to become available...\n")
|
sys.stderr.write("Waiting for PostgreSQL to become available...\n")
|
||||||
|
|
||||||
if time.time() - start > suggest_unrecoverable_after:
|
if time.time() - start > suggest_unrecoverable_after:
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
FROM nginx:1.17.8-alpine
|
||||||
|
COPY ./compose/production/nginx/default.conf /etc/nginx/conf.d/default.conf
|
|
@ -0,0 +1,7 @@
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
location /media/ {
|
||||||
|
alias /usr/share/nginx/media/;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
FROM traefik:v2.2.11
|
FROM traefik:2.10.3
|
||||||
RUN mkdir -p /etc/traefik/acme \
|
RUN mkdir -p /etc/traefik/acme \
|
||||||
&& touch /etc/traefik/acme/acme.json \
|
&& touch /etc/traefik/acme/acme.json \
|
||||||
&& chmod 600 /etc/traefik/acme/acme.json
|
&& chmod 600 /etc/traefik/acme/acme.json
|
||||||
|
|
|
@ -4,7 +4,7 @@ log:
|
||||||
entryPoints:
|
entryPoints:
|
||||||
web:
|
web:
|
||||||
# http
|
# http
|
||||||
address: ":80"
|
address: ':80'
|
||||||
http:
|
http:
|
||||||
# https://docs.traefik.io/routing/entrypoints/#entrypoint
|
# https://docs.traefik.io/routing/entrypoints/#entrypoint
|
||||||
redirections:
|
redirections:
|
||||||
|
@ -13,18 +13,18 @@ entryPoints:
|
||||||
|
|
||||||
web-secure:
|
web-secure:
|
||||||
# https
|
# https
|
||||||
address: ":443"
|
address: ':443'
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
flower:
|
flower:
|
||||||
address: ":5555"
|
address: ':5555'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
certificatesResolvers:
|
certificatesResolvers:
|
||||||
letsencrypt:
|
letsencrypt:
|
||||||
# https://docs.traefik.io/master/https/acme/#lets-encrypt
|
# https://docs.traefik.io/master/https/acme/#lets-encrypt
|
||||||
acme:
|
acme:
|
||||||
email: "{{ cookiecutter.email }}"
|
email: '{{ cookiecutter.email }}'
|
||||||
storage: /etc/traefik/acme/acme.json
|
storage: /etc/traefik/acme/acme.json
|
||||||
# https://docs.traefik.io/master/https/acme/#httpchallenge
|
# https://docs.traefik.io/master/https/acme/#httpchallenge
|
||||||
httpChallenge:
|
httpChallenge:
|
||||||
|
@ -34,9 +34,9 @@ http:
|
||||||
routers:
|
routers:
|
||||||
web-secure-router:
|
web-secure-router:
|
||||||
{%- if cookiecutter.domain_name.count('.') == 1 %}
|
{%- if cookiecutter.domain_name.count('.') == 1 %}
|
||||||
rule: "Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)"
|
rule: 'Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)'
|
||||||
{%- else %}
|
{%- else %}
|
||||||
rule: "Host(`{{ cookiecutter.domain_name }}`)"
|
rule: 'Host(`{{ cookiecutter.domain_name }}`)'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- web-secure
|
- web-secure
|
||||||
|
@ -49,7 +49,7 @@ http:
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
|
|
||||||
flower-secure-router:
|
flower-secure-router:
|
||||||
rule: "Host(`{{ cookiecutter.domain_name }}`)"
|
rule: 'Host(`{{ cookiecutter.domain_name }}`)'
|
||||||
entryPoints:
|
entryPoints:
|
||||||
- flower
|
- flower
|
||||||
service: flower
|
service: flower
|
||||||
|
@ -57,13 +57,29 @@ http:
|
||||||
# https://docs.traefik.io/master/routing/routers/#certresolver
|
# https://docs.traefik.io/master/routing/routers/#certresolver
|
||||||
certResolver: letsencrypt
|
certResolver: letsencrypt
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'None' %}
|
||||||
|
|
||||||
|
web-media-router:
|
||||||
|
{%- if cookiecutter.domain_name.count('.') == 1 %}
|
||||||
|
rule: '(Host(`{{ cookiecutter.domain_name }}`) || Host(`www.{{ cookiecutter.domain_name }}`)) && PathPrefix(`/media/`)'
|
||||||
|
{%- else %}
|
||||||
|
rule: 'Host(`{{ cookiecutter.domain_name }}`) && PathPrefix(`/media/`)'
|
||||||
|
{%- endif %}
|
||||||
|
entryPoints:
|
||||||
|
- web-secure
|
||||||
|
middlewares:
|
||||||
|
- csrf
|
||||||
|
service: django-media
|
||||||
|
tls:
|
||||||
|
certResolver: letsencrypt
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
middlewares:
|
middlewares:
|
||||||
csrf:
|
csrf:
|
||||||
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
|
# https://docs.traefik.io/master/middlewares/headers/#hostsproxyheaders
|
||||||
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
|
# https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
|
||||||
headers:
|
headers:
|
||||||
hostsProxyHeaders: ["X-CSRFToken"]
|
hostsProxyHeaders: ['X-CSRFToken']
|
||||||
|
|
||||||
services:
|
services:
|
||||||
django:
|
django:
|
||||||
|
@ -77,6 +93,13 @@ http:
|
||||||
servers:
|
servers:
|
||||||
- url: http://flower:5555
|
- url: http://flower:5555
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'None' %}
|
||||||
|
|
||||||
|
django-media:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- url: http://nginx:80
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
providers:
|
providers:
|
||||||
# https://docs.traefik.io/master/providers/file/
|
# https://docs.traefik.io/master/providers/file/
|
||||||
|
|
|
@ -15,8 +15,8 @@ from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
# This allows easy placement of apps within the interior
|
# This allows easy placement of apps within the interior
|
||||||
# {{ cookiecutter.project_slug }} directory.
|
# {{ cookiecutter.project_slug }} directory.
|
||||||
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent
|
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
|
||||||
sys.path.append(str(ROOT_DIR / "{{ cookiecutter.project_slug }}"))
|
sys.path.append(str(BASE_DIR / "{{ cookiecutter.project_slug }}"))
|
||||||
|
|
||||||
# If DJANGO_SETTINGS_MODULE is unset, default to the local settings
|
# If DJANGO_SETTINGS_MODULE is unset, default to the local settings
|
||||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
|
||||||
|
|
|
@ -5,15 +5,15 @@ from pathlib import Path
|
||||||
|
|
||||||
import environ
|
import environ
|
||||||
|
|
||||||
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent
|
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent.parent
|
||||||
# {{ cookiecutter.project_slug }}/
|
# {{ cookiecutter.project_slug }}/
|
||||||
APPS_DIR = ROOT_DIR / "{{ cookiecutter.project_slug }}"
|
APPS_DIR = BASE_DIR / "{{ cookiecutter.project_slug }}"
|
||||||
env = environ.Env()
|
env = environ.Env()
|
||||||
|
|
||||||
READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False)
|
READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=False)
|
||||||
if READ_DOT_ENV_FILE:
|
if READ_DOT_ENV_FILE:
|
||||||
# OS environment variables take precedence over variables from .env
|
# OS environment variables take precedence over variables from .env
|
||||||
env.read_env(str(ROOT_DIR / ".env"))
|
env.read_env(str(BASE_DIR / ".env"))
|
||||||
|
|
||||||
# GENERAL
|
# GENERAL
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -26,6 +26,12 @@ DEBUG = env.bool("DJANGO_DEBUG", False)
|
||||||
TIME_ZONE = "{{ cookiecutter.timezone }}"
|
TIME_ZONE = "{{ cookiecutter.timezone }}"
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#language-code
|
# https://docs.djangoproject.com/en/dev/ref/settings/#language-code
|
||||||
LANGUAGE_CODE = "en-us"
|
LANGUAGE_CODE = "en-us"
|
||||||
|
# https://docs.djangoproject.com/en/dev/ref/settings/#languages
|
||||||
|
# from django.utils.translation import gettext_lazy as _
|
||||||
|
# LANGUAGES = [
|
||||||
|
# ('en', _('English')),
|
||||||
|
# ('pt-br', _('Português')),
|
||||||
|
# ]
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#site-id
|
# https://docs.djangoproject.com/en/dev/ref/settings/#site-id
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
|
# https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
|
||||||
|
@ -33,7 +39,7 @@ USE_I18N = True
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
|
# https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths
|
# https://docs.djangoproject.com/en/dev/ref/settings/#locale-paths
|
||||||
LOCALE_PATHS = [str(ROOT_DIR / "locale")]
|
LOCALE_PATHS = [str(BASE_DIR / "locale")]
|
||||||
|
|
||||||
# DATABASES
|
# DATABASES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -87,6 +93,9 @@ THIRD_PARTY_APPS = [
|
||||||
"corsheaders",
|
"corsheaders",
|
||||||
"drf_spectacular",
|
"drf_spectacular",
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
"webpack_loader",
|
||||||
|
{%- endif %}
|
||||||
]
|
]
|
||||||
|
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
|
@ -127,9 +136,7 @@ PASSWORD_HASHERS = [
|
||||||
]
|
]
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
|
||||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
|
|
||||||
},
|
|
||||||
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
|
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
|
||||||
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
|
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
|
||||||
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
||||||
|
@ -152,14 +159,13 @@ MIDDLEWARE = [
|
||||||
"django.middleware.csrf.CsrfViewMiddleware",
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.common.BrokenLinkEmailsMiddleware",
|
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
# STATIC
|
# STATIC
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root
|
# https://docs.djangoproject.com/en/dev/ref/settings/#static-root
|
||||||
STATIC_ROOT = str(ROOT_DIR / "staticfiles")
|
STATIC_ROOT = str(BASE_DIR / "staticfiles")
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#static-url
|
# https://docs.djangoproject.com/en/dev/ref/settings/#static-url
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
|
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
|
||||||
|
@ -223,8 +229,6 @@ FIXTURE_DIRS = (str(APPS_DIR / "fixtures"),)
|
||||||
SESSION_COOKIE_HTTPONLY = True
|
SESSION_COOKIE_HTTPONLY = True
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly
|
# https://docs.djangoproject.com/en/dev/ref/settings/#csrf-cookie-httponly
|
||||||
CSRF_COOKIE_HTTPONLY = True
|
CSRF_COOKIE_HTTPONLY = True
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-browser-xss-filter
|
|
||||||
SECURE_BROWSER_XSS_FILTER = True
|
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options
|
# https://docs.djangoproject.com/en/dev/ref/settings/#x-frame-options
|
||||||
X_FRAME_OPTIONS = "DENY"
|
X_FRAME_OPTIONS = "DENY"
|
||||||
|
|
||||||
|
@ -246,6 +250,9 @@ ADMIN_URL = "admin/"
|
||||||
ADMINS = [("""{{cookiecutter.author_name}}""", "{{cookiecutter.email}}")]
|
ADMINS = [("""{{cookiecutter.author_name}}""", "{{cookiecutter.email}}")]
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
|
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
|
||||||
MANAGERS = ADMINS
|
MANAGERS = ADMINS
|
||||||
|
# https://cookiecutter-django.readthedocs.io/en/latest/settings.html#other-environment-settings
|
||||||
|
# Force the `admin` sign in process to go through the `django-allauth` workflow
|
||||||
|
DJANGO_ADMIN_FORCE_ALLAUTH = env.bool('DJANGO_ADMIN_FORCE_ALLAUTH', default=False)
|
||||||
|
|
||||||
# LOGGING
|
# LOGGING
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -257,9 +264,8 @@ LOGGING = {
|
||||||
"disable_existing_loggers": False,
|
"disable_existing_loggers": False,
|
||||||
"formatters": {
|
"formatters": {
|
||||||
"verbose": {
|
"verbose": {
|
||||||
"format": "%(levelname)s %(asctime)s %(module)s "
|
"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s",
|
||||||
"%(process)d %(thread)d %(message)s"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"handlers": {
|
"handlers": {
|
||||||
"console": {
|
"console": {
|
||||||
|
@ -312,9 +318,15 @@ CELERY_TASK_SEND_SENT_EVENT = True
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
|
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
|
||||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
ACCOUNT_AUTHENTICATION_METHOD = "username"
|
ACCOUNT_AUTHENTICATION_METHOD = "{{cookiecutter.username_type}}"
|
||||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
ACCOUNT_EMAIL_REQUIRED = True
|
ACCOUNT_EMAIL_REQUIRED = True
|
||||||
|
{%- if cookiecutter.username_type == "email" %}
|
||||||
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
|
ACCOUNT_USERNAME_REQUIRED = False
|
||||||
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
|
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
|
||||||
|
{%- endif %}
|
||||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
|
||||||
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
# https://django-allauth.readthedocs.io/en/latest/configuration.html
|
||||||
|
@ -356,6 +368,19 @@ SPECTACULAR_SETTINGS = {
|
||||||
"VERSION": "1.0.0",
|
"VERSION": "1.0.0",
|
||||||
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
|
||||||
}
|
}
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
# django-webpack-loader
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
WEBPACK_LOADER = {
|
||||||
|
"DEFAULT": {
|
||||||
|
"CACHE": not DEBUG,
|
||||||
|
"STATS_FILE": BASE_DIR / "webpack-stats.json",
|
||||||
|
"POLL_INTERVAL": 0.1,
|
||||||
|
"IGNORE": [r".+\.hot-update.js", r".+\.map"],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -37,9 +37,7 @@ EMAIL_HOST = "localhost"
|
||||||
EMAIL_PORT = 1025
|
EMAIL_PORT = 1025
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
|
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
|
||||||
EMAIL_BACKEND = env(
|
EMAIL_BACKEND = env("DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend")
|
||||||
"DJANGO_EMAIL_BACKEND", default="django.core.mail.backends.console.EmailBackend"
|
|
||||||
)
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{%- if cookiecutter.use_whitenoise == 'y' %}
|
{%- if cookiecutter.use_whitenoise == 'y' %}
|
||||||
|
@ -47,15 +45,15 @@ EMAIL_BACKEND = env(
|
||||||
# WhiteNoise
|
# WhiteNoise
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
|
# http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development
|
||||||
INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405
|
INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa: F405
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
# django-debug-toolbar
|
# django-debug-toolbar
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites
|
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites
|
||||||
INSTALLED_APPS += ["debug_toolbar"] # noqa F405
|
INSTALLED_APPS += ["debug_toolbar"] # noqa: F405
|
||||||
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware
|
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware
|
||||||
MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa F405
|
MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa: F405
|
||||||
# https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config
|
# https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config
|
||||||
DEBUG_TOOLBAR_CONFIG = {
|
DEBUG_TOOLBAR_CONFIG = {
|
||||||
"DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"],
|
"DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"],
|
||||||
|
@ -69,7 +67,7 @@ if env("USE_DOCKER") == "yes":
|
||||||
|
|
||||||
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
|
||||||
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
try:
|
try:
|
||||||
_, _, ips = socket.gethostbyname_ex("node")
|
_, _, ips = socket.gethostbyname_ex("node")
|
||||||
INTERNAL_IPS.extend(ips)
|
INTERNAL_IPS.extend(ips)
|
||||||
|
@ -82,7 +80,7 @@ if env("USE_DOCKER") == "yes":
|
||||||
# django-extensions
|
# django-extensions
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration
|
# https://django-extensions.readthedocs.io/en/latest/installation_instructions.html#configuration
|
||||||
INSTALLED_APPS += ["django_extensions"] # noqa F405
|
INSTALLED_APPS += ["django_extensions"] # noqa: F405
|
||||||
{% if cookiecutter.use_celery == 'y' -%}
|
{% if cookiecutter.use_celery == 'y' -%}
|
||||||
|
|
||||||
# Celery
|
# Celery
|
||||||
|
@ -94,6 +92,12 @@ CELERY_TASK_ALWAYS_EAGER = True
|
||||||
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-eager-propagates
|
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#task-eager-propagates
|
||||||
CELERY_TASK_EAGER_PROPAGATES = True
|
CELERY_TASK_EAGER_PROPAGATES = True
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
# django-webpack-loader
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
WEBPACK_LOADER["DEFAULT"]["CACHE"] = not DEBUG # noqa: F405
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
|
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
from sentry_sdk.integrations.celery import CeleryIntegration
|
from sentry_sdk.integrations.celery import CeleryIntegration
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
from sentry_sdk.integrations.logging import LoggingIntegration
|
from sentry_sdk.integrations.logging import LoggingIntegration
|
||||||
|
@ -22,7 +24,7 @@ ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["{{ cookiecutter.domai
|
||||||
|
|
||||||
# DATABASES
|
# DATABASES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa F405
|
DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60) # noqa: F405
|
||||||
|
|
||||||
# CACHES
|
# CACHES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -54,21 +56,17 @@ CSRF_COOKIE_SECURE = True
|
||||||
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works
|
# TODO: set this to 60 seconds first and then to 518400 once you prove the former works
|
||||||
SECURE_HSTS_SECONDS = 60
|
SECURE_HSTS_SECONDS = 60
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains
|
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-include-subdomains
|
||||||
SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool(
|
SECURE_HSTS_INCLUDE_SUBDOMAINS = env.bool("DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True)
|
||||||
"DJANGO_SECURE_HSTS_INCLUDE_SUBDOMAINS", default=True
|
|
||||||
)
|
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload
|
# https://docs.djangoproject.com/en/dev/ref/settings/#secure-hsts-preload
|
||||||
SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True)
|
SECURE_HSTS_PRELOAD = env.bool("DJANGO_SECURE_HSTS_PRELOAD", default=True)
|
||||||
# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff
|
# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff
|
||||||
SECURE_CONTENT_TYPE_NOSNIFF = env.bool(
|
SECURE_CONTENT_TYPE_NOSNIFF = env.bool("DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True)
|
||||||
"DJANGO_SECURE_CONTENT_TYPE_NOSNIFF", default=True
|
|
||||||
)
|
|
||||||
|
|
||||||
{% if cookiecutter.cloud_provider != 'None' -%}
|
{% if cookiecutter.cloud_provider != 'None' -%}
|
||||||
# STORAGES
|
# STORAGES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://django-storages.readthedocs.io/en/latest/#installation
|
# https://django-storages.readthedocs.io/en/latest/#installation
|
||||||
INSTALLED_APPS += ["storages"] # noqa F405
|
INSTALLED_APPS += ["storages"] # noqa: F405
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{% if cookiecutter.cloud_provider == 'AWS' %}
|
{% if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
||||||
|
@ -83,7 +81,7 @@ AWS_QUERYSTRING_AUTH = False
|
||||||
_AWS_EXPIRY = 60 * 60 * 24 * 7
|
_AWS_EXPIRY = 60 * 60 * 24 * 7
|
||||||
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
||||||
AWS_S3_OBJECT_PARAMETERS = {
|
AWS_S3_OBJECT_PARAMETERS = {
|
||||||
"CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate"
|
"CacheControl": f"max-age={_AWS_EXPIRY}, s-maxage={_AWS_EXPIRY}, must-revalidate",
|
||||||
}
|
}
|
||||||
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
# https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings
|
||||||
AWS_S3_MAX_MEMORY_SIZE = env.int(
|
AWS_S3_MAX_MEMORY_SIZE = env.int(
|
||||||
|
@ -159,7 +157,7 @@ ADMIN_URL = env("DJANGO_ADMIN_URL")
|
||||||
# Anymail
|
# Anymail
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://anymail.readthedocs.io/en/stable/installation/#installing-anymail
|
# https://anymail.readthedocs.io/en/stable/installation/#installing-anymail
|
||||||
INSTALLED_APPS += ["anymail"] # noqa F405
|
INSTALLED_APPS += ["anymail"] # noqa: F405
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
|
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
|
||||||
# https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference
|
# https://anymail.readthedocs.io/en/stable/installation/#anymail-settings-reference
|
||||||
{%- if cookiecutter.mail_service == 'Mailgun' %}
|
{%- if cookiecutter.mail_service == 'Mailgun' %}
|
||||||
|
@ -186,9 +184,7 @@ ANYMAIL = {
|
||||||
EMAIL_BACKEND = "anymail.backends.mandrill.EmailBackend"
|
EMAIL_BACKEND = "anymail.backends.mandrill.EmailBackend"
|
||||||
ANYMAIL = {
|
ANYMAIL = {
|
||||||
"MANDRILL_API_KEY": env("MANDRILL_API_KEY"),
|
"MANDRILL_API_KEY": env("MANDRILL_API_KEY"),
|
||||||
"MANDRILL_API_URL": env(
|
"MANDRILL_API_URL": env("MANDRILL_API_URL", default="https://mandrillapp.com/api/1.0"),
|
||||||
"MANDRILL_API_URL", default="https://mandrillapp.com/api/1.0"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
{%- elif cookiecutter.mail_service == 'Postmark' %}
|
{%- elif cookiecutter.mail_service == 'Postmark' %}
|
||||||
# https://anymail.readthedocs.io/en/stable/esps/postmark/
|
# https://anymail.readthedocs.io/en/stable/esps/postmark/
|
||||||
|
@ -209,18 +205,14 @@ ANYMAIL = {
|
||||||
EMAIL_BACKEND = "anymail.backends.sendinblue.EmailBackend"
|
EMAIL_BACKEND = "anymail.backends.sendinblue.EmailBackend"
|
||||||
ANYMAIL = {
|
ANYMAIL = {
|
||||||
"SENDINBLUE_API_KEY": env("SENDINBLUE_API_KEY"),
|
"SENDINBLUE_API_KEY": env("SENDINBLUE_API_KEY"),
|
||||||
"SENDINBLUE_API_URL": env(
|
"SENDINBLUE_API_URL": env("SENDINBLUE_API_URL", default="https://api.sendinblue.com/v3/"),
|
||||||
"SENDINBLUE_API_URL", default="https://api.sendinblue.com/v3/"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
{%- elif cookiecutter.mail_service == 'SparkPost' %}
|
{%- elif cookiecutter.mail_service == 'SparkPost' %}
|
||||||
# https://anymail.readthedocs.io/en/stable/esps/sparkpost/
|
# https://anymail.readthedocs.io/en/stable/esps/sparkpost/
|
||||||
EMAIL_BACKEND = "anymail.backends.sparkpost.EmailBackend"
|
EMAIL_BACKEND = "anymail.backends.sparkpost.EmailBackend"
|
||||||
ANYMAIL = {
|
ANYMAIL = {
|
||||||
"SPARKPOST_API_KEY": env("SPARKPOST_API_KEY"),
|
"SPARKPOST_API_KEY": env("SPARKPOST_API_KEY"),
|
||||||
"SPARKPOST_API_URL": env(
|
"SPARKPOST_API_URL": env("SPARKPOST_API_URL", default="https://api.sparkpost.com/api/v1"),
|
||||||
"SPARKPOST_API_URL", default="https://api.sparkpost.com/api/v1"
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
|
{%- elif cookiecutter.mail_service == 'Other SMTP' %}
|
||||||
# https://anymail.readthedocs.io/en/stable/esps
|
# https://anymail.readthedocs.io/en/stable/esps
|
||||||
|
@ -241,7 +233,7 @@ COMPRESS_STORAGE = "compressor.storage.GzipCompressorFileStorage"
|
||||||
COMPRESS_STORAGE = STATICFILES_STORAGE
|
COMPRESS_STORAGE = STATICFILES_STORAGE
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL
|
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_URL
|
||||||
COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa F405{% endif %}
|
COMPRESS_URL = STATIC_URL{% if cookiecutter.use_whitenoise == 'y' or cookiecutter.cloud_provider == 'None' %} # noqa: F405{% endif %}
|
||||||
{%- if cookiecutter.use_whitenoise == 'y' %}
|
{%- if cookiecutter.use_whitenoise == 'y' %}
|
||||||
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE
|
# https://django-compressor.readthedocs.io/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE
|
||||||
COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise
|
COMPRESS_OFFLINE = True # Offline compression is required when using Whitenoise
|
||||||
|
@ -259,7 +251,7 @@ COMPRESS_FILTERS = {
|
||||||
# Collectfast
|
# Collectfast
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://github.com/antonagestam/collectfast#installation
|
# https://github.com/antonagestam/collectfast#installation
|
||||||
INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa F405
|
INSTALLED_APPS = ["collectfast"] + INSTALLED_APPS # noqa: F405
|
||||||
{% endif %}
|
{% endif %}
|
||||||
# LOGGING
|
# LOGGING
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -276,9 +268,8 @@ LOGGING = {
|
||||||
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
|
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
|
||||||
"formatters": {
|
"formatters": {
|
||||||
"verbose": {
|
"verbose": {
|
||||||
"format": "%(levelname)s %(asctime)s %(module)s "
|
"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s",
|
||||||
"%(process)d %(thread)d %(message)s"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"handlers": {
|
"handlers": {
|
||||||
"mail_admins": {
|
"mail_admins": {
|
||||||
|
@ -312,9 +303,8 @@ LOGGING = {
|
||||||
"disable_existing_loggers": True,
|
"disable_existing_loggers": True,
|
||||||
"formatters": {
|
"formatters": {
|
||||||
"verbose": {
|
"verbose": {
|
||||||
"format": "%(levelname)s %(asctime)s %(module)s "
|
"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s",
|
||||||
"%(process)d %(thread)d %(message)s"
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"handlers": {
|
"handlers": {
|
||||||
"console": {
|
"console": {
|
||||||
|
@ -373,8 +363,8 @@ sentry_sdk.init(
|
||||||
# django-rest-framework
|
# django-rest-framework
|
||||||
# -------------------------------------------------------------------------------
|
# -------------------------------------------------------------------------------
|
||||||
# Tools that generate code samples can use SERVERS to point to the correct domain
|
# Tools that generate code samples can use SERVERS to point to the correct domain
|
||||||
SPECTACULAR_SETTINGS["SERVERS"] = [ # noqa F405
|
SPECTACULAR_SETTINGS["SERVERS"] = [ # noqa: F405
|
||||||
{"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"}
|
{"url": "https://{{ cookiecutter.domain_name }}", "description": "Production server"},
|
||||||
]
|
]
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -27,7 +27,13 @@ EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"
|
||||||
|
|
||||||
# DEBUGGING FOR TEMPLATES
|
# DEBUGGING FOR TEMPLATES
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa F405
|
TEMPLATES[0]["OPTIONS"]["debug"] = True # type: ignore # noqa: F405
|
||||||
|
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
# django-webpack-loader
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
WEBPACK_LOADER["DEFAULT"]["LOADER_CLASS"] = "webpack_loader.loader.FakeWebpackLoader" # noqa: F405
|
||||||
|
|
||||||
|
{%- endif %}
|
||||||
# Your stuff...
|
# Your stuff...
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,9 +14,7 @@ from rest_framework.authtoken.views import obtain_auth_token
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
path("", TemplateView.as_view(template_name="pages/home.html"), name="home"),
|
||||||
path(
|
path("about/", TemplateView.as_view(template_name="pages/about.html"), name="about"),
|
||||||
"about/", TemplateView.as_view(template_name="pages/about.html"), name="about"
|
|
||||||
),
|
|
||||||
# Django Admin, use {% raw %}{% url 'admin:index' %}{% endraw %}
|
# Django Admin, use {% raw %}{% url 'admin:index' %}{% endraw %}
|
||||||
path(settings.ADMIN_URL, admin.site.urls),
|
path(settings.ADMIN_URL, admin.site.urls),
|
||||||
# User management
|
# User management
|
||||||
|
|
|
@ -21,8 +21,8 @@ from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
# This allows easy placement of apps within the interior
|
# This allows easy placement of apps within the interior
|
||||||
# {{ cookiecutter.project_slug }} directory.
|
# {{ cookiecutter.project_slug }} directory.
|
||||||
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent
|
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
|
||||||
sys.path.append(str(ROOT_DIR / "{{ cookiecutter.project_slug }}"))
|
sys.path.append(str(BASE_DIR / "{{ cookiecutter.project_slug }}"))
|
||||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
||||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
||||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
||||||
|
|
|
@ -10,7 +10,7 @@ Welcome to {{ cookiecutter.project_name }}'s documentation!
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
howto{% if cookiecutter.use_pycharm == 'y' %}
|
howto{% if cookiecutter.editor == 'PyCharm' %}
|
||||||
pycharm/configuration{% endif %}
|
pycharm/configuration{% endif %}
|
||||||
users
|
users
|
||||||
|
|
||||||
|
|
|
@ -3,31 +3,31 @@
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
// Gulp and package
|
// Gulp and package
|
||||||
const { src, dest, parallel, series, watch } = require('gulp')
|
const { src, dest, parallel, series, watch } = require('gulp');
|
||||||
const pjson = require('./package.json')
|
const pjson = require('./package.json');
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
const autoprefixer = require('autoprefixer')
|
const autoprefixer = require('autoprefixer');
|
||||||
const browserSync = require('browser-sync').create()
|
const browserSync = require('browser-sync').create();
|
||||||
const concat = require('gulp-concat')
|
const concat = require('gulp-concat');
|
||||||
const cssnano = require ('cssnano')
|
const tildeImporter = require('node-sass-tilde-importer');
|
||||||
const imagemin = require('gulp-imagemin')
|
const cssnano = require('cssnano');
|
||||||
const pixrem = require('pixrem')
|
const imagemin = require('gulp-imagemin');
|
||||||
const plumber = require('gulp-plumber')
|
const pixrem = require('pixrem');
|
||||||
const postcss = require('gulp-postcss')
|
const plumber = require('gulp-plumber');
|
||||||
const reload = browserSync.reload
|
const postcss = require('gulp-postcss');
|
||||||
const rename = require('gulp-rename')
|
const reload = browserSync.reload;
|
||||||
const sass = require('gulp-sass')(require('sass'))
|
const rename = require('gulp-rename');
|
||||||
const spawn = require('child_process').spawn
|
const sass = require('gulp-sass')(require('sass'));
|
||||||
const uglify = require('gulp-uglify-es').default
|
const spawn = require('child_process').spawn;
|
||||||
|
const uglify = require('gulp-uglify-es').default;
|
||||||
|
|
||||||
// Relative paths function
|
// Relative paths function
|
||||||
function pathsConfig(appName) {
|
function pathsConfig(appName) {
|
||||||
this.app = `./${pjson.name}`
|
this.app = `./${pjson.name}`;
|
||||||
const vendorsRoot = 'node_modules'
|
const vendorsRoot = 'node_modules';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
bootstrapSass: `${vendorsRoot}/bootstrap/scss`,
|
|
||||||
vendorsJs: [
|
vendorsJs: [
|
||||||
`${vendorsRoot}/@popperjs/core/dist/umd/popper.js`,
|
`${vendorsRoot}/@popperjs/core/dist/umd/popper.js`,
|
||||||
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
|
`${vendorsRoot}/bootstrap/dist/js/bootstrap.js`,
|
||||||
|
@ -39,10 +39,10 @@ function pathsConfig(appName) {
|
||||||
fonts: `${this.app}/static/fonts`,
|
fonts: `${this.app}/static/fonts`,
|
||||||
images: `${this.app}/static/images`,
|
images: `${this.app}/static/images`,
|
||||||
js: `${this.app}/static/js`,
|
js: `${this.app}/static/js`,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const paths = pathsConfig()
|
const paths = pathsConfig();
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// Tasks
|
// Tasks
|
||||||
|
@ -53,25 +53,25 @@ function styles() {
|
||||||
const processCss = [
|
const processCss = [
|
||||||
autoprefixer(), // adds vendor prefixes
|
autoprefixer(), // adds vendor prefixes
|
||||||
pixrem(), // add fallbacks for rem units
|
pixrem(), // add fallbacks for rem units
|
||||||
]
|
];
|
||||||
|
|
||||||
const minifyCss = [
|
const minifyCss = [
|
||||||
cssnano({ preset: 'default' }) // minify result
|
cssnano({ preset: 'default' }), // minify result
|
||||||
]
|
];
|
||||||
|
|
||||||
return src(`${paths.sass}/project.scss`)
|
return src(`${paths.sass}/project.scss`)
|
||||||
.pipe(sass({
|
.pipe(
|
||||||
includePaths: [
|
sass({
|
||||||
paths.bootstrapSass,
|
importer: tildeImporter,
|
||||||
paths.sass
|
includePaths: [paths.sass],
|
||||||
]
|
}).on('error', sass.logError),
|
||||||
}).on('error', sass.logError))
|
)
|
||||||
.pipe(plumber()) // Checks for errors
|
.pipe(plumber()) // Checks for errors
|
||||||
.pipe(postcss(processCss))
|
.pipe(postcss(processCss))
|
||||||
.pipe(dest(paths.css))
|
.pipe(dest(paths.css))
|
||||||
.pipe(rename({ suffix: '.min' }))
|
.pipe(rename({ suffix: '.min' }))
|
||||||
.pipe(postcss(minifyCss)) // Minifies the result
|
.pipe(postcss(minifyCss)) // Minifies the result
|
||||||
.pipe(dest(paths.css))
|
.pipe(dest(paths.css));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Javascript minification
|
// Javascript minification
|
||||||
|
@ -80,57 +80,55 @@ function scripts() {
|
||||||
.pipe(plumber()) // Checks for errors
|
.pipe(plumber()) // Checks for errors
|
||||||
.pipe(uglify()) // Minifies the js
|
.pipe(uglify()) // Minifies the js
|
||||||
.pipe(rename({ suffix: '.min' }))
|
.pipe(rename({ suffix: '.min' }))
|
||||||
.pipe(dest(paths.js))
|
.pipe(dest(paths.js));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vendor Javascript minification
|
// Vendor Javascript minification
|
||||||
function vendorScripts() {
|
function vendorScripts() {
|
||||||
return src(paths.vendorsJs)
|
return src(paths.vendorsJs, { sourcemaps: true })
|
||||||
.pipe(concat('vendors.js'))
|
.pipe(concat('vendors.js'))
|
||||||
.pipe(dest(paths.js))
|
.pipe(dest(paths.js))
|
||||||
.pipe(plumber()) // Checks for errors
|
.pipe(plumber()) // Checks for errors
|
||||||
.pipe(uglify()) // Minifies the js
|
.pipe(uglify()) // Minifies the js
|
||||||
.pipe(rename({ suffix: '.min' }))
|
.pipe(rename({ suffix: '.min' }))
|
||||||
.pipe(dest(paths.js))
|
.pipe(dest(paths.js, { sourcemaps: '.' }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image compression
|
// Image compression
|
||||||
function imgCompression() {
|
function imgCompression() {
|
||||||
return src(`${paths.images}/*`)
|
return src(`${paths.images}/*`)
|
||||||
.pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images
|
.pipe(imagemin()) // Compresses PNG, JPEG, GIF and SVG images
|
||||||
.pipe(dest(paths.images))
|
.pipe(dest(paths.images));
|
||||||
}
|
}
|
||||||
|
|
||||||
{%- if cookiecutter.use_async == 'y' -%}
|
{%- if cookiecutter.use_async == 'y' -%}
|
||||||
// Run django server
|
// Run django server
|
||||||
function asyncRunServer() {
|
function asyncRunServer() {
|
||||||
const cmd = spawn('gunicorn', [
|
const cmd = spawn(
|
||||||
'config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload'
|
'gunicorn',
|
||||||
], {stdio: 'inherit'}
|
['config.asgi', '-k', 'uvicorn.workers.UvicornWorker', '--reload'],
|
||||||
)
|
{stdio: 'inherit'},
|
||||||
cmd.on('close', function(code) {
|
);
|
||||||
console.log('gunicorn exited with code ' + code)
|
cmd.on('close', function (code) {
|
||||||
|
console.log('gunicorn exited with code ' + code);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
// Run django server
|
// Run django server
|
||||||
function runServer(cb) {
|
function runServer(cb) {
|
||||||
const cmd = spawn('python', ['manage.py', 'runserver'], {stdio: 'inherit'})
|
const cmd = spawn('python', ['manage.py', 'runserver'], { stdio: 'inherit' });
|
||||||
cmd.on('close', function(code) {
|
cmd.on('close', function (code) {
|
||||||
console.log('runServer exited with code ' + code)
|
console.log('runServer exited with code ' + code);
|
||||||
cb(code)
|
cb(code);
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
// Browser sync server for live reload
|
// Browser sync server for live reload
|
||||||
function initBrowserSync() {
|
function initBrowserSync() {
|
||||||
browserSync.init(
|
browserSync.init(
|
||||||
[
|
[`${paths.css}/*.css`, `${paths.js}/*.js`, `${paths.templates}/*.html`],
|
||||||
`${paths.css}/*.css`,
|
{
|
||||||
`${paths.js}/*.js`,
|
|
||||||
`${paths.templates}/*.html`
|
|
||||||
], {
|
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
// https://www.browsersync.io/docs/options/#option-open
|
// https://www.browsersync.io/docs/options/#option-open
|
||||||
// Disable as it doesn't work from inside a container
|
// Disable as it doesn't work from inside a container
|
||||||
|
@ -144,44 +142,40 @@ function initBrowserSync() {
|
||||||
target: 'django:8000',
|
target: 'django:8000',
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
proxyReq: [
|
proxyReq: [
|
||||||
function(proxyReq, req) {
|
function (proxyReq, req) {
|
||||||
// Assign proxy "host" header same as current request at Browsersync server
|
// Assign proxy 'host' header same as current request at Browsersync server
|
||||||
proxyReq.setHeader('Host', req.headers.host)
|
proxyReq.setHeader('Host', req.headers.host);
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Watch
|
// Watch
|
||||||
function watchPaths() {
|
function watchPaths() {
|
||||||
watch(`${paths.sass}/*.scss`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, styles)
|
watch(`${paths.sass}/*.scss`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, styles);
|
||||||
watch(`${paths.templates}/**/*.html`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}).on("change", reload)
|
watch(`${paths.templates}/**/*.html`{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}).on('change', reload);
|
||||||
watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`]{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, scripts).on("change", reload)
|
watch([`${paths.js}/*.js`, `!${paths.js}/*.min.js`]{% if cookiecutter.windows == 'y' %}, { usePolling: true }{% endif %}, scripts).on(
|
||||||
|
'change',
|
||||||
|
reload,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate all assets
|
// Generate all assets
|
||||||
const generateAssets = parallel(
|
const generateAssets = parallel(styles, scripts, vendorScripts, imgCompression);
|
||||||
styles,
|
|
||||||
scripts,
|
|
||||||
vendorScripts,
|
|
||||||
imgCompression
|
|
||||||
)
|
|
||||||
|
|
||||||
// Set up dev environment
|
// Set up dev environment
|
||||||
const dev = parallel(
|
{%- if cookiecutter.use_docker == 'n' %}
|
||||||
{%- if cookiecutter.use_docker == 'n' %}
|
{%- if cookiecutter.use_async == 'y' %}
|
||||||
{%- if cookiecutter.use_async == 'y' %}
|
const dev = parallel(asyncRunServer, initBrowserSync, watchPaths);
|
||||||
asyncRunServer,
|
{%- else %}
|
||||||
{%- else %}
|
const dev = parallel(runServer, initBrowserSync, watchPaths);
|
||||||
runServer,
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- else %}
|
||||||
{%- endif %}
|
const dev = parallel(initBrowserSync, watchPaths);
|
||||||
initBrowserSync,
|
{%- endif %}
|
||||||
watchPaths
|
|
||||||
)
|
|
||||||
|
|
||||||
exports.default = series(generateAssets, dev)
|
exports.default = series(generateAssets, dev);
|
||||||
exports["generate-assets"] = generateAssets
|
exports['generate-assets'] = generateAssets;
|
||||||
exports["dev"] = dev
|
exports['dev'] = dev;
|
||||||
|
|
|
@ -25,7 +25,7 @@ services:
|
||||||
- ./.envs/.local/.django
|
- ./.envs/.local/.django
|
||||||
- ./.envs/.local/.postgres
|
- ./.envs/.local/.postgres
|
||||||
ports:
|
ports:
|
||||||
- "8000:8000"
|
- '8000:8000'
|
||||||
command: /start
|
command: /start
|
||||||
|
|
||||||
postgres:
|
postgres:
|
||||||
|
@ -53,7 +53,7 @@ services:
|
||||||
- ./config:/app/config:z
|
- ./config:/app/config:z
|
||||||
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
|
- ./{{ cookiecutter.project_slug }}:/app/{{ cookiecutter.project_slug }}:z
|
||||||
ports:
|
ports:
|
||||||
- "9000:9000"
|
- '9000:9000'
|
||||||
command: /start-docs
|
command: /start-docs
|
||||||
{%- if cookiecutter.use_mailhog == 'y' %}
|
{%- if cookiecutter.use_mailhog == 'y' %}
|
||||||
|
|
||||||
|
@ -101,11 +101,11 @@ services:
|
||||||
image: {{ cookiecutter.project_slug }}_local_flower
|
image: {{ cookiecutter.project_slug }}_local_flower
|
||||||
container_name: {{ cookiecutter.project_slug }}_local_flower
|
container_name: {{ cookiecutter.project_slug }}_local_flower
|
||||||
ports:
|
ports:
|
||||||
- "5555:5555"
|
- '5555:5555'
|
||||||
command: /start-flower
|
command: /start-flower
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
{%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %}
|
||||||
|
|
||||||
node:
|
node:
|
||||||
build:
|
build:
|
||||||
|
@ -121,8 +121,10 @@ services:
|
||||||
- /app/node_modules
|
- /app/node_modules
|
||||||
command: npm run dev
|
command: npm run dev
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- '3000:3000'
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
||||||
# Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui
|
# Expose browsersync UI: https://www.browsersync.io/docs/options/#option-ui
|
||||||
- "3001:3001"
|
- '3001:3001'
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
32
{{cookiecutter.project_slug}}/locale/README.md
Normal file
32
{{cookiecutter.project_slug}}/locale/README.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Translations
|
||||||
|
|
||||||
|
Start by configuring the `LANGUAGES` settings in `base.py`, by uncommenting languages you are willing to support. Then, translations strings will be placed in this folder when running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{% if cookiecutter.use_docker == 'y' %}docker-compose -f local.yml run --rm django {% endif %}python manage.py makemessages -all --no-location
|
||||||
|
```
|
||||||
|
|
||||||
|
This should generate `django.po` (stands for Portable Object) files under each locale `<locale name>/LC_MESSAGES/django.po`. Each translatable string in the codebase is collected with its `msgid` and need to be translated as `msgstr`, for example:
|
||||||
|
|
||||||
|
```po
|
||||||
|
msgid "users"
|
||||||
|
msgstr "utilisateurs"
|
||||||
|
```
|
||||||
|
|
||||||
|
Once all translations are done, they need to be compiled into `.mo` files (stands for Machine Object), which are the actual binary files used by the application:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
{% if cookiecutter.use_docker == 'y' %}docker-compose -f local.yml run --rm django {% endif %}python manage.py compilemessages
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the `.po` files are NOT used by the application directly, so if the `.mo` files are out of dates, the content won't appear as translated even if the `.po` files are up-to-date.
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
The production image runs `compilemessages` automatically at build time, so as long as your translated source files (PO) are up-to-date, you're good to go.
|
||||||
|
|
||||||
|
## Add a new language
|
||||||
|
|
||||||
|
1. Update the [`LANGUAGES` setting](https://docs.djangoproject.com/en/stable/ref/settings/#std-setting-LANGUAGES) to your project's base settings.
|
||||||
|
2. Create the locale folder for the language next to this file, e.g. `fr_FR` for French. Make sure the case is correct.
|
||||||
|
3. Run `makemessages` (as instructed above) to generate the PO files for the new language.
|
|
@ -1,6 +0,0 @@
|
||||||
Translations
|
|
||||||
============
|
|
||||||
|
|
||||||
Translations will be placed in this folder when running::
|
|
||||||
|
|
||||||
python manage.py makemessages
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Translations for the {{ cookiecutter.project_name }} project
|
||||||
|
# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }}
|
||||||
|
# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: {{ cookiecutter.version }}\n"
|
||||||
|
"Language: en-US\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
315
{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po
Normal file
315
{{cookiecutter.project_slug}}/locale/pt_BR/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,315 @@
|
||||||
|
# Translations for the {{ cookiecutter.project_name }} project
|
||||||
|
# Copyright (C) {% now 'utc', '%Y' %} {{ cookiecutter.author_name }}
|
||||||
|
# {{ cookiecutter.author_name }} <{{ cookiecutter.email }}>, {% now 'utc', '%Y' %}.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: {{ cookiecutter.version }}\n"
|
||||||
|
"Language: pt-BR\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:8
|
||||||
|
msgid "Account Inactive"
|
||||||
|
msgstr "Conta Inativa"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/account_inactive.html:10
|
||||||
|
msgid "This account is inactive."
|
||||||
|
msgstr "Esta conta está inativa."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:7
|
||||||
|
msgid "Account"
|
||||||
|
msgstr "Conta"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:10
|
||||||
|
msgid "E-mail Addresses"
|
||||||
|
msgstr "Endereços de E-mail"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:13
|
||||||
|
msgid "The following e-mail addresses are associated with your account:"
|
||||||
|
msgstr "Os seguintes endereços de e-mail estão associados à sua conta:"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:27
|
||||||
|
msgid "Verified"
|
||||||
|
msgstr "Verificado"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:29
|
||||||
|
msgid "Unverified"
|
||||||
|
msgstr "Não verificado"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:31
|
||||||
|
msgid "Primary"
|
||||||
|
msgstr "Primário"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:37
|
||||||
|
msgid "Make Primary"
|
||||||
|
msgstr "Tornar Primário"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:38
|
||||||
|
msgid "Re-send Verification"
|
||||||
|
msgstr "Reenviar verificação"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:39
|
||||||
|
msgid "Remove"
|
||||||
|
msgstr "Remover"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:46
|
||||||
|
msgid "Warning:"
|
||||||
|
msgstr "Aviso:"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:46
|
||||||
|
msgid ""
|
||||||
|
"You currently do not have any e-mail address set up. You should really add "
|
||||||
|
"an e-mail address so you can receive notifications, reset your password, etc."
|
||||||
|
msgstr ""
|
||||||
|
"No momento, você não tem nenhum endereço de e-mail configurado. Você "
|
||||||
|
"realmente deve adicionar um endereço de e-mail para receber notificações, "
|
||||||
|
"redefinir sua senha etc."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:51
|
||||||
|
msgid "Add E-mail Address"
|
||||||
|
msgstr "Adicionar Endereço de E-mail"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:56
|
||||||
|
msgid "Add E-mail"
|
||||||
|
msgstr "Adicionar E-mail"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email.html:66
|
||||||
|
msgid "Do you really want to remove the selected e-mail address?"
|
||||||
|
msgstr "Você realmente deseja remover o endereço de e-mail selecionado?"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:6
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:10
|
||||||
|
msgid "Confirm E-mail Address"
|
||||||
|
msgstr "Confirme o endereço de e-mail"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:16
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Please confirm that <a href=\"mailto:%(email)s\">%(email)s</a> is an e-mail "
|
||||||
|
"address for user %(user_display)s."
|
||||||
|
msgstr ""
|
||||||
|
"Confirme se <a href=\"mailto:%(email)s\">%(email)s</a> é um endereço de "
|
||||||
|
"e-mail do usuário %(user_display)s."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:20
|
||||||
|
msgid "Confirm"
|
||||||
|
msgstr "Confirmar"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/email_confirm.html:27
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"This e-mail confirmation link expired or is invalid. Please <a href="
|
||||||
|
"\"%(email_url)s\">issue a new e-mail confirmation request</a>."
|
||||||
|
msgstr "Este link de confirmação de e-mail expirou ou é inválido. "
|
||||||
|
"Por favor, <a href=\"%(email_url)s\">emita um novo pedido de confirmação por e-mail</a>."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:7
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:11
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:56
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/base.html:72
|
||||||
|
msgid "Sign In"
|
||||||
|
msgstr "Entrar"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:17
|
||||||
|
msgid "Please sign in with one of your existing third party accounts:"
|
||||||
|
msgstr "Faça login com uma de suas contas de terceiros existentes:"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:19
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Or, <a href=\"%(signup_url)s\">sign up</a> for a %(site_name)s account and "
|
||||||
|
"sign in below:"
|
||||||
|
msgstr "Ou, <a href=\"%(signup_url)s\">cadastre-se</a> para uma conta em %(site_name)s e entre abaixo:"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:32
|
||||||
|
msgid "or"
|
||||||
|
msgstr "or"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:41
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"If you have not created an account yet, then please <a href=\"%(signup_url)s"
|
||||||
|
"\">sign up</a> first."
|
||||||
|
msgstr "Se você ainda não criou uma conta, <a href=\"%(signup_url)s"
|
||||||
|
"\">registre-se primeiro</a>."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/login.html:55
|
||||||
|
msgid "Forgot Password?"
|
||||||
|
msgstr "Esqueceu sua senha?"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/logout.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/logout.html:8
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/logout.html:17
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/base.html:61
|
||||||
|
msgid "Sign Out"
|
||||||
|
msgstr "Sair"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/logout.html:10
|
||||||
|
msgid "Are you sure you want to sign out?"
|
||||||
|
msgstr "Você tem certeza que deseja sair?"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_change.html:6
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_change.html:9
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_change.html:14
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:4
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:7
|
||||||
|
msgid "Change Password"
|
||||||
|
msgstr "Alterar Senha"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:7
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:11
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:6
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:9
|
||||||
|
msgid "Password Reset"
|
||||||
|
msgstr "Redefinição de senha"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:16
|
||||||
|
msgid ""
|
||||||
|
"Forgotten your password? Enter your e-mail address below, and we'll send you "
|
||||||
|
"an e-mail allowing you to reset it."
|
||||||
|
msgstr "Esqueceu sua senha? Digite seu endereço de e-mail abaixo e enviaremos um e-mail permitindo que você o redefina."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:21
|
||||||
|
msgid "Reset My Password"
|
||||||
|
msgstr "Redefinir minha senha"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset.html:24
|
||||||
|
msgid "Please contact us if you have any trouble resetting your password."
|
||||||
|
msgstr "Entre em contato conosco se tiver algum problema para redefinir sua senha."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_done.html:15
|
||||||
|
msgid ""
|
||||||
|
"We have sent you an e-mail. Please contact us if you do not receive it "
|
||||||
|
"within a few minutes."
|
||||||
|
msgstr "Enviamos um e-mail para você. Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:8
|
||||||
|
msgid "Bad Token"
|
||||||
|
msgstr "Token Inválido"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:12
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"The password reset link was invalid, possibly because it has already been "
|
||||||
|
"used. Please request a <a href=\"%(passwd_reset_url)s\">new password reset</"
|
||||||
|
"a>."
|
||||||
|
msgstr "O link de redefinição de senha era inválido, possivelmente porque já foi usado. "
|
||||||
|
"<a href=\"%(passwd_reset_url)s\">Solicite uma nova redefinição de senha</a>."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:18
|
||||||
|
msgid "change password"
|
||||||
|
msgstr "alterar senha"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key.html:21
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_reset_from_key_done.html:8
|
||||||
|
msgid "Your password is now changed."
|
||||||
|
msgstr "Sua senha agora foi alterada."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_set.html:6
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_set.html:9
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/password_set.html:14
|
||||||
|
msgid "Set Password"
|
||||||
|
msgstr "Definir Senha"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup.html:6
|
||||||
|
msgid "Signup"
|
||||||
|
msgstr "Cadastro"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup.html:9
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup.html:19
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/base.html:67
|
||||||
|
msgid "Sign Up"
|
||||||
|
msgstr "Cadastro"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup.html:11
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"Already have an account? Then please <a href=\"%(login_url)s\">sign in</a>."
|
||||||
|
msgstr "já tem uma conta? Então, por favor, faça <a href=\"%(login_url)s\">login</a>."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:8
|
||||||
|
msgid "Sign Up Closed"
|
||||||
|
msgstr "Inscrições encerradas"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/signup_closed.html:10
|
||||||
|
msgid "We are sorry, but the sign up is currently closed."
|
||||||
|
msgstr "Lamentamos, mas as inscrições estão encerradas no momento."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:8
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:5
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:8
|
||||||
|
msgid "Verify Your E-mail Address"
|
||||||
|
msgstr "Verifique seu endereço de e-mail"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verification_sent.html:10
|
||||||
|
msgid ""
|
||||||
|
"We have sent an e-mail to you for verification. Follow the link provided to "
|
||||||
|
"finalize the signup process. Please contact us if you do not receive it "
|
||||||
|
"within a few minutes."
|
||||||
|
msgstr "Enviamos um e-mail para você para verificação. Siga o link fornecido para finalizar o processo de inscrição. Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:12
|
||||||
|
msgid ""
|
||||||
|
"This part of the site requires us to verify that\n"
|
||||||
|
"you are who you claim to be. For this purpose, we require that you\n"
|
||||||
|
"verify ownership of your e-mail address. "
|
||||||
|
msgstr "Esta parte do site exige que verifiquemos se você é quem afirma ser.\n"
|
||||||
|
"Para esse fim, exigimos que você verifique a propriedade\n"
|
||||||
|
"do seu endereço de e-mail."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:16
|
||||||
|
msgid ""
|
||||||
|
"We have sent an e-mail to you for\n"
|
||||||
|
"verification. Please click on the link inside this e-mail. Please\n"
|
||||||
|
"contact us if you do not receive it within a few minutes."
|
||||||
|
msgstr "Enviamos um e-mail para você para verificação.\n"
|
||||||
|
"Por favor, clique no link dentro deste e-mail.\n"
|
||||||
|
"Entre em contato conosco se você não recebê-lo dentro de alguns minutos."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/account/verified_email_required.html:20
|
||||||
|
#, python-format
|
||||||
|
msgid ""
|
||||||
|
"<strong>Note:</strong> you can still <a href=\"%(email_url)s\">change your e-"
|
||||||
|
"mail address</a>."
|
||||||
|
msgstr "<strong>Nota</strong>: você ainda pode <a href=\"%(email_url)s\">alterar seu endereço de e-mail</a>."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/templates/base.html:57
|
||||||
|
msgid "My Profile"
|
||||||
|
msgstr "Meu perfil"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/admin.py:17
|
||||||
|
msgid "Personal info"
|
||||||
|
msgstr "Informação pessoal"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/admin.py:19
|
||||||
|
msgid "Permissions"
|
||||||
|
msgstr "Permissões"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/admin.py:30
|
||||||
|
msgid "Important dates"
|
||||||
|
msgstr "Datas importantes"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/apps.py:7
|
||||||
|
msgid "Users"
|
||||||
|
msgstr "Usuários"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/forms.py:24
|
||||||
|
#: {{cookiecutter.project_slug}}/users/tests/test_forms.py:36
|
||||||
|
msgid "This username has already been taken."
|
||||||
|
msgstr "Este nome de usuário já foi usado."
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/models.py:15
|
||||||
|
msgid "Name of User"
|
||||||
|
msgstr "Nome do Usuário"
|
||||||
|
|
||||||
|
#: {{cookiecutter.project_slug}}/users/views.py:23
|
||||||
|
msgid "Information successfully updated"
|
||||||
|
msgstr "Informação atualizada com sucesso"
|
|
@ -2,66 +2,25 @@ import os
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
BASE_DIR = Path(__file__).parent.resolve()
|
||||||
|
PRODUCTION_DOTENVS_DIR = BASE_DIR / ".envs" / ".production"
|
||||||
ROOT_DIR_PATH = Path(__file__).parent.resolve()
|
PRODUCTION_DOTENV_FILES = [
|
||||||
PRODUCTION_DOTENVS_DIR_PATH = ROOT_DIR_PATH / ".envs" / ".production"
|
PRODUCTION_DOTENVS_DIR / ".django",
|
||||||
PRODUCTION_DOTENV_FILE_PATHS = [
|
PRODUCTION_DOTENVS_DIR / ".postgres",
|
||||||
PRODUCTION_DOTENVS_DIR_PATH / ".django",
|
|
||||||
PRODUCTION_DOTENVS_DIR_PATH / ".postgres",
|
|
||||||
]
|
]
|
||||||
DOTENV_FILE_PATH = ROOT_DIR_PATH / ".env"
|
DOTENV_FILE = BASE_DIR / ".env"
|
||||||
|
|
||||||
|
|
||||||
def merge(
|
def merge(
|
||||||
output_file_path: str, merged_file_paths: Sequence[str], append_linesep: bool = True
|
output_file: Path,
|
||||||
|
files_to_merge: Sequence[Path],
|
||||||
) -> None:
|
) -> None:
|
||||||
with open(output_file_path, "w") as output_file:
|
merged_content = ""
|
||||||
for merged_file_path in merged_file_paths:
|
for merge_file in files_to_merge:
|
||||||
with open(merged_file_path) as merged_file:
|
merged_content += merge_file.read_text()
|
||||||
merged_file_content = merged_file.read()
|
merged_content += os.linesep
|
||||||
output_file.write(merged_file_content)
|
output_file.write_text(merged_content)
|
||||||
if append_linesep:
|
|
||||||
output_file.write(os.linesep)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
merge(DOTENV_FILE_PATH, PRODUCTION_DOTENV_FILE_PATHS)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("merged_file_count", range(3))
|
|
||||||
@pytest.mark.parametrize("append_linesep", [True, False])
|
|
||||||
def test_merge(tmpdir_factory, merged_file_count: int, append_linesep: bool):
|
|
||||||
tmp_dir_path = Path(str(tmpdir_factory.getbasetemp()))
|
|
||||||
|
|
||||||
output_file_path = tmp_dir_path / ".env"
|
|
||||||
|
|
||||||
expected_output_file_content = ""
|
|
||||||
merged_file_paths = []
|
|
||||||
for i in range(merged_file_count):
|
|
||||||
merged_file_ord = i + 1
|
|
||||||
|
|
||||||
merged_filename = f".service{merged_file_ord}"
|
|
||||||
merged_file_path = tmp_dir_path / merged_filename
|
|
||||||
|
|
||||||
merged_file_content = merged_filename * merged_file_ord
|
|
||||||
|
|
||||||
with open(merged_file_path, "w+") as file:
|
|
||||||
file.write(merged_file_content)
|
|
||||||
|
|
||||||
expected_output_file_content += merged_file_content
|
|
||||||
if append_linesep:
|
|
||||||
expected_output_file_content += os.linesep
|
|
||||||
|
|
||||||
merged_file_paths.append(merged_file_path)
|
|
||||||
|
|
||||||
merge(output_file_path, merged_file_paths, append_linesep)
|
|
||||||
|
|
||||||
with open(output_file_path) as output_file:
|
|
||||||
actual_output_file_content = output_file.read()
|
|
||||||
|
|
||||||
assert actual_output_file_content == expected_output_file_content
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
merge(DOTENV_FILE, PRODUCTION_DOTENV_FILES)
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "{{cookiecutter.project_slug}}",
|
"name": "{{cookiecutter.project_slug}}",
|
||||||
"version": "{{ cookiecutter.version }}",
|
"version": "{{ cookiecutter.version }}",
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"bootstrap": "^5.1.3",
|
"@babel/core": "^7.16.5",
|
||||||
"gulp-concat": "^2.6.1",
|
"@babel/preset-env": "^7.16.5",
|
||||||
"@popperjs/core": "^2.10.2",
|
"@popperjs/core": "^2.10.2",
|
||||||
"autoprefixer": "^10.4.0",
|
"autoprefixer": "^10.4.0",
|
||||||
|
"babel-loader": "^9.1.2",
|
||||||
|
"bootstrap": "^5.2.3",
|
||||||
"browser-sync": "^2.27.7",
|
"browser-sync": "^2.27.7",
|
||||||
"cssnano": "^5.0.11",
|
"css-loader": "^6.5.1",
|
||||||
|
"gulp-concat": "^2.6.1",
|
||||||
|
"concurrently": "^8.0.1",
|
||||||
|
"cssnano": "^6.0.0",
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-imagemin": "^7.1.0",
|
"gulp-imagemin": "^7.1.0",
|
||||||
"gulp-plumber": "^1.2.1",
|
"gulp-plumber": "^1.2.1",
|
||||||
|
@ -16,18 +20,31 @@
|
||||||
"gulp-rename": "^2.0.0",
|
"gulp-rename": "^2.0.0",
|
||||||
"gulp-sass": "^5.0.0",
|
"gulp-sass": "^5.0.0",
|
||||||
"gulp-uglify-es": "^3.0.0",
|
"gulp-uglify-es": "^3.0.0",
|
||||||
|
"mini-css-extract-plugin": "^2.4.5",
|
||||||
|
"node-sass-tilde-importer": "^1.0.2",
|
||||||
"pixrem": "^5.0.0",
|
"pixrem": "^5.0.0",
|
||||||
"postcss": "^8.3.11",
|
"postcss": "^8.3.11",
|
||||||
"sass": "^1.43.4"
|
"postcss-loader": "^7.0.2",
|
||||||
|
"postcss-preset-env": "^9.0.0",
|
||||||
|
"sass": "^1.43.4",
|
||||||
|
"sass-loader": "^13.2.0",
|
||||||
|
"webpack": "^5.65.0",
|
||||||
|
"webpack-bundle-tracker": "^2.0.0",
|
||||||
|
"webpack-cli": "^5.0.1",
|
||||||
|
"webpack-dev-server": "^4.6.0",
|
||||||
|
"webpack-merge": "^5.8.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16"
|
"node": "18"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"last 2 versions"
|
"last 2 versions"
|
||||||
],
|
],
|
||||||
|
"babel": {
|
||||||
|
"presets": ["@babel/preset-env"]
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "gulp",
|
"dev": "",
|
||||||
"build": "gulp generate-assets"
|
"build": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,33 @@ volumes:
|
||||||
production_postgres_data: {}
|
production_postgres_data: {}
|
||||||
production_postgres_data_backups: {}
|
production_postgres_data_backups: {}
|
||||||
production_traefik: {}
|
production_traefik: {}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'None' %}
|
||||||
|
production_django_media: {}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
services:
|
services:
|
||||||
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
django:{% if cookiecutter.use_celery == 'y' %} &django{% endif %}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ./compose/production/django/Dockerfile
|
dockerfile: ./compose/production/django/Dockerfile
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' and cookiecutter.use_whitenoise == 'n' %}
|
||||||
|
args:
|
||||||
|
# These variable can be defined in an .env file in the root of the repo
|
||||||
|
{%- if cookiecutter.cloud_provider == 'AWS' %}
|
||||||
|
DJANGO_AWS_STORAGE_BUCKET_NAME: ${DJANGO_AWS_STORAGE_BUCKET_NAME}
|
||||||
|
DJANGO_AWS_S3_CUSTOM_DOMAIN: ${DJANGO_AWS_S3_CUSTOM_DOMAIN}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'GCP' %}
|
||||||
|
DJANGO_GCP_STORAGE_BUCKET_NAME: ${DJANGO_GCP_STORAGE_BUCKET_NAME}
|
||||||
|
{%- elif cookiecutter.cloud_provider == 'Azure' %}
|
||||||
|
DJANGO_AZURE_ACCOUNT_NAME: ${DJANGO_AZURE_ACCOUNT_NAME}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
image: {{ cookiecutter.project_slug }}_production_django
|
image: {{ cookiecutter.project_slug }}_production_django
|
||||||
|
{%- if cookiecutter.cloud_provider == 'None' %}
|
||||||
|
volumes:
|
||||||
|
- production_django_media:/app/{{ cookiecutter.project_slug }}/media
|
||||||
|
{%- endif %}
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
@ -40,10 +60,10 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- production_traefik:/etc/traefik/acme
|
- production_traefik:/etc/traefik/acme
|
||||||
ports:
|
ports:
|
||||||
- "0.0.0.0:80:80"
|
- '0.0.0.0:80:80'
|
||||||
- "0.0.0.0:443:443"
|
- '0.0.0.0:443:443'
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
- "0.0.0.0:5555:5555"
|
- '0.0.0.0:5555:5555'
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
|
@ -76,3 +96,15 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- production_postgres_data_backups:/backups:z
|
- production_postgres_data_backups:/backups:z
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.cloud_provider == 'None' %}
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ./compose/production/nginx/Dockerfile
|
||||||
|
image: {{ cookiecutter.project_slug }}_local_nginx
|
||||||
|
depends_on:
|
||||||
|
- django
|
||||||
|
volumes:
|
||||||
|
- production_django_media:/usr/share/nginx/media:ro
|
||||||
|
{%- endif %}
|
||||||
|
|
112
{{cookiecutter.project_slug}}/pyproject.toml
Normal file
112
{{cookiecutter.project_slug}}/pyproject.toml
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
# ==== pytest ====
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
minversion = "6.0"
|
||||||
|
addopts = "--ds=config.settings.test --reuse-db"
|
||||||
|
python_files = [
|
||||||
|
"tests.py",
|
||||||
|
"test_*.py",
|
||||||
|
]
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
||||||
|
norecursedirs = ["node_modules"]
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
# ==== Coverage ====
|
||||||
|
[tool.coverage.run]
|
||||||
|
include = ["{{cookiecutter.project_slug}}/**"]
|
||||||
|
omit = ["*/migrations/*", "*/tests/*"]
|
||||||
|
plugins = ["django_coverage_plugin"]
|
||||||
|
|
||||||
|
|
||||||
|
# ==== black ====
|
||||||
|
[tool.black]
|
||||||
|
line-length = 119
|
||||||
|
target-version = ['py311']
|
||||||
|
|
||||||
|
|
||||||
|
# ==== isort ====
|
||||||
|
[tool.isort]
|
||||||
|
profile = "black"
|
||||||
|
line_length = 119
|
||||||
|
known_first_party = [
|
||||||
|
"{{cookiecutter.project_slug}}",
|
||||||
|
"config",
|
||||||
|
]
|
||||||
|
skip = ["venv/"]
|
||||||
|
skip_glob = ["**/migrations/*.py"]
|
||||||
|
|
||||||
|
|
||||||
|
# ==== mypy ====
|
||||||
|
[tool.mypy]
|
||||||
|
python_version = "3.11"
|
||||||
|
check_untyped_defs = true
|
||||||
|
ignore_missing_imports = true
|
||||||
|
warn_unused_ignores = true
|
||||||
|
warn_redundant_casts = true
|
||||||
|
warn_unused_configs = true
|
||||||
|
plugins = [
|
||||||
|
"mypy_django_plugin.main",
|
||||||
|
{%- if cookiecutter.use_drf == "y" %}
|
||||||
|
"mypy_drf_plugin.main",
|
||||||
|
{%- endif %}
|
||||||
|
]
|
||||||
|
|
||||||
|
[[tool.mypy.overrides]]
|
||||||
|
# Django migrations should not produce any errors:
|
||||||
|
module = "*.migrations.*"
|
||||||
|
ignore_errors = true
|
||||||
|
|
||||||
|
[tool.django-stubs]
|
||||||
|
django_settings_module = "config.settings.test"
|
||||||
|
|
||||||
|
|
||||||
|
# ==== PyLint ====
|
||||||
|
[tool.pylint.MASTER]
|
||||||
|
load-plugins = [
|
||||||
|
"pylint_django",
|
||||||
|
{%- if cookiecutter.use_celery == "y" %}
|
||||||
|
"pylint_celery",
|
||||||
|
{%- endif %}
|
||||||
|
]
|
||||||
|
django-settings-module = "config.settings.local"
|
||||||
|
|
||||||
|
[tool.pylint.FORMAT]
|
||||||
|
max-line-length = 119
|
||||||
|
|
||||||
|
[tool.pylint."MESSAGES CONTROL"]
|
||||||
|
disable = [
|
||||||
|
"missing-docstring",
|
||||||
|
"invalid-name",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.pylint.DESIGN]
|
||||||
|
max-parents = 13
|
||||||
|
|
||||||
|
[tool.pylint.TYPECHECK]
|
||||||
|
generated-members = [
|
||||||
|
"REQUEST",
|
||||||
|
"acl_users",
|
||||||
|
"aq_parent",
|
||||||
|
"[a-zA-Z]+_set{1,2}",
|
||||||
|
"save",
|
||||||
|
"delete",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# ==== djLint ====
|
||||||
|
[tool.djlint]
|
||||||
|
blank_line_after_tag = "load,extends"
|
||||||
|
close_void_tags = true
|
||||||
|
format_css = true
|
||||||
|
format_js = true
|
||||||
|
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687
|
||||||
|
ignore = "H006,H030,H031,T002"
|
||||||
|
include = "H017,H035"
|
||||||
|
indent = 2
|
||||||
|
max_line_length = 119
|
||||||
|
profile = "django"
|
||||||
|
|
||||||
|
[tool.djlint.css]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[tool.djlint.js]
|
||||||
|
indent_size = 2
|
|
@ -1,6 +0,0 @@
|
||||||
[pytest]
|
|
||||||
addopts = --ds=config.settings.test --reuse-db
|
|
||||||
python_files = tests.py test_*.py
|
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Gulp' %}
|
|
||||||
norecursedirs = node_modules
|
|
||||||
{%- endif %}
|
|
|
@ -1,6 +1,5 @@
|
||||||
pytz==2022.7 # https://github.com/stub42/pytz
|
python-slugify==8.0.1 # https://github.com/un33k/python-slugify
|
||||||
python-slugify==7.0.0 # https://github.com/un33k/python-slugify
|
Pillow==9.5.0 # https://github.com/python-pillow/Pillow
|
||||||
Pillow==9.4.0 # https://github.com/python-pillow/Pillow
|
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
|
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
|
||||||
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
|
{%- if cookiecutter.windows == 'y' and cookiecutter.use_docker == 'n' %}
|
||||||
rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin
|
rcssmin==1.1.0 --install-option="--without-c-extensions" # https://github.com/ndparker/rcssmin
|
||||||
|
@ -10,39 +9,42 @@ rcssmin==1.1.1 # https://github.com/ndparker/rcssmin
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
|
argon2-cffi==21.3.0 # https://github.com/hynek/argon2_cffi
|
||||||
{%- if cookiecutter.use_whitenoise == 'y' %}
|
{%- if cookiecutter.use_whitenoise == 'y' %}
|
||||||
whitenoise==6.3.0 # https://github.com/evansd/whitenoise
|
whitenoise==6.5.0 # https://github.com/evansd/whitenoise
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
redis==4.4.1 # https://github.com/redis/redis-py
|
redis==4.6.0 # https://github.com/redis/redis-py
|
||||||
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
|
{%- if cookiecutter.use_docker == "y" or cookiecutter.windows == "n" %}
|
||||||
hiredis==2.1.1 # https://github.com/redis/hiredis-py
|
hiredis==2.2.3 # https://github.com/redis/hiredis-py
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.use_celery == "y" %}
|
{%- if cookiecutter.use_celery == "y" %}
|
||||||
celery==5.2.7 # pyup: < 6.0 # https://github.com/celery/celery
|
celery==5.3.1 # pyup: < 6.0 # https://github.com/celery/celery
|
||||||
django-celery-beat==2.4.0 # https://github.com/celery/django-celery-beat
|
django-celery-beat==2.5.0 # https://github.com/celery/django-celery-beat
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
flower==1.2.0 # https://github.com/mher/flower
|
flower==2.0.0 # https://github.com/mher/flower
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.use_async == 'y' %}
|
{%- if cookiecutter.use_async == 'y' %}
|
||||||
uvicorn[standard]==0.20.0 # https://github.com/encode/uvicorn
|
uvicorn[standard]==0.22.0 # https://github.com/encode/uvicorn
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
django==4.0.8 # pyup: < 4.1 # https://www.djangoproject.com/
|
django==4.2.3 # pyup: < 5.0 # https://www.djangoproject.com/
|
||||||
django-environ==0.9.0 # https://github.com/joke2k/django-environ
|
django-environ==0.10.0 # https://github.com/joke2k/django-environ
|
||||||
django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils
|
django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils
|
||||||
django-allauth==0.52.0 # https://github.com/pennersr/django-allauth
|
django-allauth==0.54.0 # https://github.com/pennersr/django-allauth
|
||||||
django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-crispy-forms
|
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
|
crispy-bootstrap5==0.7 # https://github.com/django-crispy-forms/crispy-bootstrap5
|
||||||
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
|
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
|
||||||
django-compressor==4.3 # https://github.com/django-compressor/django-compressor
|
django-compressor==4.4 # https://github.com/django-compressor/django-compressor
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
django-redis==5.2.0 # https://github.com/jazzband/django-redis
|
django-redis==5.3.0 # https://github.com/jazzband/django-redis
|
||||||
{%- if cookiecutter.use_drf == 'y' %}
|
{%- if cookiecutter.use_drf == 'y' %}
|
||||||
# Django REST Framework
|
# Django REST Framework
|
||||||
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
|
djangorestframework==3.14.0 # https://github.com/encode/django-rest-framework
|
||||||
django-cors-headers==3.13.0 # https://github.com/adamchainz/django-cors-headers
|
django-cors-headers==4.1.0 # https://github.com/adamchainz/django-cors-headers
|
||||||
# DRF-spectacular for api documentation
|
# DRF-spectacular for api documentation
|
||||||
drf-spectacular==0.25.1 # https://github.com/tfranzel/drf-spectacular
|
drf-spectacular==0.26.3 # https://github.com/tfranzel/drf-spectacular
|
||||||
|
{%- endif %}
|
||||||
|
{%- if cookiecutter.frontend_pipeline == 'Webpack' %}
|
||||||
|
django-webpack-loader==2.0.1 # https://github.com/django-webpack/django-webpack-loader
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
@ -1,48 +1,49 @@
|
||||||
-r base.txt
|
-r base.txt
|
||||||
|
|
||||||
Werkzeug[watchdog]==2.2.2 # https://github.com/pallets/werkzeug
|
Werkzeug[watchdog]==2.3.6 # https://github.com/pallets/werkzeug
|
||||||
ipdb==0.13.11 # https://github.com/gotcha/ipdb
|
ipdb==0.13.13 # https://github.com/gotcha/ipdb
|
||||||
{%- if cookiecutter.use_docker == 'y' %}
|
{%- if cookiecutter.use_docker == 'y' %}
|
||||||
psycopg2==2.9.5 # https://github.com/psycopg/psycopg2
|
psycopg[c]==3.1.9 # https://github.com/psycopg/psycopg
|
||||||
{%- else %}
|
{%- else %}
|
||||||
psycopg2-binary==2.9.5 # https://github.com/psycopg/psycopg2
|
psycopg[binary]==3.1.9 # https://github.com/psycopg/psycopg
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_async == 'y' or cookiecutter.use_celery == 'y' %}
|
||||||
watchfiles==0.18.1 # https://github.com/samuelcolvin/watchfiles
|
watchfiles==0.19.0 # https://github.com/samuelcolvin/watchfiles
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
mypy==0.982 # https://github.com/python/mypy
|
mypy==1.4.1 # https://github.com/python/mypy
|
||||||
django-stubs==1.13.1 # https://github.com/typeddjango/django-stubs
|
django-stubs==4.2.3 # https://github.com/typeddjango/django-stubs
|
||||||
pytest==7.2.0 # https://github.com/pytest-dev/pytest
|
pytest==7.4.0 # https://github.com/pytest-dev/pytest
|
||||||
pytest-sugar==0.9.6 # https://github.com/Frozenball/pytest-sugar
|
pytest-sugar==0.9.7 # https://github.com/Frozenball/pytest-sugar
|
||||||
{%- if cookiecutter.use_drf == "y" %}
|
{%- if cookiecutter.use_drf == "y" %}
|
||||||
djangorestframework-stubs==1.8.0 # https://github.com/typeddjango/djangorestframework-stubs
|
djangorestframework-stubs==3.14.2 # https://github.com/typeddjango/djangorestframework-stubs
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
sphinx==5.3.0 # https://github.com/sphinx-doc/sphinx
|
sphinx==6.2.1 # https://github.com/sphinx-doc/sphinx
|
||||||
sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild
|
sphinx-autobuild==2021.3.14 # https://github.com/GaretJax/sphinx-autobuild
|
||||||
|
|
||||||
# Code quality
|
# Code quality
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
flake8==6.0.0 # https://github.com/PyCQA/flake8
|
flake8==6.0.0 # https://github.com/PyCQA/flake8
|
||||||
flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort
|
flake8-isort==6.0.0 # https://github.com/gforcada/flake8-isort
|
||||||
coverage==7.0.4 # https://github.com/nedbat/coveragepy
|
coverage==7.2.7 # https://github.com/nedbat/coveragepy
|
||||||
black==22.12.0 # https://github.com/psf/black
|
black==23.3.0 # https://github.com/psf/black
|
||||||
|
djlint==1.31.1 # https://github.com/Riverside-Healthcare/djLint
|
||||||
pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django
|
pylint-django==2.5.3 # https://github.com/PyCQA/pylint-django
|
||||||
{%- if cookiecutter.use_celery == 'y' %}
|
{%- if cookiecutter.use_celery == 'y' %}
|
||||||
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
|
pylint-celery==0.3 # https://github.com/PyCQA/pylint-celery
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
pre-commit==2.21.0 # https://github.com/pre-commit/pre-commit
|
pre-commit==3.3.3 # https://github.com/pre-commit/pre-commit
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy
|
factory-boy==3.2.1 # https://github.com/FactoryBoy/factory_boy
|
||||||
|
|
||||||
django-debug-toolbar==3.8.1 # https://github.com/jazzband/django-debug-toolbar
|
django-debug-toolbar==4.1.0 # https://github.com/jazzband/django-debug-toolbar
|
||||||
django-extensions==3.2.1 # https://github.com/django-extensions/django-extensions
|
django-extensions==3.2.3 # https://github.com/django-extensions/django-extensions
|
||||||
django-coverage-plugin==3.0.0 # https://github.com/nedbat/django_coverage_plugin
|
django-coverage-plugin==3.0.0 # https://github.com/nedbat/django_coverage_plugin
|
||||||
pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django
|
pytest-django==4.5.2 # https://github.com/pytest-dev/pytest-django
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user