Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-django-cacheops for 
openSUSE:Factory checked in at 2023-11-13 22:18:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-cacheops (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-cacheops.new.17445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-cacheops"

Mon Nov 13 22:18:00 2023 rev:10 rq:1124878 version:7.0.2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-cacheops/python-django-cacheops.changes
    2023-05-10 16:18:14.086871882 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-django-cacheops.new.17445/python-django-cacheops.changes
 2023-11-13 22:20:37.682966331 +0100
@@ -1,0 +2,10 @@
+Fri Nov 10 12:25:25 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 7.0.2:
+  * fixed .aggregate()
+  * fixed big memory usage during migrations
+  * fixed INSIDEOUT in older redises
+  * better handle model families with abstracts in them
+  * allow funcy 2.0+
+
+-------------------------------------------------------------------

Old:
----
  django-cacheops-7.0.1.tar.gz

New:
----
  django-cacheops-7.0.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-cacheops.spec ++++++
--- /var/tmp/diff_new_pack.wj7dcZ/_old  2023-11-13 22:20:38.186984888 +0100
+++ /var/tmp/diff_new_pack.wj7dcZ/_new  2023-11-13 22:20:38.186984888 +0100
@@ -19,7 +19,7 @@
 %define skip_python2 1
 %define skip_python36 1
 Name:           python-django-cacheops
-Version:        7.0.1
+Version:        7.0.2
 Release:        0
 Summary:        Django ORM cache with automatic granular event-driven 
invalidation
 License:        BSD-3-Clause

++++++ django-cacheops-7.0.1.tar.gz -> django-cacheops-7.0.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/CHANGELOG 
new/django-cacheops-7.0.2/CHANGELOG
--- old/django-cacheops-7.0.1/CHANGELOG 2023-05-09 09:41:55.000000000 +0200
+++ new/django-cacheops-7.0.2/CHANGELOG 2023-10-24 12:16:26.000000000 +0200
@@ -1,3 +1,10 @@
+7.0.2
+- fixed .aggregate()
+- fixed big memory usage during migrations
+- fixed INSIDEOUT in older redises
+- better handle model families with abstracts in them
+- allow funcy 2.0+
+
 7.0.1
 - made it work with Redis 6.x and older again
 - handle abstract models better
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/PKG-INFO 
new/django-cacheops-7.0.2/PKG-INFO
--- old/django-cacheops-7.0.1/PKG-INFO  2023-05-09 09:49:47.681410600 +0200
+++ new/django-cacheops-7.0.2/PKG-INFO  2023-10-24 12:23:36.260995400 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: django-cacheops
-Version: 7.0.1
+Version: 7.0.2
 Summary: A slick ORM cache with automatic granular event-driven invalidation 
for Django.
 Home-page: http://github.com/Suor/django-cacheops
 Author: Alexander Schepanovski
 Author-email: suor....@gmail.com
 License: BSD
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -886,5 +885,3 @@
 
 .. |Build Status| image:: 
https://github.com/Suor/django-cacheops/actions/workflows/ci.yml/badge.svg
    :target: 
https://github.com/Suor/django-cacheops/actions/workflows/ci.yml?query=branch%3Amaster
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/__init__.py 
new/django-cacheops-7.0.2/cacheops/__init__.py
--- old/django-cacheops-7.0.1/cacheops/__init__.py      2023-05-09 
09:42:08.000000000 +0200
+++ new/django-cacheops-7.0.2/cacheops/__init__.py      2023-10-24 
12:16:49.000000000 +0200
@@ -1,4 +1,4 @@
-__version__ = '7.0.1'
+__version__ = '7.0.2'
 VERSION = tuple(map(int, __version__.split('.')))
 
 from .simple import *  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/conf.py 
new/django-cacheops-7.0.2/cacheops/conf.py
--- old/django-cacheops-7.0.1/cacheops/conf.py  2023-05-05 13:51:50.000000000 
+0200
+++ new/django-cacheops-7.0.2/cacheops/conf.py  2023-05-19 17:36:38.000000000 
+0200
@@ -96,7 +96,7 @@
     """
     Returns cacheops profile for a model
     """
-    assert not model._meta.abstract, "This should be handled by caller"
+    assert not model._meta.abstract, "Can't get profile for %s" % model
     # Django migrations create lots of fake models, just skip them
     if model.__module__ == '__fake__':
         return None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/getset.py 
new/django-cacheops-7.0.2/cacheops/getset.py
--- old/django-cacheops-7.0.1/cacheops/getset.py        2023-02-25 
06:59:13.000000000 +0100
+++ new/django-cacheops-7.0.2/cacheops/getset.py        2023-10-24 
12:11:51.000000000 +0200
@@ -1,6 +1,7 @@
 from contextlib import contextmanager
 import hashlib
 import json
+import random
 
 from .conf import settings
 from .redis import redis_client, handle_connection_failure, load_script
@@ -35,6 +36,8 @@
                 json.dumps(schemes),
                 json.dumps(conj_keys),
                 timeout,
+                # Need to pass it from here since random inside is not seeded 
in Redis pre 7.0
+                random.random(),
                 expected_checksum,
             ]
         )
@@ -78,7 +81,7 @@
 
     if None in stamps:
         redis_client.unlink(key)
-        return
+        return None
 
     stamp_checksum, data = coded.split(b':', 1)
     if stamp_checksum.decode() != join_stamps(stamps):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/lua/cache_thing.lua 
new/django-cacheops-7.0.2/cacheops/lua/cache_thing.lua
--- old/django-cacheops-7.0.1/cacheops/lua/cache_thing.lua      2023-04-03 
13:32:23.000000000 +0200
+++ new/django-cacheops-7.0.2/cacheops/lua/cache_thing.lua      2023-05-20 
07:25:51.000000000 +0200
@@ -50,13 +50,13 @@
         -- REDIS_7
         redis.call('expire', conj_key, timeout, 'gt')
         -- /REDIS_7
-        -- REDIS_6
+        -- REDIS_4
         local conj_ttl = redis.call('ttl', conj_key)
         if conj_ttl < timeout then
             -- We set conj_key life with a margin over key life to call expire 
rarer
             -- And add few extra seconds to be extra safe
             redis.call('expire', conj_key, timeout * 2 + 10)
         end
-        -- /REDIS_6
+        -- /REDIS_4
     end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-cacheops-7.0.1/cacheops/lua/cache_thing_insideout.lua 
new/django-cacheops-7.0.2/cacheops/lua/cache_thing_insideout.lua
--- old/django-cacheops-7.0.1/cacheops/lua/cache_thing_insideout.lua    
2023-04-03 13:31:30.000000000 +0200
+++ new/django-cacheops-7.0.2/cacheops/lua/cache_thing_insideout.lua    
2023-05-20 08:14:06.000000000 +0200
@@ -4,7 +4,8 @@
 local schemes = cjson.decode(ARGV[2])
 local conj_keys = cjson.decode(ARGV[3])
 local timeout = tonumber(ARGV[4])
-local expected_checksum = ARGV[5]
+local rnd = ARGV[5]  -- A new value for empty stamps
+local expected_checksum = ARGV[6]
 
 -- Ensure schemes are known
 for db_table, _schemes in pairs(schemes) do
@@ -13,23 +14,31 @@
 
 -- Fill in invalidators and collect stamps
 local stamps = {}
-local rnd = tostring(math.random())  -- A new value for empty stamps
 for _, conj_key in ipairs(conj_keys) do
+    -- REDIS_7
     local stamp = redis.call('set', conj_key, rnd, 'nx', 'get') or rnd
+    -- /REDIS_7
+    -- REDIS_4
+    local stamp = redis.call('get', conj_key)
+    if not stamp then
+        stamp = rnd
+        redis.call('set', conj_key, rnd)
+    end
+    -- /REDIS_4
     table.insert(stamps, stamp)
     -- NOTE: an invalidator should live longer than any key it references.
     --       So we update its ttl on every key if needed.
     -- REDIS_7
     redis.call('expire', conj_key, timeout, 'gt')
     -- /REDIS_7
-    -- REDIS_6
+    -- REDIS_4
     local conj_ttl = redis.call('ttl', conj_key)
     if conj_ttl < timeout then
         -- We set conj_key life with a margin over key life to call expire 
rarer
         -- And add few extra seconds to be extra safe
         redis.call('expire', conj_key, timeout * 2 + 10)
     end
-    -- /REDIS_6
+    -- /REDIS_4
 end
 
 -- Write data to cache along with a checksum of the stamps to see if any of 
them changed
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/query.py 
new/django-cacheops-7.0.2/cacheops/query.py
--- old/django-cacheops-7.0.1/cacheops/query.py 2023-05-05 13:51:50.000000000 
+0200
+++ new/django-cacheops-7.0.2/cacheops/query.py 2023-10-18 11:15:33.000000000 
+0200
@@ -274,14 +274,33 @@
 
     def aggregate(self, *args, **kwargs):
         if self._should_cache('aggregate'):
-            # We resolve aggregates to add joins, which will affect query DNF
-            qs = self._clone()
-            for aggregate_expr in chain(args, kwargs.values()):
-                aggregate_expr.resolve_expression(
-                    qs.query, allow_joins=True, reuse=None, summarize=True)
+            # Apply all aggregates the same way original .aggregate() does, 
but do not perform sql.
+            # This code is mostly taken from QuerySet.aggregate().
+            normalized_kwargs = kwargs.copy()
+            for arg in args:
+                try:
+                    normalized_kwargs[arg.default_alias] = arg
+                except (AttributeError, TypeError):
+                    # Let Django raise a proper error
+                    return self._no_monkey.aggregate(*args, **kwargs)
+
+            # Simulate Query.get_aggregation() preparations, this adds proper 
joins to qs.query
+            if not normalized_kwargs:
+                return {}
 
-            # Use resulting qs as a ref
-            return cached_as(qs)(lambda: self._no_monkey.aggregate(self, 
*args, **kwargs))()
+            qs = self._clone()
+            aggregates = {}
+            for alias, aggregate_expr in normalized_kwargs.items():
+                aggregate = aggregate_expr.resolve_expression(
+                    qs.query, allow_joins=True, reuse=None, summarize=True
+                )
+                if not aggregate.contains_aggregate:
+                    raise TypeError("%s is not an aggregate expression" % 
alias)
+                aggregates[alias] = aggregate
+
+            # Use resulting qs as a ref, aggregates still contain names, etc
+            func = lambda: self._no_monkey.aggregate(self, *args, **kwargs)
+            return cached_as(qs, extra=aggregates)(func)()
         else:
             return self._no_monkey.aggregate(self, *args, **kwargs)
 
@@ -397,8 +416,9 @@
     def contribute_to_class(self, cls, name):
         self._no_monkey.contribute_to_class(self, cls, name)
         # NOTE: we check it here rather then inside _install_cacheops()
-        #       because we don't want @once_per() to hold refs to all of them.
-        if family_has_profile(cls):
+        #       because we don't want @once_per() and family_has_profile() 
memory to hold refs.
+        #       Otherwise, temporary classes made for migrations might hoard 
lots of memory.
+        if cls.__module__ != '__fake__' and family_has_profile(cls):
             self._install_cacheops(cls)
 
     @skip_on_no_invalidation
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/redis.py 
new/django-cacheops-7.0.2/cacheops/redis.py
--- old/django-cacheops-7.0.1/cacheops/redis.py 2023-04-04 12:55:06.000000000 
+0200
+++ new/django-cacheops-7.0.2/cacheops/redis.py 2023-05-20 08:14:38.000000000 
+0200
@@ -63,7 +63,7 @@
     with open(filename) as f:
         code = f.read()
     if is_redis_7():
-        code = re.sub(r'REDIS_6.*?/REDIS_6', '', code, flags=re.S)
+        code = re.sub(r'REDIS_4.*?/REDIS_4', '', code, flags=re.S)
     else:
         code = re.sub(r'REDIS_7.*?/REDIS_7', '', code, flags=re.S)
     return redis_client.register_script(code)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/cacheops/utils.py 
new/django-cacheops-7.0.2/cacheops/utils.py
--- old/django-cacheops-7.0.1/cacheops/utils.py 2023-05-05 13:51:50.000000000 
+0200
+++ new/django-cacheops-7.0.2/cacheops/utils.py 2023-05-19 17:43:23.000000000 
+0200
@@ -1,7 +1,7 @@
 import re
 import json
 import inspect
-from funcy import memoize, compose, wraps, any, any_fn, select_values, lmapcat
+from funcy import memoize, compose, wraps, any, any_fn, select_values, mapcat
 
 from django.db import models
 from django.http import HttpRequest
@@ -9,10 +9,6 @@
 from .conf import model_profile
 
 
-def get_table_model(model):
-    return next((b for b in model.__mro__ if issubclass(b, models.Model) and b 
is not models.Model
-                 and not b._meta.proxy and not b._meta.abstract), None)
-
 def model_family(model):
     """
     The family is models sharing a database table, events on one should affect 
each other.
@@ -20,14 +16,19 @@
     We simply collect a list of all proxy models, including subclasess, 
superclasses and siblings.
     Two descendants of an abstract model are not family - they cannot affect 
each other.
     """
-    def class_tree(cls):
-        return [cls] + lmapcat(class_tree, cls.__subclasses__())
-
-    # NOTE: we also list multitable submodels here, we just don't care.
-    #       Cacheops doesn't support them anyway.
-    table_model = get_table_model(model)
-    return class_tree(table_model) if table_model else []
+    if model._meta.abstract:  # No table - no family
+        return set()
 
+    @memoize
+    def class_tree(cls):
+        # NOTE: we also list multitable submodels here, we just don't care.
+        #       Cacheops doesn't support them anyway.
+        return {cls} | set(mapcat(class_tree, cls.__subclasses__()))
+
+    table_bases = {b for b in model.__mro__ if issubclass(b, models.Model) and 
b is not models.Model
+                   and not b._meta.proxy and not b._meta.abstract}
+    family = set(mapcat(class_tree, table_bases))
+    return {cls for cls in family if not cls._meta.abstract}
 
 @memoize
 def family_has_profile(cls):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-cacheops-7.0.1/django_cacheops.egg-info/PKG-INFO 
new/django-cacheops-7.0.2/django_cacheops.egg-info/PKG-INFO
--- old/django-cacheops-7.0.1/django_cacheops.egg-info/PKG-INFO 2023-05-09 
09:49:47.000000000 +0200
+++ new/django-cacheops-7.0.2/django_cacheops.egg-info/PKG-INFO 2023-10-24 
12:23:36.000000000 +0200
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: django-cacheops
-Version: 7.0.1
+Version: 7.0.2
 Summary: A slick ORM cache with automatic granular event-driven invalidation 
for Django.
 Home-page: http://github.com/Suor/django-cacheops
 Author: Alexander Schepanovski
 Author-email: suor....@gmail.com
 License: BSD
-Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Operating System :: OS Independent
@@ -886,5 +885,3 @@
 
 .. |Build Status| image:: 
https://github.com/Suor/django-cacheops/actions/workflows/ci.yml/badge.svg
    :target: 
https://github.com/Suor/django-cacheops/actions/workflows/ci.yml?query=branch%3Amaster
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-cacheops-7.0.1/django_cacheops.egg-info/requires.txt 
new/django-cacheops-7.0.2/django_cacheops.egg-info/requires.txt
--- old/django-cacheops-7.0.1/django_cacheops.egg-info/requires.txt     
2023-05-09 09:49:47.000000000 +0200
+++ new/django-cacheops-7.0.2/django_cacheops.egg-info/requires.txt     
2023-10-24 12:23:36.000000000 +0200
@@ -1,3 +1,3 @@
 django>=3.2
 redis>=3.0.0
-funcy<2.0,>=1.8
+funcy<3.0,>=1.8
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/requirements-test.txt 
new/django-cacheops-7.0.2/requirements-test.txt
--- old/django-cacheops-7.0.1/requirements-test.txt     2023-03-11 
10:05:33.000000000 +0100
+++ new/django-cacheops-7.0.2/requirements-test.txt     2023-05-11 
08:42:49.000000000 +0200
@@ -2,7 +2,7 @@
 pytest-django==4.5.2
 django>=3.2
 redis>=3.0.0
-funcy>=1.8,<2.0
+funcy>=1.8,<3.0
 before_after==1.0.0
 jinja2>=2.10
 dill
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/setup.py 
new/django-cacheops-7.0.2/setup.py
--- old/django-cacheops-7.0.1/setup.py  2023-05-09 09:42:03.000000000 +0200
+++ new/django-cacheops-7.0.2/setup.py  2023-10-24 12:16:36.000000000 +0200
@@ -7,7 +7,7 @@
 
 setup(
     name='django-cacheops',
-    version='7.0.1',
+    version='7.0.2',
     author='Alexander Schepanovski',
     author_email='suor....@gmail.com',
 
@@ -26,7 +26,7 @@
     install_requires=[
         'django>=3.2',
         'redis>=3.0.0',
-        'funcy>=1.8,<2.0',
+        'funcy>=1.8,<3.0',
     ],
     classifiers=[
         'Development Status :: 5 - Production/Stable',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/tests/models.py 
new/django-cacheops-7.0.2/tests/models.py
--- old/django-cacheops-7.0.1/tests/models.py   2023-05-05 13:51:50.000000000 
+0200
+++ new/django-cacheops-7.0.2/tests/models.py   2023-05-20 07:03:30.000000000 
+0200
@@ -309,6 +309,44 @@
     name = models.CharField(max_length=255)
 
 
+# Abstract models
 class Abs(models.Model):
     class Meta:
         abstract = True
+
+class Concrete1(Abs):
+    pass
+
+class AbsChild(Abs):
+    class Meta:
+        abstract = True
+
+class Concrete2(AbsChild):
+    pass
+
+class NoProfile(models.Model):
+    title = models.CharField(max_length=128)
+
+class NoProfileProxy(NoProfile):
+    class Meta:
+        proxy = True
+
+class AbsNoProfile(NoProfile):
+    class Meta:
+        abstract = True
+
+class NoProfileChild(AbsNoProfile):
+    pass
+
+
+class ParentId(models.Model):
+    pass
+
+class ParentStr(models.Model):
+    name = models.CharField(max_length=128, primary_key=True)
+
+class Mess(ParentId, ParentStr):
+    pass
+
+class MessChild(Mess):
+    pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/tests/settings.py 
new/django-cacheops-7.0.2/tests/settings.py
--- old/django-cacheops-7.0.1/tests/settings.py 2023-05-03 09:01:43.000000000 
+0200
+++ new/django-cacheops-7.0.2/tests/settings.py 2023-05-17 13:55:39.000000000 
+0200
@@ -111,6 +111,7 @@
     'tests.*': {},
     'tests.noncachedvideoproxy': None,
     'tests.noncachedmedia': None,
+    'tests.noprofile': None,
     'auth.*': {},
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/tests/test_extras.py 
new/django-cacheops-7.0.2/tests/test_extras.py
--- old/django-cacheops-7.0.1/tests/test_extras.py      2023-05-05 
13:51:50.000000000 +0200
+++ new/django-cacheops-7.0.2/tests/test_extras.py      2023-05-20 
07:03:41.000000000 +0200
@@ -6,7 +6,7 @@
 from cacheops.signals import cache_read, cache_invalidated
 
 from .utils import BaseTestCase, make_inc
-from .models import Post, Category, Local, DbAgnostic, DbBinded, Abs
+from .models import Post, Category, Local, DbAgnostic, DbBinded
 
 
 class SettingsTests(TestCase):
@@ -185,7 +185,23 @@
             list(DbBinded.objects.cache().using('slave'))
 
 
-def test_abstract_family():
+def test_model_family():
     from cacheops.utils import model_family
+    from .models import Abs, Concrete1, AbsChild, Concrete2
+    from .models import NoProfile, NoProfileProxy, AbsNoProfile, NoProfileChild
+    from .models import ParentId, ParentStr, Mess, MessChild
+
+    # Abstract models do not have family, children of an abstract model are 
not a family
+    assert model_family(Abs) == set()
+    assert model_family(Concrete1) == {Concrete1}
+    assert model_family(AbsChild) == set()
+    assert model_family(Concrete2) == {Concrete2}
+
+    # Everything in but an abstract model
+    assert model_family(NoProfile) == {NoProfile, NoProfileProxy, 
NoProfileChild}
+    assert model_family(NoProfileProxy) == {NoProfile, NoProfileProxy, 
NoProfileChild}
+    assert model_family(AbsNoProfile) == set()
+    assert model_family(NoProfileChild) == {NoProfile, NoProfileProxy, 
NoProfileChild}
 
-    assert model_family(Abs) == []
+    # The worst of multiple inheritance
+    assert model_family(Mess) == {Mess, MessChild, ParentId, ParentStr}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-cacheops-7.0.1/tests/tests.py 
new/django-cacheops-7.0.2/tests/tests.py
--- old/django-cacheops-7.0.1/tests/tests.py    2023-05-05 13:51:50.000000000 
+0200
+++ new/django-cacheops-7.0.2/tests/tests.py    2023-05-20 08:14:46.000000000 
+0200
@@ -10,7 +10,7 @@
 from django.test import override_settings
 from django.test.client import RequestFactory
 from django.template import Context, Template
-from django.db.models import F, Count, OuterRef, Sum, Subquery, Exists
+from django.db.models import F, Count, Max, OuterRef, Sum, Subquery, Exists, Q
 from django.db.models.expressions import RawSQL
 
 from cacheops import invalidate_model, invalidate_obj, \
@@ -794,6 +794,16 @@
         with self.assertNumQueries(0):
             qs.aggregate(posts_count=Count('posts'))
 
+    def test_new_alias(self):
+        qs = Post.objects.cache()
+        assert qs.aggregate(max=Max('category')) == {'max': 3}
+        assert qs.aggregate(cat=Max('category')) == {'cat': 3}
+
+    def test_filter(self):
+        qs = Post.objects.cache()
+        assert qs.aggregate(cnt=Count('category', filter=Q(category__gt=1))) 
== {'cnt': 2}
+        assert qs.aggregate(cnt=Count('category', filter=Q(category__lt=3))) 
== {'cnt': 1}
+
 
 class M2MTests(BaseTestCase):
     brand_cls = Brand

Reply via email to