1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
From 5c096ad7a59a3e9edee66e27fbae46c30e4abd6b Mon Sep 17 00:00:00 2001
From: asherzod1 <sh.abdumutalov1@gmail.com>
Date: Wed, 11 Mar 2026 00:53:19 +0500
Subject: [PATCH] fix: add Django 6 compatibility for signals, constraints, and
random char field
---
django_extensions/db/fields/__init__.py | 18 +++++++++++++-----
.../management/commands/list_signals.py | 4 +++-
tests/test_management_command.py | 6 +++++-
tests/testapp/models.py | 7 ++++++-
4 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/django_extensions/db/fields/__init__.py b/django_extensions/db/fields/__init__.py
index 938254e1f..c233cee84 100644
--- a/django_extensions/db/fields/__init__.py
+++ b/django_extensions/db/fields/__init__.py
@@ -86,7 +86,11 @@ def find_unique(self, model_instance, field, iterator, *args):
new = next(iterator)
kwargs[self.attname] = new
- while not new or queryset.filter(query, **kwargs):
+ while True:
+ matching = queryset.filter(query, **kwargs)
+ has_match = matching.exists() if hasattr(matching, "exists") else bool(matching)
+ if new and not has_match:
+ break
new = next(iterator)
kwargs[self.attname] = new
setattr(model_instance, self.attname, new)
@@ -388,10 +392,14 @@ def in_unique_together(self, model_instance):
return False
def pre_save(self, model_instance, add):
- if (not add or self.keep_default) and getattr(
- model_instance, self.attname
- ) != "":
- return getattr(model_instance, self.attname)
+ current_value = getattr(model_instance, self.attname)
+ # Django 6 may call pre_save multiple times for inserts; if we've already
+ # populated the field value, reuse it instead of regenerating.
+ if current_value not in ("", None):
+ return current_value
+
+ if (not add or self.keep_default) and current_value != "":
+ return current_value
population = ""
if self.include_alpha:
diff --git a/django_extensions/management/commands/list_signals.py b/django_extensions/management/commands/list_signals.py
index 9cadc4f85..e7bc9d7f6 100644
--- a/django_extensions/management/commands/list_signals.py
+++ b/django_extensions/management/commands/list_signals.py
@@ -52,7 +52,9 @@ def handle(self, *args, **options):
for signal in signals:
signal_name = SIGNAL_NAMES.get(signal, "unknown")
for receiver in signal.receivers:
- if django.VERSION >= (5, 0):
+ if django.VERSION >= (6, 0):
+ lookup, receiver, _sender, is_async = receiver
+ elif django.VERSION >= (5, 0):
lookup, receiver, is_async = receiver
else:
lookup, receiver = receiver
diff --git a/tests/test_management_command.py b/tests/test_management_command.py
index ea205ed72..0fb9dc27b 100644
--- a/tests/test_management_command.py
+++ b/tests/test_management_command.py
@@ -3,6 +3,7 @@
import logging
import importlib
+import django
from django.core.management import (
call_command,
find_commands,
@@ -421,7 +422,10 @@ def test_field_class(self):
stdout=out,
)
self.output = out.getvalue()
- self.assertIn("id - AutoField", self.output)
+ if django.VERSION >= (6, 0):
+ self.assertIn("id - BigAutoField", self.output)
+ else:
+ self.assertIn("id - AutoField", self.output)
self.assertIn("char_field - CharField", self.output)
self.assertIn("integer_field - IntegerField", self.output)
self.assertIn("foreign_key_field - ForeignKey", self.output)
diff --git a/tests/testapp/models.py b/tests/testapp/models.py
index 278402f51..3f31efcda 100644
--- a/tests/testapp/models.py
+++ b/tests/testapp/models.py
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
+import django
from django.db import models
from django.contrib.auth import get_user_model
from django.db.models import UniqueConstraint
@@ -178,7 +179,11 @@ class Meta:
fields=("common_field", "uniq_field"), name="unique_common_uniq_pair"
),
models.CheckConstraint(
- check=~models.Q(common_field=models.F("another_common_field")),
+ **(
+ {"condition": ~models.Q(common_field=models.F("another_common_field"))}
+ if django.VERSION >= (5, 2)
+ else {"check": ~models.Q(common_field=models.F("another_common_field"))}
+ ),
name="common_and_another_common_differ",
),
]
|