Skip to content
Snippets Groups Projects
Verified Commit 8bd1b47e authored by Nik | Klampfradler's avatar Nik | Klampfradler
Browse files

Add general signal interface for default data maintenance

This change is primarily intended to allow models to declare their own
default data, without having to use data migrations. Data migrations
have the downside of being run only once, so e.g. `manage.py flush` will
delete default data wchich will never be restored. Also, I consider it
more natural todefine default data setup on model classes.

In order to achieve that, this adds a generic interface for apps to
register hooks called on several signals, by simply implementing methods
with the same name on their AppConfig instance.
parent 3da5e898
No related branches found
No related tags found
1 merge request!154Maintain default data and implement app hooks
from django.apps import AppConfig, apps
from constance.signals import config_updated
from .signals import clean_scss
from .util.apps import AppConfig
class CoreConfig(AppConfig):
......@@ -10,5 +7,7 @@ class CoreConfig(AppConfig):
verbose_name = "AlekSIS — The Free School Information System"
def ready(self) -> None:
super().ready()
def config_updated(self, *args, **kwargs) -> None:
clean_scss()
config_updated.connect(clean_scss)
from importlib import import_module
from typing import Any, Optional
import django.apps
from django.db.models.signals import post_migrate, pre_migrate
from constance.signals import config_updated
class AppConfig(django.apps.AppConfig):
......@@ -17,3 +21,64 @@ class AppConfig(django.apps.AppConfig):
except ImportError:
# ImportErrors are non-fatal because model extensions are optional.
pass
# Register default listeners
pre_migrate.connect(self.pre_migrate, sender=self)
post_migrate.connect(self.post_migrate, sender=self)
config_updated.connect(self.config_updated)
# Getting an app ready means it should look at its config once
self.config_updated()
def config_updated(
self,
key: Optional[str] = "",
old_value: Optional[Any] = None,
new_value: Optional[Any] = None,
**kwargs
) -> None:
""" Called on every app instance if a Constance config chagnes, and once on startup
By default, it does nothing.
"""
pass
def pre_migrate(
self,
app_config: django.apps.AppConfig,
verbosity: int,
interactive: bool,
using: str,
plan: List[Tuple],
apps: django.apps.Apps,
) -> None:
""" Called on every app instance before its models are migrated
By default, it does nothing.
"""
pass
def post_migrate(
self,
app_config: django.apps.AppConfig,
verbosity: int,
interactive: bool,
using: str,
plan: List[Tuple],
apps: django.apps.Apps,
) -> None:
""" Called on every app instance after its models have been migrated
By default, asks all models to do maintenance on their default data.
"""
self._maintain_default_data()
def _maintain_default_data(self):
if not self.models_module:
# This app does not have any models, so bail out early
return
for model in self.get_models():
if hasattr(model, "maintain_default_data"):
# Method implemented by each model object; can be left out
model.maintain_default_data()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment