Merge branch 'cookiecutter-master'

This commit is contained in:
Alejandro Franco 2024-04-24 13:47:04 -06:00
commit 0ecbcbd6d4
46 changed files with 452 additions and 106 deletions

View File

@ -1538,5 +1538,30 @@
"name": "Simeon Emanuilov", "name": "Simeon Emanuilov",
"github_login": "s-emanuilov", "github_login": "s-emanuilov",
"twitter_username": "s_emanuilov" "twitter_username": "s_emanuilov"
},
{
"name": "Patrick Zhang",
"github_login": "PatDuJour",
"twitter_username": ""
},
{
"name": "GvS",
"github_login": "GvS666",
"twitter_username": ""
},
{
"name": "David Păcioianu",
"github_login": "DavidPacioianu",
"twitter_username": ""
},
{
"name": "farwill",
"github_login": "farwill",
"twitter_username": ""
},
{
"name": "quroom",
"github_login": "quroom",
"twitter_username": ""
} }
] ]

View File

@ -33,7 +33,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit changes - name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5.0.0 uses: stefanzweifel/git-auto-commit-action@v5.0.1
with: with:
commit_message: Update Contributors commit_message: Update Contributors
file_pattern: CONTRIBUTORS.md .github/contributors.json file_pattern: CONTRIBUTORS.md .github/contributors.json

View File

@ -6,7 +6,7 @@ default_language_version:
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.6.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
@ -26,14 +26,14 @@ repos:
args: ["--tab-width", "2"] args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v3.15.1 rev: v3.15.2
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py312-plus] args: [--py312-plus]
exclude: hooks/ exclude: hooks/
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 24.3.0 rev: 24.4.0
hooks: hooks:
- id: black - id: black

View File

@ -3,6 +3,203 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
<!-- GENERATOR_PLACEHOLDER --> <!-- GENERATOR_PLACEHOLDER -->
## 2024.04.23
### Changed
- Update link to djlint on pyproject.toml ([#5019](https://github.com/cookiecutter/cookiecutter-django/pull/5019))
### Updated
- Update redis to 5.0.4 ([#5018](https://github.com/cookiecutter/cookiecutter-django/pull/5018))
- Update django-allauth to 0.62.0 ([#5016](https://github.com/cookiecutter/cookiecutter-django/pull/5016))
## 2024.04.22
### Fixed
- Fix broken link for sphinx-doc in generated docs ([#5015](https://github.com/cookiecutter/cookiecutter-django/pull/5015))
## 2024.04.20
### Updated
- Auto-update pre-commit hooks ([#5014](https://github.com/cookiecutter/cookiecutter-django/pull/5014))
- Update pytest-xdist to 3.6.0 ([#5013](https://github.com/cookiecutter/cookiecutter-django/pull/5013))
## 2024.04.19
### Updated
- Update ruff to 0.4.1 ([#5011](https://github.com/cookiecutter/cookiecutter-django/pull/5011))
- Update ruff to 0.4.0 ([#5007](https://github.com/cookiecutter/cookiecutter-django/pull/5007))
- Auto-update pre-commit hooks ([#5008](https://github.com/cookiecutter/cookiecutter-django/pull/5008))
- Update sphinx to 7.3.7 ([#5010](https://github.com/cookiecutter/cookiecutter-django/pull/5010))
## 2024.04.18
### Updated
- Update celery to 5.4.0 ([#5005](https://github.com/cookiecutter/cookiecutter-django/pull/5005))
- Update sphinx to 7.3.6 ([#5004](https://github.com/cookiecutter/cookiecutter-django/pull/5004))
## 2024.04.17
### Updated
- Update sphinx to 7.3.5 ([#5003](https://github.com/cookiecutter/cookiecutter-django/pull/5003))
- Update gunicorn to 22.0.0 ([#5001](https://github.com/cookiecutter/cookiecutter-django/pull/5001))
- Update sphinx to 7.3.3 ([#5000](https://github.com/cookiecutter/cookiecutter-django/pull/5000))
## 2024.04.16
### Changed
- Add a prefix setting so that swagger tags are generated in a readable way ([#4975](https://github.com/cookiecutter/cookiecutter-django/pull/4975))
### Fixed
- Fix `runserver_plus` hot-reload when under Windows + Docker ([#4971](https://github.com/cookiecutter/cookiecutter-django/pull/4971))
### Documentation
- Update docs for `test_bare.sh` ([#4996](https://github.com/cookiecutter/cookiecutter-django/pull/4996))
### Updated
- Bump traefik from 2.11.0 to 2.11.2 ([#4993](https://github.com/cookiecutter/cookiecutter-django/pull/4993))
- Update sphinx-autobuild to 2024.4.16 ([#4999](https://github.com/cookiecutter/cookiecutter-django/pull/4999))
- Update sphinx-autobuild to 2024.4.13 ([#4991](https://github.com/cookiecutter/cookiecutter-django/pull/4991))
- Update sentry-sdk to 1.45.0 ([#4982](https://github.com/cookiecutter/cookiecutter-django/pull/4982))
- Update ruff to 0.3.7 ([#4989](https://github.com/cookiecutter/cookiecutter-django/pull/4989))
- Auto-update pre-commit hooks ([#4988](https://github.com/cookiecutter/cookiecutter-django/pull/4988))
## 2024.04.10
### Updated
- Bump python from 3.12.2 to 3.12.3 in docs ([#4979](https://github.com/cookiecutter/cookiecutter-django/pull/4979))
- Bump python from 3.12.2 to 3.12.3 in local ([#4981](https://github.com/cookiecutter/cookiecutter-django/pull/4981))
- Bump python from 3.12.2 to 3.12.3 in production ([#4980](https://github.com/cookiecutter/cookiecutter-django/pull/4980))
## 2024.04.09
### Documentation
- Fix start command for docs ([#4978](https://github.com/cookiecutter/cookiecutter-django/pull/4978))
## 2024.04.07
### Updated
- Auto-update pre-commit hooks ([#4974](https://github.com/cookiecutter/cookiecutter-django/pull/4974))
## 2024.04.06
### Fixed
- Fix syntax error in GitHub CI workflow ([#4972](https://github.com/cookiecutter/cookiecutter-django/pull/4972))
## 2024.04.05
### Updated
- Update django-webpack-loader to 3.1.0 ([#4965](https://github.com/cookiecutter/cookiecutter-django/pull/4965))
## 2024.04.03
### Changed
- Update GH actions to resolve deprecation warnings ([#4964](https://github.com/cookiecutter/cookiecutter-django/pull/4964))
### Updated
- Update sentry-sdk to 1.44.1 ([#4963](https://github.com/cookiecutter/cookiecutter-django/pull/4963))
## 2024.04.02
### Changed
- Change pytest import mode to importlib ([#4950](https://github.com/cookiecutter/cookiecutter-django/pull/4950))
- Use main over master for branch name in deployment-on-heroku instruction ([#4954](https://github.com/cookiecutter/cookiecutter-django/pull/4954))
- change obsolete docker image &#34;docker/compose:1.29.2&#34; to &#34;docker:25.0&#34; ([#4961](https://github.com/cookiecutter/cookiecutter-django/pull/4961))
### Updated
- Update sentry-sdk to 1.44.0 ([#4948](https://github.com/cookiecutter/cookiecutter-django/pull/4948))
- Update ruff to 0.3.5 ([#4955](https://github.com/cookiecutter/cookiecutter-django/pull/4955))
- Update gitpython to 3.1.43 ([#4951](https://github.com/cookiecutter/cookiecutter-django/pull/4951))
- Update pillow to 10.3.0 ([#4953](https://github.com/cookiecutter/cookiecutter-django/pull/4953))
- Update django-model-utils to 4.5.0 ([#4956](https://github.com/cookiecutter/cookiecutter-django/pull/4956))
- Update drf-spectacular to 0.27.2 ([#4957](https://github.com/cookiecutter/cookiecutter-django/pull/4957))
- Update werkzeug to 3.0.2 ([#4958](https://github.com/cookiecutter/cookiecutter-django/pull/4958))
- Auto-update pre-commit hooks ([#4959](https://github.com/cookiecutter/cookiecutter-django/pull/4959))
## 2024.03.29
### Documentation
- Add instruction for adding a django app ([#4944](https://github.com/cookiecutter/cookiecutter-django/pull/4944))
## 2024.03.27
### Updated
- Update pre-commit to 3.7.0 ([#4943](https://github.com/cookiecutter/cookiecutter-django/pull/4943))
- Update djangorestframework to 3.15.1 ([#4941](https://github.com/cookiecutter/cookiecutter-django/pull/4941))
- Update ruff to 0.3.4 ([#4936](https://github.com/cookiecutter/cookiecutter-django/pull/4936))
- Auto-update pre-commit hooks ([#4937](https://github.com/cookiecutter/cookiecutter-django/pull/4937))
## 2024.03.26
### Documentation
- Update mentions of psycopg in comments ([#4947](https://github.com/cookiecutter/cookiecutter-django/pull/4947))
## 2024.03.21 ## 2024.03.21

View File

@ -66,13 +66,13 @@ $ source venv/bin/activate
These tests are slower and can be run with or without Docker: These tests are slower and can be run with or without Docker:
- Without Docker: `scripts/test_bare.sh` (for bare metal) - Without Docker: `tests/test_bare.sh` (for bare metal)
- With Docker: `scripts/test_docker.sh` - With Docker: `tests/test_docker.sh`
All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example: All arguments to these scripts will be passed to the `cookiecutter` CLI, letting you set options, for example:
```bash ```bash
$ scripts/test_bare.sh use_celery=y $ tests/test_bare.sh use_celery=y
``` ```
## Submitting a pull request ## Submitting a pull request

View File

@ -656,6 +656,13 @@ Listed in alphabetical order.
</td> </td>
<td>DavidDiazPinto</td> <td>DavidDiazPinto</td>
</tr> </tr>
<tr>
<td>David Păcioianu</td>
<td>
<a href="https://github.com/DavidPacioianu">DavidPacioianu</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Davit Tovmasyan</td> <td>Davit Tovmasyan</td>
<td> <td>
@ -810,6 +817,13 @@ Listed in alphabetical order.
</td> </td>
<td>fabaff</td> <td>fabaff</td>
</tr> </tr>
<tr>
<td>farwill</td>
<td>
<a href="https://github.com/farwill">farwill</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Fateme Fouladkar</td> <td>Fateme Fouladkar</td>
<td> <td>
@ -915,6 +929,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>GvS</td>
<td>
<a href="https://github.com/GvS666">GvS666</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Hamish Durkin</td> <td>Hamish Durkin</td>
<td> <td>
@ -1664,6 +1685,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>Patrick Zhang</td>
<td>
<a href="https://github.com/PatDuJour">PatDuJour</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Paul Wulff</td> <td>Paul Wulff</td>
<td> <td>
@ -1727,6 +1755,13 @@ Listed in alphabetical order.
</td> </td>
<td></td> <td></td>
</tr> </tr>
<tr>
<td>quroom</td>
<td>
<a href="https://github.com/quroom">quroom</a>
</td>
<td></td>
</tr>
<tr> <tr>
<td>Raony Guimarães Corrêa</td> <td>Raony Guimarães Corrêa</td>
<td> <td>
@ -2177,4 +2212,4 @@ guidance and advice.
- Jannis Leidel - Jannis Leidel
- Nate Aune - Nate Aune
- Barry Morrison - Barry Morrison

View File

@ -6,7 +6,7 @@
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![Updates](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/shield.svg)](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/) [![Updates](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/shield.svg)](https://pyup.io/repos/github/cookiecutter/cookiecutter-django/)
[![Join our Discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/uFXweDQc5a) [![Join our Discord](https://img.shields.io/badge/Discord-cookiecutter-5865F2?style=flat&logo=discord&logoColor=white)](https://discord.gg/rAWFUP47d2)
[![Code Helpers Badge](https://www.codetriage.com/cookiecutter/cookiecutter-django/badges/users.svg)](https://www.codetriage.com/cookiecutter/cookiecutter-django) [![Code Helpers Badge](https://www.codetriage.com/cookiecutter/cookiecutter-django/badges/users.svg)](https://www.codetriage.com/cookiecutter/cookiecutter-django)
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

View File

@ -46,7 +46,7 @@ Run these commands to deploy the project to Heroku:
# Assign with AWS_STORAGE_BUCKET_NAME # Assign with AWS_STORAGE_BUCKET_NAME
heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME= heroku config:set DJANGO_AWS_STORAGE_BUCKET_NAME=
git push heroku master git push heroku main
heroku run python manage.py createsuperuser heroku run python manage.py createsuperuser

View File

@ -96,6 +96,61 @@ First things first.
.. _direnv: https://direnv.net/ .. _direnv: https://direnv.net/
Creating Your First Django App
-------------------------------
After setting up your environment, you're ready to add your first app. This project uses the setup from "Two Scoops of Django" with a two-tier layout:
- **Top Level Repository Root** has config files, documentation, `manage.py`, and more.
- **Second Level Django Project Root** is where your Django apps live.
- **Second Level Configuration Root** holds settings and URL configurations.
The project layout looks something like this: ::
<repository_root>/
├── config/
│ ├── settings/
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── local.py
│ │ └── production.py
│ ├── urls.py
│ └── wsgi.py
├── <django_project_root>/
│ ├── <name_of_the_app>/
│ │ ├── migrations/
│ │ ├── admin.py
│ │ ├── apps.py
│ │ ├── models.py
│ │ ├── tests.py
│ │ └── views.py
│ ├── __init__.py
│ └── ...
├── requirements/
│ ├── base.txt
│ ├── local.txt
│ └── production.txt
├── manage.py
├── README.md
└── ...
Following this structured approach, here's how to add a new app:
#. **Create the app** using Django's ``startapp`` command, replacing ``<name-of-the-app>`` with your desired app name: ::
$ python manage.py startapp <name-of-the-app>
#. **Move the app** to the Django Project Root, maintaining the project's two-tier structure: ::
$ mv <name-of-the-app> <django_project_root>/
#. **Edit the app's apps.py** change ``name = '<name-of-the-app>'`` to ``name = '<django_project_root>.<name-of-the-app>'``.
#. **Register the new app** by adding it to the ``LOCAL_APPS`` list in ``config/settings/base.py``, integrating it as an official component of your project.
Setup Email Backend Setup Email Backend
------------------- -------------------

View File

@ -11,7 +11,7 @@ After you have set up to `develop locally`_, run the following command from the
If you set up your project to `develop locally with docker`_, run the following command: :: If you set up your project to `develop locally with docker`_, run the following command: ::
$ docker compose -f local.yml up docs $ docker compose -f docs.yml up
Navigate to port 9000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development. Navigate to port 9000 on your host to see the documentation. This will be opened automatically at `localhost`_ for local, non-docker development.

View File

@ -1,3 +1,3 @@
sphinx==7.2.6 sphinx==7.3.7
sphinx-rtd-theme==2.0.0 sphinx-rtd-theme==2.0.0
myst-parser==2.0.0 myst-parser==3.0.0

View File

@ -4,23 +4,23 @@ binaryornot==0.4.4
# Code quality # Code quality
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ruff==0.3.3 ruff==0.4.1
django-upgrade==1.16.0 django-upgrade==1.16.0
djlint==1.34.1 djlint==1.34.1
pre-commit==3.6.2 pre-commit==3.7.0
# Testing # Testing
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
tox==4.14.1 tox==4.14.2
pytest==8.1.1 pytest==8.1.1
pytest-xdist==3.5.0 pytest-xdist==3.6.0
pytest-cookies==0.7.0 pytest-cookies==0.7.0
pytest-instafail==0.5.0 pytest-instafail==0.5.0
pyyaml==6.0.1 pyyaml==6.0.1
# Scripting # Scripting
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
PyGithub==2.2.0 PyGithub==2.3.0
gitpython==3.1.42 gitpython==3.1.43
jinja2==3.1.3 jinja2==3.1.3
requests==2.31.0 requests==2.31.0

View File

@ -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 = "2024.03.21" version = "2024.04.23"
with open("README.md") as readme_file: with open("README.md") as readme_file:
long_description = readme_file.read() long_description = readme_file.read()

View File

@ -27,7 +27,7 @@ steps:
- name: test - name: test
pull: if-not-exists pull: if-not-exists
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
image: docker/compose:1.29.2 image: docker:25.0
environment: environment:
DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
commands: commands:

View File

@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v5
with: with:
python-version: '3.12' python-version: '3.12'
@ -34,7 +34,7 @@ jobs:
# Consider using pre-commit.ci for open source project # Consider using pre-commit.ci for open source project
{%- endif %} {%- endif %}
- name: Run pre-commit - name: Run pre-commit
uses: pre-commit/action@v3.0.0 uses: pre-commit/action@v3.0.1
# With no caching at all the entire ci process takes 3m to complete! # With no caching at all the entire ci process takes 3m to complete!
pytest: pytest:
@ -70,7 +70,9 @@ jobs:
- name: Build the Stack - name: Build the Stack
run: docker compose -f local.yml build django run: docker compose -f local.yml build django
run: docker compose -f local.yml build docs
- name: Build the docs
run: docker compose -f docs.yml build docs
- name: Run DB Migrations - name: Run DB Migrations
run: docker compose -f local.yml run --rm django python manage.py migrate run: docker compose -f local.yml run --rm django python manage.py migrate

View File

@ -27,7 +27,7 @@ precommit:
pytest: pytest:
stage: test stage: test
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
image: docker/compose:1.29.2 image: docker:25.0
tags: tags:
- docker - docker
services: services:

View File

@ -6,7 +6,7 @@ default_language_version:
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0 rev: v4.6.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
- id: end-of-file-fixer - id: end-of-file-fixer
@ -39,7 +39,7 @@ repos:
# Run the Ruff linter. # Run the Ruff linter.
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.3 rev: v0.4.1
hooks: hooks:
# Linter # Linter
- id: ruff - id: ruff
@ -52,10 +52,10 @@ repos:
hooks: hooks:
- id: djlint-reformat-django - id: djlint-reformat-django
files: "templates" files: "templates"
exclude: r'gto_supply/static/.*' exclude: r'{{cookiecutter.project_slug}}/static/.*'
- id: djlint-django - id: djlint-django
files: "templates" files: "templates"
exclude: r'gto_supply/static/.*' exclude: r'{{cookiecutter.project_slug}}/static/.*'
# 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:

View File

@ -1,5 +1,5 @@
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.12.2-slim-bookworm as python FROM docker.io/python:3.12.3-slim-bookworm as python
# Python build stage # Python build stage
FROM python as python-build-stage FROM python as python-build-stage
@ -10,7 +10,7 @@ ARG BUILD_ENVIRONMENT=local
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev libpq-dev
# Requirements are installed here to ensure they will be cached. # Requirements are installed here to ensure they will be cached.
@ -47,7 +47,7 @@ RUN groupadd --gid 1000 dev-user \
# 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 # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -1,5 +1,5 @@
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.12.2-slim-bookworm as python FROM docker.io/python:3.12.3-slim-bookworm as python
# Python build stage # Python build stage
@ -10,7 +10,7 @@ ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# cleaning up unused files # cleaning up unused files
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \
@ -35,7 +35,7 @@ ENV PYTHONDONTWRITEBYTECODE 1
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# To run the Makefile # To run the Makefile
make \ make \
# psycopg2 dependencies # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -25,7 +25,7 @@ RUN npm run build
{%- endif %} {%- endif %}
# define an alias for the specific python version used in this file. # define an alias for the specific python version used in this file.
FROM docker.io/python:3.12.2-slim-bookworm as python FROM docker.io/python:3.12.3-slim-bookworm as python
# Python build stage # Python build stage
FROM python as python-build-stage FROM python as python-build-stage
@ -36,7 +36,7 @@ ARG BUILD_ENVIRONMENT=production
RUN apt-get update && apt-get install --no-install-recommends -y \ RUN apt-get update && apt-get install --no-install-recommends -y \
# dependencies for building Python packages # dependencies for building Python packages
build-essential \ build-essential \
# psycopg2 dependencies # psycopg dependencies
libpq-dev libpq-dev
# Requirements are installed here to ensure they will be cached. # Requirements are installed here to ensure they will be cached.
@ -65,7 +65,7 @@ RUN addgroup --system django \
# 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 # psycopg dependencies
libpq-dev \ libpq-dev \
# Translations dependencies # Translations dependencies
gettext \ gettext \

View File

@ -1,4 +1,4 @@
FROM docker.io/traefik:2.11.0 FROM docker.io/traefik:2.11.2
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

View File

@ -378,6 +378,7 @@ SPECTACULAR_SETTINGS = {
"DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}", "DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}",
"VERSION": "1.0.0", "VERSION": "1.0.0",
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"], "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"],
"SCHEMA_PATH_PREFIX": "/api/",
} }
{%- endif %} {%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %}

View File

@ -56,34 +56,43 @@ EMAIL_BACKEND = env(
INSTALLED_APPS = ["whitenoise.runserver_nostatic", *INSTALLED_APPS] INSTALLED_APPS = ["whitenoise.runserver_nostatic", *INSTALLED_APPS]
{% 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"]
# # 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"]
# # 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"],
# "SHOW_TEMPLATE_CONTEXT": True, "SHOW_TEMPLATE_CONTEXT": True,
# } }
# # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips
# INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"]
# {% if cookiecutter.use_docker == 'y' -%} {% if cookiecutter.use_docker == 'y' -%}
# if env("USE_DOCKER") == "yes": if env("USE_DOCKER") == "yes":
# import socket import socket
#
# 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 in ['Gulp', 'Webpack'] %} {%- 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)
# except socket.gaierror: except socket.gaierror:
# # The node container isn't started (yet?) # The node container isn't started (yet?)
# pass pass
# {%- endif %} {%- endif %}
# {%- endif %} {%- if cookiecutter.windows == 'y' %}
# RunServerPlus
# ------------------------------------------------------------------------------
# This is a custom setting for RunServerPlus to fix reloader issue in Windows docker environment
# Werkzeug reloader type [auto, watchdog, or stat]
RUNSERVERPLUS_POLLER_RELOADER_TYPE = 'stat'
# If you have CPU and IO load issues, you can increase this poller interval e.g) 5
RUNSERVERPLUS_POLLER_RELOADER_INTERVAL = 1
{%- endif %}
{%- endif %}
# django-extensions # django-extensions
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -43,7 +43,7 @@ urlpatterns += [
# API base url # API base url
path("api/", include("config.api_router")), path("api/", include("config.api_router")),
# DRF auth token # DRF auth token
path("auth-token/", obtain_auth_token), path("api/auth-token/", obtain_auth_token),
path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"), path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
path( path(
"api/docs/", "api/docs/",

View File

@ -26,7 +26,7 @@ Changes to files in `docs/_source` will be picked up and reloaded automatically.
Docstrings to Documentation Docstrings to Documentation
---------------------------------------------------------------------- ----------------------------------------------------------------------
The sphinx extension `apidoc <https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html/>`_ is used to automatically document code using signatures and docstrings. The sphinx extension `apidoc <https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html>`_ is used to automatically document code using signatures and docstrings.
Numpy or Google style docstrings will be picked up from project files and available for documentation. See the `Napoleon <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/>`_ extension for details. Numpy or Google style docstrings will be picked up from project files and available for documentation. See the `Napoleon <https://sphinxcontrib-napoleon.readthedocs.io/en/latest/>`_ extension for details.

View File

@ -1,7 +1,7 @@
# ==== pytest ==== # ==== pytest ====
[tool.pytest.ini_options] [tool.pytest.ini_options]
minversion = "6.0" minversion = "6.0"
addopts = "--ds=config.settings.test --reuse-db" addopts = "--ds=config.settings.test --reuse-db --import-mode=importlib"
python_files = [ python_files = [
"tests.py", "tests.py",
"test_*.py", "test_*.py",
@ -45,7 +45,7 @@ blank_line_after_tag = "load,extends,endblock"
close_void_tags = true close_void_tags = true
format_css = false format_css = false
format_js = false format_js = false
# TODO: remove T002 when fixed https://github.com/Riverside-Healthcare/djLint/issues/687 # TODO: remove T002 when fixed https://github.com/djlint/djLint/issues/687
ignore = "H006,H030,H031,T002,H020,H023,H033,D018" ignore = "H006,H030,H031,T002,H020,H023,H033,D018"
include = "H017,H035" include = "H017,H035"
indent = 2 indent = 2
@ -150,11 +150,20 @@ select = [
ignore = [ ignore = [
"S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/ "S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
"SIM102" # sometimes it's better to nest "SIM102", # sometimes it's better to nest
"UP038" # Checks for uses of isinstance/issubclass that take a tuple
# of types for comparison.
# Deactivated because it can make the code slow:
# https://github.com/astral-sh/ruff/issues/7871
] ]
# Allow fix for all enabled rules (when `--fix`) is provided. # Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"] fixable = ["ALL"]
unfixable = [] unfixable = []
# The fixes in extend-unsafe-fixes will require
# provide the `--unsafe-fixes` flag when fixing.
extend-unsafe-fixes = [
"UP038"
]
# Allow unused variables when underscore-prefixed. # Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

View File

@ -1,5 +1,5 @@
python-slugify==8.0.4 # https://github.com/un33k/python-slugify python-slugify==8.0.4 # https://github.com/un33k/python-slugify
Pillow==10.2.0 # https://github.com/python-pillow/Pillow Pillow==10.3.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
@ -11,12 +11,12 @@ argon2-cffi==23.1.0 # https://github.com/hynek/argon2_cffi
{%- if cookiecutter.use_whitenoise == 'y' %} {%- if cookiecutter.use_whitenoise == 'y' %}
whitenoise==6.6.0 # https://github.com/evansd/whitenoise whitenoise==6.6.0 # https://github.com/evansd/whitenoise
{%- endif %} {%- endif %}
redis==5.0.3 # https://github.com/redis/redis-py redis==5.0.4 # 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.3.2 # https://github.com/redis/hiredis-py hiredis==2.3.2 # https://github.com/redis/hiredis-py
{%- endif %} {%- endif %}
{%- if cookiecutter.use_celery == "y" %} {%- if cookiecutter.use_celery == "y" %}
celery==5.3.6 # pyup: < 6.0 # https://github.com/celery/celery celery==5.4.0 # pyup: < 6.0 # https://github.com/celery/celery
django-celery-beat==2.6.0 # https://github.com/celery/django-celery-beat django-celery-beat==2.6.0 # https://github.com/celery/django-celery-beat
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
flower==2.0.1 # https://github.com/mher/flower flower==2.0.1 # https://github.com/mher/flower
@ -30,8 +30,8 @@ uvicorn[standard]==0.29.0 # https://github.com/encode/uvicorn
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
django==4.2.11 # pyup: < 5.0 # https://www.djangoproject.com/ django==4.2.11 # pyup: < 5.0 # https://www.djangoproject.com/
django-environ==0.11.2 # https://github.com/joke2k/django-environ django-environ==0.11.2 # https://github.com/joke2k/django-environ
django-model-utils==4.4.0 # https://github.com/jazzband/django-model-utils django-model-utils==4.5.0 # https://github.com/jazzband/django-model-utils
django-allauth[mfa]==0.61.1 # https://github.com/pennersr/django-allauth django-allauth[mfa]==0.62.1 # https://github.com/pennersr/django-allauth
django-crispy-forms==2.1 # https://github.com/django-crispy-forms/django-crispy-forms django-crispy-forms==2.1 # https://github.com/django-crispy-forms/django-crispy-forms
crispy-bootstrap5==2024.2 # https://github.com/django-crispy-forms/crispy-bootstrap5 crispy-bootstrap5==2024.2 # https://github.com/django-crispy-forms/crispy-bootstrap5
{%- if cookiecutter.frontend_pipeline == 'Django Compressor' %} {%- if cookiecutter.frontend_pipeline == 'Django Compressor' %}
@ -40,13 +40,13 @@ django-compressor==4.4 # https://github.com/django-compressor/django-compressor
django-redis==5.4.0 # https://github.com/jazzband/django-redis django-redis==5.4.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.15.0 # https://github.com/encode/django-rest-framework djangorestframework==3.15.1 # https://github.com/encode/django-rest-framework
django-cors-headers==4.3.1 # https://github.com/adamchainz/django-cors-headers django-cors-headers==4.3.1 # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation # DRF-spectacular for api documentation
drf-spectacular==0.27.1 # https://github.com/tfranzel/drf-spectacular drf-spectacular==0.27.2 # https://github.com/tfranzel/drf-spectacular
{%- endif %} {%- endif %}
{%- if cookiecutter.frontend_pipeline == 'Webpack' %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %}
django-webpack-loader==3.0.1 # https://github.com/django-webpack/django-webpack-loader django-webpack-loader==3.1.0 # https://github.com/django-webpack/django-webpack-loader
{%- endif %} {%- endif %}
# Project # Project

View File

@ -1,6 +1,6 @@
-r production.txt -r production.txt
Werkzeug[watchdog]==3.0.1 # https://github.com/pallets/werkzeug Werkzeug[watchdog]==3.0.2 # https://github.com/pallets/werkzeug
ipdb==0.13.13 # https://github.com/gotcha/ipdb ipdb==0.13.13 # https://github.com/gotcha/ipdb
{%- if cookiecutter.use_docker == 'y' %} {%- if cookiecutter.use_docker == 'y' %}
psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg
@ -23,16 +23,16 @@ djangorestframework-stubs[compatible-mypy]==3.14.5 # https://github.com/typeddj
# Documentation # Documentation
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
sphinx==7.2.6 # https://github.com/sphinx-doc/sphinx sphinx==7.3.7 # https://github.com/sphinx-doc/sphinx
sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild sphinx-autobuild==2024.4.16 # https://github.com/GaretJax/sphinx-autobuild
sphinx-rtd-theme==2.0.0 # https://pypi.org/project/sphinx-rtd-theme/ sphinx-rtd-theme==2.0.0 # https://pypi.org/project/sphinx-rtd-theme/
# Code quality # Code quality
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
ruff==0.3.3 # https://github.com/astral-sh/ruff ruff==0.4.1 # https://github.com/astral-sh/ruff
coverage==7.4.4 # https://github.com/nedbat/coveragepy coverage==7.4.4 # https://github.com/nedbat/coveragepy
djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint
pre-commit==3.6.2 # https://github.com/pre-commit/pre-commit pre-commit==3.7.0 # https://github.com/pre-commit/pre-commit
# Django # Django
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -2,13 +2,13 @@
-r base.txt -r base.txt
gunicorn==21.2.0 # https://github.com/benoitc/gunicorn gunicorn==22.0.0 # https://github.com/benoitc/gunicorn
psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg psycopg[c]==3.1.18 # https://github.com/psycopg/psycopg
{%- if cookiecutter.use_whitenoise == 'n' %} {%- if cookiecutter.use_whitenoise == 'n' %}
Collectfast==2.2.0 # https://github.com/antonagestam/collectfast Collectfast==2.2.0 # https://github.com/antonagestam/collectfast
{%- endif %} {%- endif %}
{%- if cookiecutter.use_sentry == "y" %} {%- if cookiecutter.use_sentry == "y" %}
sentry-sdk==1.43.0 # https://github.com/getsentry/sentry-python sentry-sdk==1.45.0 # https://github.com/getsentry/sentry-python
{%- endif %} {%- endif %}
{%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %}
hiredis==2.3.2 # https://github.com/redis/hiredis-py hiredis==2.3.2 # https://github.com/redis/hiredis-py

View File

@ -1 +1 @@
python-3.12.2 python-3.12.3

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -9,7 +9,7 @@ python3-dev
##Pillow, pylibmc ##Pillow, pylibmc
zlib1g-dev zlib1g-dev
##Postgresql and psycopg2 dependencies ##Postgresql and psycopg dependencies
libpq-dev libpq-dev
##Pillow dependencies ##Pillow dependencies

View File

@ -30,6 +30,8 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter):
) -> bool: ) -> bool:
return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True)
def pre_social_login(self, request, sociallogin): def pre_social_login(self, request, sociallogin):
# social account already exists, so this is just a login # social account already exists, so this is just a login
if sociallogin.is_existing: if sociallogin.is_existing:

View File

@ -8,10 +8,10 @@ from rest_framework.mixins import UpdateModelMixin
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet from rest_framework.viewsets import GenericViewSet
from {{ cookiecutter.project_slug }}.users.models import User
from .serializers import UserSerializer from .serializers import UserSerializer
User = get_user_model()
class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet): class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
serializer_class = UserSerializer serializer_class = UserSerializer

View File

@ -27,6 +27,11 @@ class UserAdminCreationForm(admin_forms.UserCreationForm):
error_messages = { error_messages = {
"email": {"unique": _("This email has already been taken.")} "email": {"unique": _("This email has already been taken.")}
} }
{%- else %}
error_messages = {
"username": {"unique": _("This username has already been taken.")},
}
{%- endif %}
class UserSignupForm(SignupForm): class UserSignupForm(SignupForm):

View File

@ -1,8 +1,9 @@
import django.contrib.auth.models import django.contrib.auth.models
import django.contrib.auth.validators import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone import django.utils.timezone
import uuid import uuid
from django.db import migrations
from django.db import models
import {{cookiecutter.project_slug}}.users.models import {{cookiecutter.project_slug}}.users.models

View File

@ -1,5 +1,7 @@
import uuid as uuid_lib import uuid as uuid_lib
from typing import ClassVar
from django.contrib.auth.base_user import BaseUserManager from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
@ -31,7 +33,7 @@ class User(AbstractUser):
"last_name", "last_name",
] ]
objects = UserManager() objects: ClassVar[UserManager] = UserManager()
def get_absolute_url(self) -> str: def get_absolute_url(self) -> str:
"""Get URL for user's detail view. """Get URL for user's detail view.

View File

@ -2,14 +2,17 @@ from collections.abc import Sequence
from typing import Any from typing import Any
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from factory import Faker, post_generation from factory import Faker
from factory import post_generation
from factory.django import DjangoModelFactory from factory.django import DjangoModelFactory
class UserFactory(DjangoModelFactory): class UserFactory(DjangoModelFactory):
{%- if cookiecutter.username_type == "username" %}
username = Faker("user_name")
{%- endif %}
email = Faker("email") email = Faker("email")
first_name = Faker("name") name = Faker("name")
last_name = Faker("name")
@post_generation @post_generation
def password(self, create: bool, extracted: Sequence[Any], **kwargs): # noqa: FBT001 def password(self, create: bool, extracted: Sequence[Any], **kwargs): # noqa: FBT001