New Upstream Release - django-cachalot

Ready changes

Summary

Merged new upstream version: 2.5.3 (was: 2.5.2).

Resulting package

Built on 2023-05-31T17:24 (took 4m7s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases python3-django-cachalot

Lintian Result

Diff

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 509d6ac..6637bbb 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,14 @@
 What’s new in django-cachalot?
 ==============================
 
+2.5.3
+-----
+- Verify get_meta isn't none before requesting db_table (#225 #226)
+
+2.5.2
+-----
+- Added Django 4.1 support (#217)
+
 2.5.1
 -----
 
diff --git a/PKG-INFO b/PKG-INFO
index 7b551b3..732ef75 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: django-cachalot
-Version: 2.5.1
+Version: 2.5.3
 Summary: Caches your Django ORM queries and automatically invalidates them.
 Home-page: https://github.com/noripyt/django-cachalot
 Author: Bertrand Bordage, Andrew Chen Wang
 Author-email: acwangpython@gmail.com
 License: BSD
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Framework :: Django
 Classifier: Intended Audience :: Developers
@@ -15,6 +14,7 @@ Classifier: Operating System :: OS Independent
 Classifier: Framework :: Django :: 2.2
 Classifier: Framework :: Django :: 3.2
 Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
@@ -64,7 +64,7 @@ Table of Contents:
 Quickstart
 ----------
 
-Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0 with the databases PostgreSQL, SQLite, and MySQL.
+Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0-4.1 with the databases PostgreSQL, SQLite, and MySQL.
 
 Note: an upper limit on Django version is set for your safety. Please do not ignore it.
 
@@ -166,5 +166,3 @@ Legacy chats:
 .. _Andrew Chen Wang: https://github.com/Andrew-Chen-Wang
 
 .. image:: https://raw.github.com/noripyt/django-cachalot/master/django-cachalot.jpg
-
-
diff --git a/README.rst b/README.rst
index 48fc720..e58e5fd 100644
--- a/README.rst
+++ b/README.rst
@@ -39,7 +39,7 @@ Table of Contents:
 Quickstart
 ----------
 
-Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0 with the databases PostgreSQL, SQLite, and MySQL.
+Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0-4.1 with the databases PostgreSQL, SQLite, and MySQL.
 
 Note: an upper limit on Django version is set for your safety. Please do not ignore it.
 
diff --git a/cachalot/__init__.py b/cachalot/__init__.py
index f8d7ab0..32a4043 100644
--- a/cachalot/__init__.py
+++ b/cachalot/__init__.py
@@ -1,4 +1,4 @@
-VERSION = (2, 5, 1)
+VERSION = (2, 5, 3)
 __version__ = ".".join(map(str, VERSION))
 
 try:
diff --git a/cachalot/admin_tests/__init__.py b/cachalot/admin_tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/cachalot/admin_tests/admin.py b/cachalot/admin_tests/admin.py
new file mode 100644
index 0000000..dc42133
--- /dev/null
+++ b/cachalot/admin_tests/admin.py
@@ -0,0 +1,6 @@
+from django.contrib import admin
+from .models import TestModel
+
+@admin.register(TestModel)
+class TestModelAdmin(admin.ModelAdmin):
+    list_display = ('name', 'owner')
diff --git a/cachalot/admin_tests/migrations/0001_initial.py b/cachalot/admin_tests/migrations/0001_initial.py
new file mode 100644
index 0000000..9e41fe6
--- /dev/null
+++ b/cachalot/admin_tests/migrations/0001_initial.py
@@ -0,0 +1,52 @@
+# Generated by Django 4.1.7 on 2023-03-10 19:33
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django.db.models.functions.text
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="TestModel",
+            fields=[
+                (
+                    "id",
+                    models.AutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("name", models.CharField(max_length=20)),
+                (
+                    "owner",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.SET_NULL,
+                        to=settings.AUTH_USER_MODEL,
+                    ),
+                ),
+            ],
+            options={
+                "ordering": ("name",),
+            },
+        ),
+        migrations.AddConstraint(
+            model_name="testmodel",
+            constraint=models.UniqueConstraint(
+                fields=["name"],
+                condition=models.Q(owner=None),
+                name="unique_name",
+            ),
+        ),
+    ]
diff --git a/cachalot/admin_tests/migrations/__init__.py b/cachalot/admin_tests/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/cachalot/admin_tests/models.py b/cachalot/admin_tests/models.py
new file mode 100644
index 0000000..15ce4eb
--- /dev/null
+++ b/cachalot/admin_tests/models.py
@@ -0,0 +1,18 @@
+from django.conf import settings
+from django.db.models import Q, UniqueConstraint, Model, CharField, ForeignKey, SET_NULL
+
+
+class TestModel(Model):
+    name = CharField(max_length=20)
+    owner = ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
+                       on_delete=SET_NULL)
+
+    class Meta:
+        ordering = ('name',)
+        constraints = [
+            UniqueConstraint(
+                fields=["name"],
+                condition=Q(owner=None),
+                name="unique_name",
+            )
+        ]
diff --git a/cachalot/admin_tests/test_admin.py b/cachalot/admin_tests/test_admin.py
new file mode 100644
index 0000000..81df0fe
--- /dev/null
+++ b/cachalot/admin_tests/test_admin.py
@@ -0,0 +1,19 @@
+from django.test import TestCase
+from django.contrib.auth.models import User
+from .models import TestModel
+from django.test import Client
+
+
+class AdminTestCase(TestCase):
+    def setUp(self):
+        self.client = Client()
+        self.user = User.objects.create(username='admin', is_staff=True, is_superuser=True)
+
+    def test_save_test_model(self):
+        """
+        Model 'TestModel' has UniqueConstraint which caused problems when saving TestModelAdmin in Django >= 4.1
+        """
+        self.client.force_login(self.user)
+        response = self.client.post('/admin/admin_tests/testmodel/add/', {'name': 'test', 'public': True})
+        self.assertEqual(response.status_code, 302)
+        self.assertEqual(TestModel.objects.count(), 1)
diff --git a/cachalot/tests/read.py b/cachalot/tests/read.py
index 8d69956..f06354a 100644
--- a/cachalot/tests/read.py
+++ b/cachalot/tests/read.py
@@ -52,12 +52,13 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
         self.group__permissions = list(Permission.objects.all()[:3])
         self.group.permissions.add(*self.group__permissions)
         self.user = User.objects.create_user('user')
-        self.user__permissions = list(Permission.objects.all()[3:6])
+        self.user__permissions = list(Permission.objects.filter(content_type__app_label='auth')[3:6])
         self.user.groups.add(self.group)
         self.user.user_permissions.add(*self.user__permissions)
         self.admin = User.objects.create_superuser('admin', 'admin@test.me',
                                                    'password')
-        self.t1__permission = (Permission.objects.order_by('?')
+        self.t1__permission = (Permission.objects
+                               .order_by('?')
                                .select_related('content_type')[0])
         self.t1 = Test.objects.create(
             name='test1', owner=self.user,
@@ -352,7 +353,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
     @all_final_sql_checks
     def test_subquery(self):
         additional_tables = []
-        if django_version[0] >= 4 and settings.CACHALOT_FINAL_SQL_CHECK:
+        if django_version[0] == 4 and django_version[1] < 1 and settings.CACHALOT_FINAL_SQL_CHECK:
             # with Django 4.0 comes some query optimalizations that do selects little differently.
             additional_tables.append('django_content_type')
         qs = Test.objects.filter(owner__in=User.objects.all())
@@ -907,7 +908,7 @@ class ReadTestCase(TestUtilsMixin, TransactionTestCase):
     def test_explain(self):
         explain_kwargs = {}
         if self.is_sqlite:
-            expected = (r'\d+ 0 0 SCAN TABLE cachalot_test\n'
+            expected = (r'\d+ 0 0 SCAN cachalot_test\n'
                         r'\d+ 0 0 USE TEMP B-TREE FOR ORDER BY')
         elif self.is_mysql:
             if self.django_version < (3, 1):
diff --git a/cachalot/utils.py b/cachalot/utils.py
index a20d2a6..9df2a74 100644
--- a/cachalot/utils.py
+++ b/cachalot/utils.py
@@ -217,7 +217,8 @@ def _get_tables(db_alias, query, compiler=False):
 
         # Gets all tables already found by the ORM.
         tables = set(query.table_map)
-        tables.add(query.get_meta().db_table)
+        if query.get_meta():
+            tables.add(query.get_meta().db_table)
 
         # Gets tables in subquery annotations.
         for annotation in query.annotations.values():
diff --git a/debian/changelog b/debian/changelog
index 7e14ea8..1a77f97 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,9 +1,14 @@
-django-cachalot (2.5.1-1) UNRELEASED; urgency=medium
+django-cachalot (2.5.3-1) UNRELEASED; urgency=medium
 
+  [ Lena Voytek ]
   * New upstream versions 2.4.4, 2.4.5, 2.5.0, 2.5.1
   * d/control: allow python3-django 4.0 and above
 
- -- Lena Voytek <lena.voytek@canonical.com>  Mon, 15 Aug 2022 10:32:50 -0700
+  [ Debian Janitor ]
+  * New upstream release.
+  * New upstream release.
+
+ -- Lena Voytek <lena.voytek@canonical.com>  Wed, 31 May 2023 17:20:43 -0000
 
 django-cachalot (2.4.3-2) unstable; urgency=medium
 
diff --git a/django_cachalot.egg-info/PKG-INFO b/django_cachalot.egg-info/PKG-INFO
index 7b551b3..732ef75 100644
--- a/django_cachalot.egg-info/PKG-INFO
+++ b/django_cachalot.egg-info/PKG-INFO
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: django-cachalot
-Version: 2.5.1
+Version: 2.5.3
 Summary: Caches your Django ORM queries and automatically invalidates them.
 Home-page: https://github.com/noripyt/django-cachalot
 Author: Bertrand Bordage, Andrew Chen Wang
 Author-email: acwangpython@gmail.com
 License: BSD
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Framework :: Django
 Classifier: Intended Audience :: Developers
@@ -15,6 +14,7 @@ Classifier: Operating System :: OS Independent
 Classifier: Framework :: Django :: 2.2
 Classifier: Framework :: Django :: 3.2
 Classifier: Framework :: Django :: 4.0
+Classifier: Framework :: Django :: 4.1
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.7
 Classifier: Programming Language :: Python :: 3.8
@@ -64,7 +64,7 @@ Table of Contents:
 Quickstart
 ----------
 
-Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0 with the databases PostgreSQL, SQLite, and MySQL.
+Cachalot officially supports Python 3.7-3.10 and Django 2.2, 3.2, and 4.0-4.1 with the databases PostgreSQL, SQLite, and MySQL.
 
 Note: an upper limit on Django version is set for your safety. Please do not ignore it.
 
@@ -166,5 +166,3 @@ Legacy chats:
 .. _Andrew Chen Wang: https://github.com/Andrew-Chen-Wang
 
 .. image:: https://raw.github.com/noripyt/django-cachalot/master/django-cachalot.jpg
-
-
diff --git a/django_cachalot.egg-info/SOURCES.txt b/django_cachalot.egg-info/SOURCES.txt
index de821d9..cf02841 100644
--- a/django_cachalot.egg-info/SOURCES.txt
+++ b/django_cachalot.egg-info/SOURCES.txt
@@ -20,6 +20,12 @@ cachalot/settings.py
 cachalot/signals.py
 cachalot/transaction.py
 cachalot/utils.py
+cachalot/admin_tests/__init__.py
+cachalot/admin_tests/admin.py
+cachalot/admin_tests/models.py
+cachalot/admin_tests/test_admin.py
+cachalot/admin_tests/migrations/0001_initial.py
+cachalot/admin_tests/migrations/__init__.py
 cachalot/management/__init__.py
 cachalot/management/commands/__init__.py
 cachalot/management/commands/invalidate_cachalot.py
diff --git a/django_cachalot.egg-info/requires.txt b/django_cachalot.egg-info/requires.txt
index 8480fb7..051fbc0 100644
--- a/django_cachalot.egg-info/requires.txt
+++ b/django_cachalot.egg-info/requires.txt
@@ -1 +1 @@
-Django<4.1,>=2.2
+Django<4.2,>=2.2
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index b355ad0..b271001 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -4,7 +4,7 @@ Quick start
 Requirements
 ............
 
-- Django 2.2, 3.2, 4.0
+- Django 2.2, 3.2, 4.0-4.1
 - Python 3.7-3.10
 - a cache configured as ``'default'`` with one of these backends:
 
diff --git a/requirements.txt b/requirements.txt
index 9e8cdd1..7613f70 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1 @@
-Django>=2.2,<4.1
+Django>=2.2,<4.2
diff --git a/runtests.py b/runtests.py
index 14496e3..11f53a0 100755
--- a/runtests.py
+++ b/runtests.py
@@ -9,6 +9,6 @@ if __name__ == '__main__':
     django.setup()
     from django.test.runner import DiscoverRunner
     test_runner = DiscoverRunner(verbosity=2, interactive=False)
-    failures = test_runner.run_tests(['cachalot.tests'])
+    failures = test_runner.run_tests(['cachalot.tests', 'cachalot.admin_tests'])
     if failures:
         sys.exit(failures)
diff --git a/runtests_urls.py b/runtests_urls.py
index b11ff8c..4ca4fd1 100644
--- a/runtests_urls.py
+++ b/runtests_urls.py
@@ -1,6 +1,7 @@
 import debug_toolbar
-from django.urls import re_path, include
+from django.urls import path, re_path, include
 from django.http import HttpResponse
+from django.contrib import admin
 
 
 def empty_page(request):
@@ -10,4 +11,5 @@ def empty_page(request):
 urlpatterns = [
     re_path(r'^$', empty_page),
     re_path(r'^__debug__/', include(debug_toolbar.urls)),
+    path('admin/', admin.site.urls),
 ]
diff --git a/settings.py b/settings.py
index 0c1a89f..19d7560 100644
--- a/settings.py
+++ b/settings.py
@@ -12,6 +12,7 @@ DATABASES = {
         'ENGINE': 'django.db.backends.postgresql',
         'NAME': 'cachalot',
         'USER': 'cachalot',
+        'PASSWORD': 'password',
         'HOST': '127.0.0.1',
     },
     'mysql': {
@@ -90,9 +91,13 @@ elif DEFAULT_CACHE_ALIAS == 'pylibmc':
 
 INSTALLED_APPS = [
     'cachalot',
+    'cachalot.admin_tests',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.postgres',  # Enables the unaccent lookup.
+    'django.contrib.sessions',
+    'django.contrib.admin',
+    'django.contrib.messages',
 ]
 
 MIGRATION_MODULES = {
@@ -104,6 +109,12 @@ TEMPLATES = [
         'BACKEND': 'django.template.backends.django.DjangoTemplates',
         'DIRS': [],
         'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        }
     },
     {
         'BACKEND': 'django.template.backends.jinja2.Jinja2',
@@ -116,7 +127,11 @@ TEMPLATES = [
     }
 ]
 
-MIDDLEWARE = []
+MIDDLEWARE = [
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+]
 PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher']
 SECRET_KEY = 'it’s not important in tests but we have to set it'
 
diff --git a/setup.py b/setup.py
index 8f1a12a..4bcde17 100755
--- a/setup.py
+++ b/setup.py
@@ -28,6 +28,7 @@ setup(
         'Framework :: Django :: 2.2',
         'Framework :: Django :: 3.2',
         'Framework :: Django :: 4.0',
+        'Framework :: Django :: 4.1',
         'Programming Language :: Python :: 3',
         'Programming Language :: Python :: 3.7',
         'Programming Language :: Python :: 3.8',
diff --git a/tox.ini b/tox.ini
index 780eb86..166b359 100644
--- a/tox.ini
+++ b/tox.ini
@@ -3,9 +3,11 @@ envlist =
     py{37,38,39}-django2.2-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
     py{37,38,39,310}-django3.2-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
     py{38,39,310}-django4.0-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
+    py{38,39,310}-django4.1-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
     py{38,39,310}-djangomain-{sqlite3,postgresql,mysql}-{redis,memcached,pylibmc,locmem,filebased},
 
 [testenv]
+passenv = *
 basepython =
     py37: python3.7
     py38: python3.8
@@ -15,6 +17,7 @@ deps =
     django2.2: Django>=2.2,<2.3
     django3.2: Django>=3.2,<4.0
     django4.0: Django>=4.0,<4.1
+    django4.1: Django>=4.1,<4.2
     djangomain: https://github.com/django/django/archive/main.tar.gz
     psycopg2-binary>=2.8,<2.9
     mysqlclient
@@ -51,4 +54,5 @@ DJANGO =
     2.2: django2.2
     3.2: django3.2
     4.0: django4.0
+    4.1: django4.1
     main: djangomain

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/__init__.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/admin.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/migrations/0001_initial.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/migrations/__init__.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/models.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/cachalot/admin_tests/test_admin.py
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.3.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.3.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.3.egg-info/not-zip-safe
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.3.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.3.egg-info/top_level.txt

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.1.egg-info/PKG-INFO
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.1.egg-info/dependency_links.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.1.egg-info/not-zip-safe
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.1.egg-info/requires.txt
-rw-r--r--  root/root   /usr/lib/python3/dist-packages/django_cachalot-2.5.1.egg-info/top_level.txt

No differences were encountered in the control files

More details

Full run details