From b3540bc0190db563409328c26cd722cf7f2bd6e5 Mon Sep 17 00:00:00 2001 From: Mounir Date: Thu, 15 Dec 2022 11:32:33 +0100 Subject: [PATCH] Make `Theme.get_active_theme` class method a manager method. (#230) - Make `get_active_theme` a manager method instead of class method - Replace `get_active_theme` by `get_active` - Refactor signals handlers --- admin_interface/models.py | 63 ++++++++++--------- .../templatetags/admin_interface_tags.py | 2 +- tests/test_fixtures.py | 4 +- tests/test_models.py | 24 +++---- tests/test_multidb.py | 4 +- 5 files changed, 49 insertions(+), 48 deletions(-) diff --git a/admin_interface/models.py b/admin_interface/models.py index dd91bbf..70d6e65 100644 --- a/admin_interface/models.py +++ b/admin_interface/models.py @@ -2,47 +2,25 @@ from colorfield.fields import ColorField from django.core.validators import FileExtensionValidator from django.db import models from django.db.models.signals import post_delete, post_save, pre_save +from django.dispatch import receiver from django.utils.encoding import force_str from django.utils.translation import gettext_lazy as _ from .cache import del_cached_active_theme -class Theme(models.Model): - @staticmethod - def post_delete_handler(**kwargs): - del_cached_active_theme() - Theme.get_active_theme() - - @staticmethod - def post_save_handler(instance, **kwargs): - del_cached_active_theme() - if instance.active: - Theme.objects.exclude(pk=instance.pk).update(active=False) - Theme.get_active_theme() - - @staticmethod - def pre_save_handler(instance, **kwargs): - if instance.pk is None: - try: - obj = Theme.objects.get(name=instance.name) - instance.pk = obj.pk - except Theme.DoesNotExist: - pass - - @staticmethod - def get_active_theme(): - objs_manager = Theme.objects - objs_active_qs = objs_manager.filter(active=True) +class ThemeQuerySet(models.QuerySet): + def get_active(self): + objs_active_qs = self.filter(active=True) objs_active_ls = list(objs_active_qs) objs_active_count = len(objs_active_ls) if objs_active_count == 0: - obj = objs_manager.all().first() + obj = self.all().first() if obj: obj.set_active() else: - obj = objs_manager.create() + obj = self.create() elif objs_active_count == 1: obj = objs_active_ls[0] @@ -53,6 +31,8 @@ class Theme(models.Model): return obj + +class Theme(models.Model): name = models.CharField( unique=True, max_length=50, @@ -386,6 +366,8 @@ class Theme(models.Model): verbose_name=_("sticky pagination"), ) + objects = ThemeQuerySet.as_manager() + def set_active(self): self.active = True self.save() @@ -399,6 +381,25 @@ class Theme(models.Model): return force_str(self.name) -post_delete.connect(Theme.post_delete_handler, sender=Theme) -post_save.connect(Theme.post_save_handler, sender=Theme) -pre_save.connect(Theme.pre_save_handler, sender=Theme) +@receiver(post_delete, sender=Theme) +def post_delete_handler(sender, instance, **kwargs): + del_cached_active_theme() + Theme.objects.get_active() + + +@receiver(post_save, sender=Theme) +def post_save_handler(sender, instance, **kwargs): + del_cached_active_theme() + if instance.active: + Theme.objects.exclude(pk=instance.pk).update(active=False) + Theme.objects.get_active() + + +@receiver(pre_save, sender=Theme) +def pre_save_handler(sender, instance, **kwargs): + if instance.pk is None: + try: + obj = Theme.objects.get(name=instance.name) + instance.pk = obj.pk + except Theme.DoesNotExist: + pass diff --git a/admin_interface/templatetags/admin_interface_tags.py b/admin_interface/templatetags/admin_interface_tags.py index 2855562..a93b5ef 100644 --- a/admin_interface/templatetags/admin_interface_tags.py +++ b/admin_interface/templatetags/admin_interface_tags.py @@ -59,7 +59,7 @@ def get_admin_interface_languages(context): def get_admin_interface_theme(): theme = get_cached_active_theme() if not theme: - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() set_cached_active_theme(theme) return theme diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 49aaa1b..7b2cc2c 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -38,10 +38,10 @@ class AdminInterfaceFixturesTestCase(TestCase): self.assertEqual(Theme.objects.count(), 2) def test_import_override(self): - obj1 = Theme.get_active_theme() + obj1 = Theme.objects.get_active() obj1.title = "Custom 1" obj1.save() self.__load_theme("django") - obj2 = Theme.get_active_theme() + obj2 = Theme.objects.get_active() self.assertEqual(obj1.pk, obj2.pk) self.assertTrue(obj1.title != obj2.title) diff --git a/tests/test_models.py b/tests/test_models.py index 1b3a5a4..49ff785 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -17,7 +17,7 @@ class AdminInterfaceModelsTestCase(TestCase): shutil.rmtree(settings.MEDIA_ROOT, ignore_errors=True) def __test_active_theme(self): - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() print(theme) self.assertTrue(theme is not None) self.assertTrue(theme.active) @@ -33,7 +33,7 @@ class AdminInterfaceModelsTestCase(TestCase): def test_default_theme_activated_on_save_if_no_active_themes(self): Theme.objects.all().delete() - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() theme.active = False theme.save() self.__test_active_theme() @@ -57,7 +57,7 @@ class AdminInterfaceModelsTestCase(TestCase): theme_1 = Theme.objects.create(name="Custom 1", active=True) theme_2 = Theme.objects.create(name="Custom 2", active=True) theme_3 = Theme.objects.create(name="Custom 3", active=True) - Theme.objects.filter(pk=Theme.get_active_theme().pk).delete() + Theme.objects.filter(pk=Theme.objects.get_active().pk).delete() self.__test_active_theme() def test_last_theme_activated_on_multiple_themes_created(self): @@ -65,7 +65,7 @@ class AdminInterfaceModelsTestCase(TestCase): theme_1 = Theme.objects.create(name="Custom 1", active=True) theme_2 = Theme.objects.create(name="Custom 2", active=True) theme_3 = Theme.objects.create(name="Custom 3", active=True) - self.assertEqual(Theme.get_active_theme().pk, theme_3.pk) + self.assertEqual(Theme.objects.get_active().pk, theme_3.pk) self.__test_active_theme() def test_last_theme_activated_on_multiple_themes_activated(self): @@ -80,15 +80,15 @@ class AdminInterfaceModelsTestCase(TestCase): random.shuffle(themes) for theme in themes: theme.set_active() - self.assertEqual(Theme.get_active_theme().pk, theme.pk) + self.assertEqual(Theme.objects.get_active().pk, theme.pk) self.__test_active_theme() def test_repr(self): - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() self.assertEqual(repr(theme), "") def test_str(self): - theme = Theme.get_active_theme() + theme = Theme.objects.get_active() self.assertEqual(str(theme), "Django") @@ -100,18 +100,18 @@ class AdminInterfaceModelsTestCase(TestCase): # Theme.objects.create(name="Change Active", active=True) # def test_get_theme_from_default_db(self): -# de_theme = Theme.get_active_theme() +# de_theme = Theme.objects.get_active() # assert de_theme.name == "Change Active" # def test_get_theme_from_replica_db(self): -# replica_theme = Theme.get_active_theme(database="replica") +# replica_theme = Theme.objects.get_active(database="replica") # assert replica_theme.name == "Django" # def test_db_are_isolated(self): -# default_theme = Theme.get_active_theme() -# replica_theme = Theme.get_active_theme(database="replica") +# default_theme = Theme.objects.get_active() +# replica_theme = Theme.objects.get_active(database="replica") # assert default_theme.name != replica_theme.name # @expectedFailure # def test_fail_for_wrong_db_defined_in_kwargs(self): -# Theme.get_active_theme(database="other") +# Theme.objects.get_active(database="other") diff --git a/tests/test_multidb.py b/tests/test_multidb.py index f5929b0..4b49489 100644 --- a/tests/test_multidb.py +++ b/tests/test_multidb.py @@ -25,7 +25,7 @@ class AdminInterfaceModelsWithDBRoutingTestCase(TestCase): def test_dbrouter_errors_when_fetching_from_default(self): with self.assertRaises(Exception): - Theme.get_active_theme() + Theme.objects.get_active() def test_dbrouter_fetches_db(self): DATABASE_APPS_MAPPING = { @@ -33,4 +33,4 @@ class AdminInterfaceModelsWithDBRoutingTestCase(TestCase): } router = DatabaseAppsRouter(db_map=DATABASE_APPS_MAPPING) with self.settings(DATABASE_ROUTERS=[router]): - Theme.get_active_theme() + Theme.objects.get_active()