Repository: cookiecutter/cookiecutter-django

Issue:
Python 3.12
Abused the `create_django_issue.py` script to create a table for Python 3.12. 

There is a lot of work to do: 

## base.txt

| Name | Version in Master | 3.12 Compatible Version | OK|  Issue / PR |
| ---- | :---------------: | :-----------------------------: | :-: |:-:|
| [python-slugify](https://github.com/un33k/python-slugify) | 8.0.1 |  | ✅ |https://github.com/un33k/python-slugify/issues/138|
| [Pillow](https://python-pillow.org) | 10.1.0 | 10.1.0 | ✅ ||
| [rcssmin](http://opensource.perlig.de/rcssmin/) | 1.1.1 | 1.1.2 | ✅ |https://github.com/cookiecutter/cookiecutter-django/pull/4614|
| [argon2-cffi](https://pypi.org/project/argon2-cffi/) | 23.1.0 | 23.1.0 | ✅ ||
| [whitenoise](https://github.com/evansd/whitenoise) | 6.6.0 | 6.6.0 | ✅ ||
| [redis](https://github.com/redis/redis-py) | 5.0.3 |  | ❌ |https://github.com/redis/redis-py/pull/2979|
| [hiredis](https://github.com/redis/hiredis-py) | 2.3.2 | 2.3.1 | ✅ |https://github.com/redis/hiredis-py/issues/172|
| [celery](https://docs.celeryq.dev/) | 5.3.5 |  | ✅ |https://github.com/celery/celery/pull/8549|
| [django-celery-beat](https://github.com/celery/django-celery-beat) | 2.6.0 |  | ✅ |https://github.com/celery/django-celery-beat/issues/691|
| [flower](https://github.com/mher/flower) | 2.0.1 |  | ❌ |https://github.com/mher/flower/pull/1334|
| [uvicorn](https://pypi.org/project/uvicorn/) | 0.24.0.post1  | 0.24.0  | ✅ |https://github.com/encode/uvicorn/pull/2145|
| [django](https://www.djangoproject.com/) | 4.2.8 | 4.2.8  | ✅ |https://github.com/django/django/pull/17331 |
| [django-environ](https://django-environ.readthedocs.org) | 0.11.2 | >0.11.2  | ✅| https://github.com/joke2k/django-environ/pull/508|
| [django-model-utils](https://github.com/jazzband/django-model-utils) | 4.4.0 | >  4.3.1 / 3.12-dev | ✅ |https://github.com/jazzband/django-model-utils/pull/545|
| [django-allauth](https://www.intenct.nl/projects/django-allauth/) | 0.57.0 | 0.57.0 | ✅ |https://github.com/pennersr/django-allauth/pull/3463|
| [django-crispy-forms](https://pypi.org/project/django-crispy-forms/) | 2.1 | 2.1 | ✅ ||
| [crispy-bootstrap5](https://github.com/django-crispy-forms/crispy-bootstrap5) | [2023.10](https://github.com/django-crispy-forms/crispy-bootstrap5/releases/tag/2023.10) | 2023.10 | ✅ |https://github.com/django-crispy-forms/crispy-bootstrap5/pull/155|
| [django-compressor](https://django-compressor.readthedocs.io/en/latest/) | 4.4 |  | ✅ |https://github.com/django-compressor/django-compressor/pull/1214|
| [django-redis](https://github.com/jazzband/django-redis) | 5.4.0 |  | ❌ |https://github.com/jazzband/django-redis/pull/689|
| [djangorestframework](https://www.django-rest-framework.org/) | 3.15.0 |  | ✅ ||
| [django-cors-headers](https://github.com/adamchainz/django-cors-headers) | 4.3.0 | 4.3.0 | ✅ ||
| [drf-spectacular](https://github.com/tfranzel/drf-spectacular) | 0.27.0 | 0.27.0 | ✅ |https://github.com/tfranzel/drf-spectacular/pull/1096|
| [django-webpack-loader](https://github.com/django-webpack/django-webpack-loader) | 2.0.1 | 2.0.1  | ✅ |https://github.com/django-webpack/django-webpack-loader/pull/357|


## local.txt



| Name | Version in Master | 3.12 Compatible Version | OK | Issue / PR |
| ---- | :---------------: | :-----------------------------: | :-: |:-: |
| [Werkzeug](https://pypi.org/project/Werkzeug/) | 3.0.0 | n/a | ✅ ||
| [ipdb](https://github.com/gotcha/ipdb) | 0.13.13 |  | ❌ ||
| [psycopg](https://psycopg.org/psycopg3/) | 3.1.12 | 3.1.12 | ✅ ||
| [watchfiles](https://github.com/samuelcolvin/watchfiles/watchfiles) | 0.21.0 | 0.21.0 | ✅ ||
| [mypy](https://www.mypy-lang.org/) | 1.6.1 |  | ❌ ||
| [django-stubs](https://github.com/typeddjango/django-stubs) | 4.2.7 | 4.2.6 | ✅ ||
| [pytest](https://docs.pytest.org/en/latest/) | 7.4.2 | 7.4.3 | ✅ ||
| [pytest-sugar](https://pivotfinland.com/pytest-sugar/) | 1.0.0 |  | ✅ ||
| [djangorestframework-stubs](https://github.com/typeddjango/djangorestframework-stubs) | 3.14.4 | 3.14.4 | ✅ ||
| [sphinx](https://pypi.org/project/Sphinx/) | 7.2.6 | 7.2.6 | ✅ ||
| [sphinx-autobuild](https://github.com/executablebooks/sphinx-autobuild) | 2021.3.14 | 2021.3.14 | ✅ |https://github.com/executablebooks/sphinx-autobuild/pull/139|
| [flake8](https://github.com/pycqa/flake8) | 6.1.0 | n/a | ✅ ||
| [flake8-isort](https://github.com/gforcada/flake8-isort) | 6.1.0 | 6.1.0  |✅ |3.12.0-beta.2|
| [coverage](https://github.com/nedbat/coveragepy) | 7.3.2 | 7.3.2 | ✅ ||
| [black](https://pypi.org/project/black/) | 23.10.1 | 23.10.1 | ✅ ||
| [djlint](https://github.com/Riverside-Healthcare/djlint) | 1.34.1 |  | ✅ |https://github.com/Riverside-Healthcare/djLint/pull/781|
| [pylint-django](https://github.com/PyCQA/pylint-django) | 2.5.5 |  | ✅ |https://github.com/pylint-dev/pylint-django/pull/415|
| [pylint-celery](https://github.com/landscapeio/pylint-celery) | 0.3 | n/a | ✅ ||
| [pre-commit](https://github.com/pre-commit/pre-commit) | 3.5.0 | n/a | ✅ ||
| [factory-boy](https://github.com/FactoryBoy/factory_boy) | 3.3.0 | 3.3.0 |✅| CI
| [django-debug-toolbar](https://pypi.org/project/django-debug-toolbar/) | 4.2.0 | 4.2.0 | ✅ |CI|
| [django-extensions](https://github.com/django-extensions/django-extensions) | 3.2.3 |  | ❌ |https://github.com/django-extensions/django-extensions/pull/1849|
| [django-coverage-plugin](https://github.com/nedbat/django_coverage_plugin) | 3.1.0 | 3.1.0 | ✅ ||
| [pytest-django](https://pytest-django.readthedocs.io/) | 4.7.0 | 4.7.0 | ✅ |https://github.com/pytest-dev/pytest-django/pull/1086|


## production.txt

| Name | Version in Master | 3.12 Compatible Version | OK |Issue / PR |
| ---- | :---------------: | :-----------------------------: | :-: |:-:|
| [gunicorn](https://gunicorn.org) | 21.2.0 | 21.2.0 | ✅ |
| [psycopg](https://psycopg.org/psycopg3/) | 3.1.12 | 3.1.12 | ✅ ||
| [Collectfast](https://github.com/antonagestam/collectfast/) | 2.2.0 | Unmaintained | ✴️ ||
| [sentry-sdk](https://github.com/getsentry/sentry-python) | 1.33.0 | >1.32.0  | ✅ |https://github.com/getsentry/sentry-python/issues/2299|
| [hiredis](https://github.com/redis/hiredis-py) | 2.3.2 |  | ✅ |https://github.com/redis/hiredis-py/pull/174|
| [django-storages](https://pypi.org/project/django-storages/) | 1.14.2 |  | ✅ |https://github.com/jschneier/django-storages/pull/1331|
| [django-anymail](https://pypi.org/project/django-anymail/) | 10.2 | 10.2 | ✅ ||




Discussion:
As of today, we'd also need to update to Django 5.0 first:

> <h2>What Python version can I use with Django</h2>
> 
> Django version | Python versions
> -- | --
> 3.2 | 3.6, 3.7, 3.8, 3.9, 3.10 (added in 3.2.9)
> 4.0 | 3.8, 3.9, 3.10
> 4.1 | 3.8, 3.9, 3.10, 3.11 (added in 4.1.3)
> 4.2 | 3.8, 3.9, 3.10, 3.11
> 5.0 | 3.10, 3.11, 3.12
> 5.1 | 3.10, 3.11, 3.12

https://docs.djangoproject.com/en/dev/faq/install/#what-python-version-can-i-use-with-django
Since november django is being tested with 3.12: https://github.com/django/django/pull/16274
Its seems that 4.2.7 will officially support 3.12: https://forum.djangoproject.com/t/django-4-2-lts-compatibility-with-python-3-12/24508/3 
As per #4903, it looks like we were generating projects running Python 3.12 for about a month, and nobody really noticed, so we're probably good to move this forward. The projects which are still red in the table above are probably just signalling compatibilty in their trove classifiers. 

I've upgraded one of a project and the main blocker I hit was [this one](https://github.com/jazzband/django-debug-toolbar/issues/1875), with Django debug toolbar, when making concurrent requests locally.
              @WisdomPill We have an issue with async SSL in 3.12. But this should release in the 5.x final.

_Originally posted by @chayim in https://github.com/jazzband/django-redis/issues/689#issuecomment-1884494012_
            
The `redis` package is my only concern but we aren't using async + SSL so we can go ahead I think. 

Resolving patch:
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -39,7 +39,7 @@
     if python_major_version == 2:
         print(
             WARNING + "You're running cookiecutter under Python 2, but the generated "
-            "project requires Python 3.11+. Do you want to proceed (y/n)? " + TERMINATOR
+            "project requires Python 3.12+. Do you want to proceed (y/n)? " + TERMINATOR
         )
         yes_options, no_options = frozenset(["y"]), frozenset(["n"])
         while True:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,7 @@
         "License :: OSI Approved :: BSD License",
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3.12",
         "Programming Language :: Python :: Implementation :: CPython",
         "Topic :: Software Development",
     ],


Test patch: