diff --git a/.github/contributors.json b/.github/contributors.json
index 596f2af838..057309a52a 100644
--- a/.github/contributors.json
+++ b/.github/contributors.json
@@ -1115,7 +1115,7 @@
"twitter_username": "Qoyyuum"
},
{
- "name": "mfosterw",
+ "name": "Matthew Foster Walsh",
"github_login": "mfosterw",
"twitter_username": ""
},
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7daf6ac713..6355c5ac72 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -26,7 +26,7 @@ repos:
args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade
- rev: v3.15.0
+ rev: v3.15.1
hooks:
- id: pyupgrade
args: [--py311-plus]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1f9b078572..b8ad3f6bf1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,23 @@ All enhancements and patches to Cookiecutter Django will be documented in this f
+## 2024.02.21
+
+
+### Changed
+
+- Switch to `celery.shared_task` to define tasks ([#4881](https://github.com/cookiecutter/cookiecutter-django/pull/4881))
+
+- Replace usages of `get_user_model` by importing model directly ([#4879](https://github.com/cookiecutter/cookiecutter-django/pull/4879))
+
+### Updated
+
+- Auto-update pre-commit hooks ([#4873](https://github.com/cookiecutter/cookiecutter-django/pull/4873))
+
+- Update pre-commit to 3.6.2 ([#4874](https://github.com/cookiecutter/cookiecutter-django/pull/4874))
+
+- Update ruff to 0.2.2 ([#4871](https://github.com/cookiecutter/cookiecutter-django/pull/4871))
+
## 2024.02.19
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 9a59b6572b..734900362f 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -1454,6 +1454,13 @@ Listed in alphabetical order.
|
+
+ Matthew Foster Walsh |
+
+ mfosterw
+ |
+ |
+
Matthew Sisley |
@@ -1489,13 +1496,6 @@ Listed in alphabetical order.
|
|
-
- mfosterw |
-
- mfosterw
- |
- |
-
Michael Gecht |
diff --git a/requirements.txt b/requirements.txt
index 077ce3f751..3635390f15 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,10 +4,10 @@ binaryornot==0.4.4
# Code quality
# ------------------------------------------------------------------------------
-ruff==0.2.1
+ruff==0.2.2
django-upgrade==1.16.0
djlint==1.34.1
-pre-commit==3.6.1
+pre-commit==3.6.2
# Testing
# ------------------------------------------------------------------------------
diff --git a/setup.py b/setup.py
index b29fc417a7..62b38573dd 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
from distutils.core import setup
# We use calendar versioning
-version = "2024.02.19"
+version = "2024.02.21"
with open("README.md") as readme_file:
long_description = readme_file.read()
diff --git a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
index 7c9565e191..1d06c042ff 100644
--- a/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
+++ b/{{cookiecutter.project_slug}}/.pre-commit-config.yaml
@@ -35,7 +35,7 @@ repos:
# Run the Ruff linter.
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.2.1
+ rev: v0.2.2
hooks:
# Linter
- id: ruff
diff --git a/{{cookiecutter.project_slug}}/requirements/local.txt b/{{cookiecutter.project_slug}}/requirements/local.txt
index 4c142ff66e..8225dab0f7 100644
--- a/{{cookiecutter.project_slug}}/requirements/local.txt
+++ b/{{cookiecutter.project_slug}}/requirements/local.txt
@@ -28,10 +28,10 @@ sphinx-autobuild==2024.2.4 # https://github.com/GaretJax/sphinx-autobuild
# Code quality
# ------------------------------------------------------------------------------
-ruff==0.2.1 # https://github.com/astral-sh/ruff
+ruff==0.2.2 # https://github.com/astral-sh/ruff
coverage==7.4.1 # https://github.com/nedbat/coveragepy
djlint==1.34.1 # https://github.com/Riverside-Healthcare/djLint
-pre-commit==3.6.1 # https://github.com/pre-commit/pre-commit
+pre-commit==3.6.2 # https://github.com/pre-commit/pre-commit
# Django
# ------------------------------------------------------------------------------
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py
index 9d6c7562dd..d0d1488f86 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/admin.py
@@ -1,19 +1,17 @@
from django.conf import settings
from django.contrib import admin
from django.contrib.auth import admin as auth_admin
-from django.contrib.auth import decorators
-from django.contrib.auth import get_user_model
+from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext_lazy as _
from {{ cookiecutter.project_slug }}.users.forms import UserAdminChangeForm
from {{ cookiecutter.project_slug }}.users.forms import UserAdminCreationForm
-
-User = get_user_model()
+from {{ cookiecutter.project_slug }}.users.models import User
if settings.DJANGO_ADMIN_FORCE_ALLAUTH:
# Force the `admin` sign in process to go through the `django-allauth` workflow:
# https://docs.allauth.org/en/latest/common/admin.html#admin
- admin.site.login = decorators.login_required(admin.site.login) # type: ignore[method-assign]
+ admin.site.login = login_required(admin.site.login) # type: ignore[method-assign]
@admin.register(User)
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py
index ef2adb911d..51e0859f36 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/serializers.py
@@ -1,12 +1,9 @@
-from django.contrib.auth import get_user_model
from rest_framework import serializers
-from {{ cookiecutter.project_slug }}.users.models import User as UserType
+from {{ cookiecutter.project_slug }}.users.models import User
-User = get_user_model()
-
-class UserSerializer(serializers.ModelSerializer[UserType]):
+class UserSerializer(serializers.ModelSerializer[User]):
class Meta:
model = User
{%- if cookiecutter.username_type == "email" %}
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 8bdf24b0be..7a521cdfe4 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/api/views.py
@@ -1,4 +1,3 @@
-from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.mixins import ListModelMixin
@@ -7,9 +6,9 @@
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
-from .serializers import UserSerializer
+from {{ cookiecutter.project_slug }}.users.models import User
-User = get_user_model()
+from .serializers import UserSerializer
class UserViewSet(RetrieveModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py
index ac5b647d32..2d18de2089 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/forms.py
@@ -1,13 +1,12 @@
from allauth.account.forms import SignupForm
from allauth.socialaccount.forms import SignupForm as SocialSignupForm
from django.contrib.auth import forms as admin_forms
-from django.contrib.auth import get_user_model
{%- if cookiecutter.username_type == "email" %}
from django.forms import EmailField
{%- endif %}
from django.utils.translation import gettext_lazy as _
-User = get_user_model()
+from {{ cookiecutter.project_slug }}.users.models import User
class UserAdminChangeForm(admin_forms.UserChangeForm):
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py
index c99341c5ff..2afd4d4bde 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tasks.py
@@ -1,11 +1,9 @@
-from django.contrib.auth import get_user_model
+from celery import shared_task
-from config import celery_app
+from {{ cookiecutter.project_slug }}.users.models import User
-User = get_user_model()
-
-@celery_app.task()
+@shared_task()
def get_users_count():
"""A pointless Celery task to demonstrate usage."""
return User.objects.count()
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 f614681bbd..136d0b1d52 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/tests/factories.py
@@ -1,11 +1,12 @@
from collections.abc import Sequence
from typing import Any
-from django.contrib.auth import get_user_model
from factory import Faker
from factory import post_generation
from factory.django import DjangoModelFactory
+from {{ cookiecutter.project_slug }}.users.models import User
+
class UserFactory(DjangoModelFactory):
{%- if cookiecutter.username_type == "username" %}
@@ -38,5 +39,5 @@ def _after_postgeneration(cls, instance, create, results=None):
instance.save()
class Meta:
- model = get_user_model()
+ model = User
django_get_or_create = ["{{cookiecutter.username_type}}"]
diff --git a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py
index 6d26e9c75e..3f20f2686c 100644
--- a/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py
+++ b/{{cookiecutter.project_slug}}/{{cookiecutter.project_slug}}/users/views.py
@@ -1,4 +1,3 @@
-from django.contrib.auth import get_user_model
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse
@@ -7,7 +6,7 @@
from django.views.generic import RedirectView
from django.views.generic import UpdateView
-User = get_user_model()
+from {{ cookiecutter.project_slug }}.users.models import User
class UserDetailView(LoginRequiredMixin, DetailView):
|