Store feature flags persistent into Django cache/database.
All flags will be stored to cache and database and only on cache miss fetched again from database.
There is optional a Admin Extra Views base class to manage all flags in the admin.
Change your settings
, e.g.:
INSTALLED_APPS = [
# ...
'bx_django_utils.feature_flags.apps.FeatureFlagsAppConfig',
# ...
]
Define somewhere a flag, e.g.:
from bx_django_utils.feature_flags.data_classes import FeatureFlag
foo_feature_flag = FeatureFlag(
cache_key='foo',
human_name='Foo',
description='This is a feature flag',
initial_enabled=True,
)
Use this flag somewhere, e.g.:
from my_flags import foo_feature_flag
def my_view(request):
if not foo_feature_flag.is_enabled:
raise NotImplemented
#...
To manage all feature flags in the admin: Register ManageFeatureFlagsBaseView
admin extra view, e.g.:
from bx_django_utils.admin_extra_views.datatypes import AdminExtraMeta, PseudoApp
from bx_django_utils.admin_extra_views.registry import register_admin_view
from bx_django_utils.feature_flags.admin_views import ManageFeatureFlagsBaseView
def can_manage_feature_flags(request):
if request.user.is_superuser:
return True
return False
manage_flags_app = PseudoApp(
meta=AdminExtraMeta(
name='Feature Flags',
app_label='feature_flags',
conditions={can_manage_feature_flags},
)
)
@register_admin_view(pseudo_app=manage_flags_app)
class ManageFeatureFlagsAdminExtraView(ManageFeatureFlagsBaseView):
pass
By default, each time the flags state is evaluated (e.g. when calling foo_feature_flag.is_enabled()
), the flag state is fetched from the database. This may cause poor performance in hot code paths.
You can limit this evaluation to once per n seconds by passing the cache_duration=timedelta(seconds=n)
argument to the FeatureFlag
constructor.