From 88a0482838850ec866dcc2b23654af0ae0c2b176 Mon Sep 17 00:00:00 2001 From: Mira Weller Date: Fri, 25 Sep 2026 17:45:41 +0200 Subject: [PATCH] Move get_plugins, set_active_plugins, enable_plugin and disable_plugin into PluginsMixin --- src/pretix/base/models/base.py | 52 +++++++++++++++++++++++++++++ src/pretix/base/models/event.py | 51 ++-------------------------- src/pretix/base/models/organizer.py | 52 ++--------------------------- 3 files changed, 56 insertions(+), 99 deletions(-) diff --git a/src/pretix/base/models/base.py b/src/pretix/base/models/base.py index 64e37088f7..fc52d91737 100644 --- a/src/pretix/base/models/base.py +++ b/src/pretix/base/models/base.py @@ -274,3 +274,55 @@ class LockModel: field.delete_cached_value(self) self._state.db = db_instance._state.db + + +class PluginsMixin: + + def get_plugins(self): + """ + Returns the names of the plugins activated for this model as a list. + """ + if self.plugins is None: + return [] + return self.plugins.split(",") + + def set_active_plugins(self, modules, allow_restricted=frozenset()): + plugins_available = self.get_available_plugins() + plugins_current = set(self.get_plugins()) + plugins_new = set(modules) + + for module in plugins_new - plugins_current: + if module not in plugins_available: + continue + if getattr(plugins_available[module].app, 'restricted', False) and module not in allow_restricted: + modules.remove(module) + elif hasattr(plugins_available[module].app, 'installed'): + getattr(plugins_available[module].app, 'installed')(self) + + for module in plugins_current - plugins_new: + if module in plugins_available and hasattr(plugins_available[module].app, 'uninstalled'): + getattr(plugins_available[module].app, 'uninstalled')(self) + + self.plugins = ",".join(modules) + + def enable_plugin(self, module, allow_restricted=frozenset()): + """ + Adds a plugin to the list of plugins, calling its ``installed`` hook (if available). + It is the caller's responsibility to save the model object, as well as, in case of enabling + a hybrid organizer-event plugin on an event, to enable it on the organizer, if necessary. + """ + plugins_active = self.get_plugins() + if module not in plugins_active: + plugins_active.append(module) + self.set_active_plugins(plugins_active, allow_restricted=allow_restricted) + + def disable_plugin(self, module): + """ + Removes a plugin from the list of plugins, calling its ``uninstalled`` hook (if available). + It is the caller's responsibility to save the model object, as well as, in case of disabling + a hybrid organizer-event plugin on an organizer, to remove it from all events. + """ + plugins_active = self.get_plugins() + if module in plugins_active: + plugins_active.remove(module) + self.set_active_plugins(plugins_active) diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 39cda62954..63a16519b0 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -67,7 +67,7 @@ from django.utils.translation import gettext, gettext_lazy as _ from django_scopes import ScopedManager, scopes_disabled from i18nfield.fields import I18nCharField, I18nTextField -from pretix.base.models.base import LoggedModel +from pretix.base.models.base import LoggedModel, PluginsMixin from pretix.base.reldate import RelativeDateWrapper from pretix.base.timemachine import time_machine_now from pretix.base.validators import EventSlugBanlistValidator @@ -563,7 +563,7 @@ def default_sales_channels(): # kept for legacy migration @settings_hierarkey.add(parent_field='organizer', cache_namespace='event') -class Event(EventMixin, LoggedModel): +class Event(PluginsMixin, EventMixin, LoggedModel): """ This model represents an event. An event is anything you can buy tickets for. @@ -800,14 +800,6 @@ class Event(EventMixin, LoggedModel): self.cache.clear() return obj - def get_plugins(self): - """ - Returns the names of the plugins activated for this event as a list. - """ - if self.plugins is None: - return [] - return self.plugins.split(",") - def get_cache(self): """ Returns an :py:class:`ObjectRelatedCache` object. This behaves equivalent to @@ -1479,45 +1471,6 @@ class Event(EventMixin, LoggedModel): return get_all_plugins_map(event=self, only_visible=True) - def set_active_plugins(self, modules, allow_restricted=frozenset()): - plugins_available = self.get_available_plugins() - plugins_current = set(self.get_plugins()) - plugins_new = set(modules) - - for module in plugins_new - plugins_current: - if module not in plugins_available: - continue - if getattr(plugins_available[module].app, 'restricted', False) and module not in allow_restricted: - modules.remove(module) - elif hasattr(plugins_available[module].app, 'installed'): - getattr(plugins_available[module].app, 'installed')(self) - - for module in plugins_current - plugins_new: - if module in plugins_available and hasattr(plugins_available[module].app, 'uninstalled'): - getattr(plugins_available[module].app, 'uninstalled')(self) - - self.plugins = ",".join(modules) - - def enable_plugin(self, module, allow_restricted=frozenset()): - """ - Adds a plugin to the list of plugins, calling its ``installed`` hook (if available). - It is the caller's responsibility to save the event object. - """ - plugins_active = self.get_plugins() - if module not in plugins_active: - plugins_active.append(module) - self.set_active_plugins(plugins_active, allow_restricted=allow_restricted) - - def disable_plugin(self, module): - """ - Removes a plugin from the list of plugins, calling its ``uninstalled`` hook (if available). - It is the caller's responsibility to save the event object. - """ - plugins_active = self.get_plugins() - if module in plugins_active: - plugins_active.remove(module) - self.set_active_plugins(plugins_active) - @staticmethod def clean_has_subevents(event, has_subevents): if event is not None and event.has_subevents is not None: diff --git a/src/pretix/base/models/organizer.py b/src/pretix/base/models/organizer.py index b3ac5f0146..01b536b124 100644 --- a/src/pretix/base/models/organizer.py +++ b/src/pretix/base/models/organizer.py @@ -52,7 +52,7 @@ from django_scopes import ScopedManager, scope from i18nfield.fields import I18nCharField from i18nfield.strings import LazyI18nString -from pretix.base.models.base import LoggedModel +from pretix.base.models.base import LoggedModel, PluginsMixin from pretix.base.validators import OrganizerSlugBanlistValidator from ...helpers.permission_migration import ( @@ -67,7 +67,7 @@ if TYPE_CHECKING: @settings_hierarkey.add(cache_namespace='organizer') -class Organizer(LoggedModel): +class Organizer(PluginsMixin, LoggedModel): """ This model represents an entity organizing events, e.g. a company, institution, charity, person, … @@ -166,59 +166,11 @@ class Organizer(LoggedModel): return ObjectRelatedCache(self) - def get_plugins(self): - """ - Returns the names of the plugins activated for this organizer as a list. - """ - if not self.plugins: - return [] - return self.plugins.split(",") - def get_available_plugins(self): from pretix.base.plugins import get_all_plugins_map return get_all_plugins_map(organizer=self, only_visible=True) - def set_active_plugins(self, modules, allow_restricted=frozenset()): - plugins_available = self.get_available_plugins() - plugins_current = set(self.get_plugins()) - plugins_new = set(modules) - - for module in plugins_new - plugins_current: - if module not in plugins_available: - continue - if getattr(plugins_available[module].app, 'restricted', False) and module not in allow_restricted: - modules.remove(module) - elif hasattr(plugins_available[module].app, 'installed'): - getattr(plugins_available[module].app, 'installed')(self) - - for module in plugins_current - plugins_new: - if module in plugins_available and hasattr(plugins_available[module].app, 'uninstalled'): - getattr(plugins_available[module].app, 'uninstalled')(self) - - self.plugins = ",".join(modules) - - def enable_plugin(self, module, allow_restricted=frozenset()): - """ - Adds a plugin to the list of plugins, calling its ``installed`` hook (if available). - It is the caller's responsibility to save the organizer object. - """ - plugins_active = self.get_plugins() - if module not in plugins_active: - plugins_active.append(module) - self.set_active_plugins(plugins_active, allow_restricted=allow_restricted) - - def disable_plugin(self, module): - """ - Removes a plugin from the list of plugins, calling its ``uninstalled`` hook (if available). - It is the caller's responsibility to save the organizer object and, in case of a hybrid organizer-event plugin, - to remove it from all events. - """ - plugins_active = self.get_plugins() - if module in plugins_active: - plugins_active.remove(module) - self.set_active_plugins(plugins_active) - @property def timezone(self): return pytz_deprecation_shim.timezone(self.settings.timezone)