diff --git a/.github/contributors.json b/.github/contributors.json index b47a56246..5c9885eea 100644 --- a/.github/contributors.json +++ b/.github/contributors.json @@ -1538,5 +1538,30 @@ "name": "Simeon Emanuilov", "github_login": "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": "" } -] \ No newline at end of file +] diff --git a/.github/workflows/update-contributors.yml b/.github/workflows/update-contributors.yml index e814039db..c77bc5e8f 100644 --- a/.github/workflows/update-contributors.yml +++ b/.github/workflows/update-contributors.yml @@ -33,7 +33,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v5.0.0 + uses: stefanzweifel/git-auto-commit-action@v5.0.1 with: commit_message: Update Contributors file_pattern: CONTRIBUTORS.md .github/contributors.json diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20d2f9c9f..97cad833b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -26,14 +26,14 @@ repos: args: ["--tab-width", "2"] - repo: https://github.com/asottile/pyupgrade - rev: v3.15.1 + rev: v3.15.2 hooks: - id: pyupgrade args: [--py312-plus] exclude: hooks/ - repo: https://github.com/psf/black - rev: 24.3.0 + rev: 24.4.0 hooks: - id: black diff --git a/CHANGELOG.md b/CHANGELOG.md index e70117ffe..383db8d98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,203 @@ All enhancements and patches to Cookiecutter Django will be documented in this f +## 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 "docker/compose:1.29.2" to "docker:25.0" ([#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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 753e827aa..8d2025e37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -66,13 +66,13 @@ $ 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` +- Without Docker: `tests/test_bare.sh` (for bare metal) +- With Docker: `tests/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 +$ tests/test_bare.sh use_celery=y ``` ## Submitting a pull request diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c14c0ea3b..8e454a737 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -656,6 +656,13 @@ Listed in alphabetical order. DavidDiazPinto + + David Păcioianu + + DavidPacioianu + + + Davit Tovmasyan @@ -810,6 +817,13 @@ Listed in alphabetical order. fabaff + + farwill + + farwill + + + Fateme Fouladkar @@ -915,6 +929,13 @@ Listed in alphabetical order. + + GvS + + GvS666 + + + Hamish Durkin @@ -1664,6 +1685,13 @@ Listed in alphabetical order. + + Patrick Zhang + + PatDuJour + + + Paul Wulff @@ -1727,6 +1755,13 @@ Listed in alphabetical order. + + quroom + + quroom + + + Raony Guimarães Corrêa @@ -2177,4 +2212,4 @@ guidance and advice. - Jannis Leidel - Nate Aune -- Barry Morrison \ No newline at end of file +- Barry Morrison diff --git a/README.md b/README.md index a4e2e10f8..aa7ee88d6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![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/) -[![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) Powered by [Cookiecutter](https://github.com/cookiecutter/cookiecutter), Cookiecutter Django is a framework for jumpstarting diff --git a/docs/deployment-on-heroku.rst b/docs/deployment-on-heroku.rst index 71c6e11b2..fdd953e09 100644 --- a/docs/deployment-on-heroku.rst +++ b/docs/deployment-on-heroku.rst @@ -46,7 +46,7 @@ Run these commands to deploy the project to Heroku: # Assign with 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 diff --git a/docs/developing-locally.rst b/docs/developing-locally.rst index f7191d27d..16247d082 100644 --- a/docs/developing-locally.rst +++ b/docs/developing-locally.rst @@ -96,6 +96,61 @@ First things first. .. _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: :: + + / + ├── config/ + │ ├── settings/ + │ │ ├── __init__.py + │ │ ├── base.py + │ │ ├── local.py + │ │ └── production.py + │ ├── urls.py + │ └── wsgi.py + ├── / + │ ├── / + │ │ ├── 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 ```` with your desired app name: :: + + $ python manage.py startapp + +#. **Move the app** to the Django Project Root, maintaining the project's two-tier structure: :: + + $ mv / + +#. **Edit the app's apps.py** change ``name = ''`` to ``name = '.'``. + +#. **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 ------------------- diff --git a/docs/document.rst b/docs/document.rst index 26f5d56a1..f93f2b60e 100644 --- a/docs/document.rst +++ b/docs/document.rst @@ -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: :: - $ 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. diff --git a/docs/requirements.txt b/docs/requirements.txt index d002affa7..f84dbf045 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ -sphinx==7.2.6 +sphinx==7.3.7 sphinx-rtd-theme==2.0.0 -myst-parser==2.0.0 +myst-parser==3.0.0 diff --git a/requirements.txt b/requirements.txt index 48cacacc9..87a86fd70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,23 +4,23 @@ binaryornot==0.4.4 # Code quality # ------------------------------------------------------------------------------ -ruff==0.3.3 +ruff==0.4.1 django-upgrade==1.16.0 djlint==1.34.1 -pre-commit==3.6.2 +pre-commit==3.7.0 # Testing # ------------------------------------------------------------------------------ -tox==4.14.1 +tox==4.14.2 pytest==8.1.1 -pytest-xdist==3.5.0 +pytest-xdist==3.6.0 pytest-cookies==0.7.0 pytest-instafail==0.5.0 pyyaml==6.0.1 # Scripting # ------------------------------------------------------------------------------ -PyGithub==2.2.0 -gitpython==3.1.42 +PyGithub==2.3.0 +gitpython==3.1.43 jinja2==3.1.3 requests==2.31.0 diff --git a/setup.py b/setup.py index f6e6a0999..5d8ad95c5 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ except ImportError: from distutils.core import setup # We use calendar versioning -version = "2024.03.21" +version = "2024.04.23" with open("README.md") as readme_file: long_description = readme_file.read() diff --git a/{{cookiecutter.project_slug}}/.drone.yml b/{{cookiecutter.project_slug}}/.drone.yml index 2753fa4e0..829ead2ca 100644 --- a/{{cookiecutter.project_slug}}/.drone.yml +++ b/{{cookiecutter.project_slug}}/.drone.yml @@ -27,7 +27,7 @@ steps: - name: test pull: if-not-exists {%- if cookiecutter.use_docker == 'y' %} - image: docker/compose:1.29.2 + image: docker:25.0 environment: DATABASE_URL: pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB commands: diff --git a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml index 4e24af5a9..4e6ec1cd2 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/ci.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.12' @@ -34,7 +34,7 @@ jobs: # Consider using pre-commit.ci for open source project {%- endif %} - 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! pytest: @@ -70,7 +70,9 @@ jobs: - name: Build the Stack 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 run: docker compose -f local.yml run --rm django python manage.py migrate diff --git a/{{cookiecutter.project_slug}}/.gitlab-ci.yml b/{{cookiecutter.project_slug}}/.gitlab-ci.yml index df823db1f..75c03e876 100644 --- a/{{cookiecutter.project_slug}}/.gitlab-ci.yml +++ b/{{cookiecutter.project_slug}}/.gitlab-ci.yml @@ -27,7 +27,7 @@ precommit: pytest: stage: test {%- if cookiecutter.use_docker == 'y' %} - image: docker/compose:1.29.2 + image: docker:25.0 tags: - docker services: diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml index 5a7bdac52..510578f4d 100644 --- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml +++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml @@ -6,7 +6,7 @@ default_language_version: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -39,7 +39,7 @@ repos: # Run the Ruff linter. - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.3 + rev: v0.4.1 hooks: # Linter - id: ruff @@ -52,10 +52,10 @@ repos: hooks: - id: djlint-reformat-django files: "templates" - exclude: r'gto_supply/static/.*' + exclude: r'{{cookiecutter.project_slug}}/static/.*' - id: djlint-django 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 ci: diff --git a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile index d607550a3..88ccb7491 100644 --- a/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/django/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM docker.io/python:3.12.2-slim-bookworm as python +FROM docker.io/python:3.12.3-slim-bookworm as python # 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 \ # dependencies for building Python packages build-essential \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev # Requirements are installed here to ensure they will be cached. @@ -47,7 +47,7 @@ RUN groupadd --gid 1000 dev-user \ # Install required system dependencies RUN apt-get update && apt-get install --no-install-recommends -y \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev \ # Translations dependencies gettext \ diff --git a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile index c95fa6663..35565042d 100644 --- a/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/local/docs/Dockerfile @@ -1,5 +1,5 @@ # define an alias for the specific python version used in this file. -FROM docker.io/python:3.12.2-slim-bookworm as python +FROM docker.io/python:3.12.3-slim-bookworm as python # Python build stage @@ -10,7 +10,7 @@ ENV PYTHONDONTWRITEBYTECODE 1 RUN apt-get update && apt-get install --no-install-recommends -y \ # dependencies for building Python packages build-essential \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev \ # cleaning up unused files && 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 \ # To run the Makefile make \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev \ # Translations dependencies gettext \ diff --git a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile index ea4f1899d..671eb4635 100644 --- a/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/django/Dockerfile @@ -25,7 +25,7 @@ RUN npm run build {%- endif %} # define an alias for the specific python version used in this file. -FROM docker.io/python:3.12.2-slim-bookworm as python +FROM docker.io/python:3.12.3-slim-bookworm as python # 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 \ # dependencies for building Python packages build-essential \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev # Requirements are installed here to ensure they will be cached. @@ -65,7 +65,7 @@ RUN addgroup --system django \ # Install required system dependencies RUN apt-get update && apt-get install --no-install-recommends -y \ - # psycopg2 dependencies + # psycopg dependencies libpq-dev \ # Translations dependencies gettext \ diff --git a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile index ea918e911..d54bf27ca 100644 --- a/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile +++ b/{{cookiecutter.project_slug}}/compose/production/traefik/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/traefik:2.11.0 +FROM docker.io/traefik:2.11.2 RUN mkdir -p /etc/traefik/acme \ && touch /etc/traefik/acme/acme.json \ && chmod 600 /etc/traefik/acme/acme.json diff --git a/{{cookiecutter.project_slug}}/config/settings/base.py b/{{cookiecutter.project_slug}}/config/settings/base.py index ec98689dc..0cb095284 100644 --- a/{{cookiecutter.project_slug}}/config/settings/base.py +++ b/{{cookiecutter.project_slug}}/config/settings/base.py @@ -378,6 +378,7 @@ SPECTACULAR_SETTINGS = { "DESCRIPTION": "Documentation of API endpoints of {{ cookiecutter.project_name }}", "VERSION": "1.0.0", "SERVE_PERMISSIONS": ["rest_framework.permissions.IsAdminUser"], + "SCHEMA_PATH_PREFIX": "/api/", } {%- endif %} {%- if cookiecutter.frontend_pipeline == 'Webpack' %} diff --git a/{{cookiecutter.project_slug}}/config/settings/local.py b/{{cookiecutter.project_slug}}/config/settings/local.py index 475d985a5..ab526f968 100644 --- a/{{cookiecutter.project_slug}}/config/settings/local.py +++ b/{{cookiecutter.project_slug}}/config/settings/local.py @@ -56,34 +56,43 @@ EMAIL_BACKEND = env( INSTALLED_APPS = ["whitenoise.runserver_nostatic", *INSTALLED_APPS] {% endif %} -# # django-debug-toolbar -# # ------------------------------------------------------------------------------ -# # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites -# INSTALLED_APPS += ["debug_toolbar"] # noqa: F405 -# # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware -# MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] # noqa: F405 -# # https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config -# DEBUG_TOOLBAR_CONFIG = { -# "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], -# "SHOW_TEMPLATE_CONTEXT": True, -# } -# # https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips -# INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] -# {% if cookiecutter.use_docker == 'y' -%} -# if env("USE_DOCKER") == "yes": -# import socket -# -# hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) -# INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] -# {%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %} -# try: -# _, _, ips = socket.gethostbyname_ex("node") -# INTERNAL_IPS.extend(ips) -# except socket.gaierror: -# # The node container isn't started (yet?) -# pass -# {%- endif %} -# {%- endif %} +# django-debug-toolbar +# ------------------------------------------------------------------------------ +# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites +INSTALLED_APPS += ["debug_toolbar"] +# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#middleware +MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"] +# https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#debug-toolbar-config +DEBUG_TOOLBAR_CONFIG = { + "DISABLE_PANELS": ["debug_toolbar.panels.redirects.RedirectsPanel"], + "SHOW_TEMPLATE_CONTEXT": True, +} +# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#internal-ips +INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"] +{% if cookiecutter.use_docker == 'y' -%} +if env("USE_DOCKER") == "yes": + import socket + + hostname, _, ips = socket.gethostbyname_ex(socket.gethostname()) + INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips] + {%- if cookiecutter.frontend_pipeline in ['Gulp', 'Webpack'] %} + try: + _, _, ips = socket.gethostbyname_ex("node") + INTERNAL_IPS.extend(ips) + except socket.gaierror: + # The node container isn't started (yet?) + pass + {%- 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 # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/config/urls.py b/{{cookiecutter.project_slug}}/config/urls.py index 5d9301b67..aca4352e6 100644 --- a/{{cookiecutter.project_slug}}/config/urls.py +++ b/{{cookiecutter.project_slug}}/config/urls.py @@ -43,7 +43,7 @@ urlpatterns += [ # API base url path("api/", include("config.api_router")), # 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/docs/", diff --git a/{{cookiecutter.project_slug}}/docs/howto.rst b/{{cookiecutter.project_slug}}/docs/howto.rst index 7d86351cf..2d734ceb2 100644 --- a/{{cookiecutter.project_slug}}/docs/howto.rst +++ b/{{cookiecutter.project_slug}}/docs/howto.rst @@ -26,7 +26,7 @@ Changes to files in `docs/_source` will be picked up and reloaded automatically. Docstrings to Documentation ---------------------------------------------------------------------- -The sphinx extension `apidoc `_ is used to automatically document code using signatures and docstrings. +The sphinx extension `apidoc `_ 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 `_ extension for details. diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 4f4a49b95..4ee354865 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -1,7 +1,7 @@ # ==== pytest ==== [tool.pytest.ini_options] minversion = "6.0" -addopts = "--ds=config.settings.test --reuse-db" +addopts = "--ds=config.settings.test --reuse-db --import-mode=importlib" python_files = [ "tests.py", "test_*.py", @@ -45,7 +45,7 @@ blank_line_after_tag = "load,extends,endblock" close_void_tags = true format_css = 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" include = "H017,H035" indent = 2 @@ -150,11 +150,20 @@ select = [ ignore = [ "S101", # Use of assert detected https://docs.astral.sh/ruff/rules/assert/ "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. fixable = ["ALL"] 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. dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" diff --git a/{{cookiecutter.project_slug}}/requirements/base.txt b/{{cookiecutter.project_slug}}/requirements/base.txt index a20b782a9..92b26802b 100644 --- a/{{cookiecutter.project_slug}}/requirements/base.txt +++ b/{{cookiecutter.project_slug}}/requirements/base.txt @@ -1,5 +1,5 @@ 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.windows == 'y' and cookiecutter.use_docker == 'n' %} 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' %} whitenoise==6.6.0 # https://github.com/evansd/whitenoise {%- 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" %} hiredis==2.3.2 # https://github.com/redis/hiredis-py {%- endif %} {%- 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 {%- if cookiecutter.use_docker == 'y' %} 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-environ==0.11.2 # https://github.com/joke2k/django-environ -django-model-utils==4.4.0 # https://github.com/jazzband/django-model-utils -django-allauth[mfa]==0.61.1 # https://github.com/pennersr/django-allauth +django-model-utils==4.5.0 # https://github.com/jazzband/django-model-utils +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 crispy-bootstrap5==2024.2 # https://github.com/django-crispy-forms/crispy-bootstrap5 {%- 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 {%- if cookiecutter.use_drf == 'y' %} # 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 # 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 %} {%- 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 %} # Project diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt index e52cf10fa..ae01903e5 100644 --- a/{{cookiecutter.project_slug}}/requirements/local.txt +++ b/{{cookiecutter.project_slug}}/requirements/local.txt @@ -1,6 +1,6 @@ -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 {%- if cookiecutter.use_docker == 'y' %} 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 # ------------------------------------------------------------------------------ -sphinx==7.2.6 # https://github.com/sphinx-doc/sphinx -sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild +sphinx==7.3.7 # https://github.com/sphinx-doc/sphinx +sphinx-autobuild==2024.4.16 # https://github.com/GaretJax/sphinx-autobuild sphinx-rtd-theme==2.0.0 # https://pypi.org/project/sphinx-rtd-theme/ # 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 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 # ------------------------------------------------------------------------------ diff --git a/{{cookiecutter.project_slug}}/requirements/production.txt b/{{cookiecutter.project_slug}}/requirements/production.txt index e412bd0cc..29e23563e 100644 --- a/{{cookiecutter.project_slug}}/requirements/production.txt +++ b/{{cookiecutter.project_slug}}/requirements/production.txt @@ -2,13 +2,13 @@ -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 {%- if cookiecutter.use_whitenoise == 'n' %} Collectfast==2.2.0 # https://github.com/antonagestam/collectfast {%- endif %} {%- 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 %} {%- if cookiecutter.use_docker == "n" and cookiecutter.windows == "y" %} hiredis==2.3.2 # https://github.com/redis/hiredis-py diff --git a/{{cookiecutter.project_slug}}/runtime.txt b/{{cookiecutter.project_slug}}/runtime.txt index 6e797d468..4ddc7cd66 100644 --- a/{{cookiecutter.project_slug}}/runtime.txt +++ b/{{cookiecutter.project_slug}}/runtime.txt @@ -1 +1 @@ -python-3.12.2 +python-3.12.3 diff --git a/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt b/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt index 1ca82b264..0e1a6572c 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-bionic.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt b/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt index a4910eb6d..f24f6f3da 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-bookworm.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-bullseye.apt b/{{cookiecutter.project_slug}}/utility/requirements-bullseye.apt index 60f602873..e8e36b631 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-bullseye.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-bullseye.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-buster.apt b/{{cookiecutter.project_slug}}/utility/requirements-buster.apt index 75957f40d..f2c81962d 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-buster.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-buster.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-focal.apt b/{{cookiecutter.project_slug}}/utility/requirements-focal.apt index fe6f21e46..f400b4196 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-focal.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-focal.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt b/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt index 63d1587e6..ea52472a1 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-jammy.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-jessie.apt b/{{cookiecutter.project_slug}}/utility/requirements-jessie.apt index 5c49365ba..ebf0e583e 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-jessie.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-jessie.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-stretch.apt b/{{cookiecutter.project_slug}}/utility/requirements-stretch.apt index a2b3a7e5e..979eca313 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-stretch.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-stretch.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-trusty.apt b/{{cookiecutter.project_slug}}/utility/requirements-trusty.apt index 455f1a868..954f78375 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-trusty.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-trusty.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/utility/requirements-xenial.apt b/{{cookiecutter.project_slug}}/utility/requirements-xenial.apt index ba84ef167..1784e40c6 100644 --- a/{{cookiecutter.project_slug}}/utility/requirements-xenial.apt +++ b/{{cookiecutter.project_slug}}/utility/requirements-xenial.apt @@ -9,7 +9,7 @@ python3-dev ##Pillow, pylibmc zlib1g-dev -##Postgresql and psycopg2 dependencies +##Postgresql and psycopg dependencies libpq-dev ##Pillow dependencies diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py index 253a84933..371b1f935 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/adapters.py @@ -30,6 +30,8 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter): ) -> bool: return getattr(settings, "ACCOUNT_ALLOW_REGISTRATION", True) + + def pre_social_login(self, request, sociallogin): # social account already exists, so this is just a login if sociallogin.is_existing: diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py index 91b8ea69f..59a611673 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py @@ -8,10 +8,10 @@ from rest_framework.mixins import UpdateModelMixin from rest_framework.response import Response from rest_framework.viewsets import GenericViewSet -from {{ cookiecutter.project_slug }}.users.models import User - from .serializers import UserSerializer +User = get_user_model() + class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet): serializer_class = UserSerializer diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py index 71ddaaa74..0c572c895 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py @@ -27,6 +27,11 @@ class UserAdminCreationForm(admin_forms.UserCreationForm): error_messages = { "email": {"unique": _("This email has already been taken.")} } + {%- else %} + error_messages = { + "username": {"unique": _("This username has already been taken.")}, + } + {%- endif %} class UserSignupForm(SignupForm): diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py index f36e1316a..6a544021a 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/migrations/0001_initial.py @@ -1,8 +1,9 @@ import django.contrib.auth.models import django.contrib.auth.validators -from django.db import migrations, models import django.utils.timezone import uuid +from django.db import migrations +from django.db import models import {{cookiecutter.project_slug}}.users.models diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py index 500792a5e..f81d2446f 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/models.py @@ -1,5 +1,7 @@ import uuid as uuid_lib +from typing import ClassVar + from django.contrib.auth.base_user import BaseUserManager from django.contrib.auth.models import AbstractUser from django.db import models @@ -31,7 +33,7 @@ class User(AbstractUser): "last_name", ] - objects = UserManager() + objects: ClassVar[UserManager] = UserManager() def get_absolute_url(self) -> str: """Get URL for user's detail view. diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py index 019bffffb..785d80001 100644 --- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py +++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py @@ -2,14 +2,17 @@ from collections.abc import Sequence from typing import Any 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 class UserFactory(DjangoModelFactory): + {%- if cookiecutter.username_type == "username" %} + username = Faker("user_name") + {%- endif %} email = Faker("email") - first_name = Faker("name") - last_name = Faker("name") + name = Faker("name") @post_generation def password(self, create: bool, extracted: Sequence[Any], **kwargs): # noqa: FBT001