# Django Dynamic Settings
[![Build status](https://img.shields.io/bitbucket/pipelines/akinonteam/dj-dynamic-settings)](https://bitbucket.org/akinonteam/dj-dynamic-settings/addon/pipelines/home)
![PyPI](https://img.shields.io/pypi/v/dj-dynamic-settings)
![PyPI - Django version](https://img.shields.io/pypi/djversions/dj-dynamic-settings)
![PyPI - Python version](https://img.shields.io/pypi/pyversions/dj-dynamic-settings)
![PyPI - License](https://img.shields.io/pypi/l/dj-dynamic-settings)
Django Dynamic Settings allows you to create & use dynamic settings backed by a database.
## Installation
Installation using pip:
```
pip install dj-dynamic-settings
```
`dj_dynamic_settings` app has to be added to `INSTALLED_APPS` and `migrate` command has to be run.
```python
INSTALLED_APPS = (
# other apps here...
"dj_dynamic_settings",
)
```
`dj_dynamic_settings.urls` must be included to a desired url path.
```python
urlpatterns = [
...,
url(r"^api/v1/", include("dj_dynamic_settings.urls")),
]
```
Setting class must be defined & registered. Please make sure that this class' module
runs whenever the application runs.
```python
from dj_dynamic_settings.registry import BaseSetting, registry
from dj_dynamic_settings.validators import TypeValidator
@registry.register
class FeatureActive(BaseSetting):
key = "FEATURE_ACTIVE"
validators = [TypeValidator(bool)]
default = False
description = "Flag for Feature X"
```
Create `Setting` instance using view.
```python
import requests
requests.post(
url="https://your-app.com/api/v1/dynamic_settings/",
headers={
"Authorization": "Token <secret-login-token>",
},
json={
"key": "FEATURE_ACTIVE",
"value": True,
"is_active": True,
}
)
```
Access this setting as in `django.conf.settings`
```python
from dj_dynamic_settings.conf import settings
settings.FEATURE_ACTIVE # True
```
### Create / Update Triggers
To fire a callback method when a specific setting value updated or created, you can implement `post_save_actions` in `BaseSetting` inherited class
Following example shows how to implement `post_save_actions` method.
The callback method will be called with following kwargs:
```
key=instance.key
value=instance.value
created=created # is create operation
```
Note: `post_save_actions` returns an array, so you can add multiple callback methods. These callback methods will be called synchronously.
```python
class PostUpdateTestConfiguration(BaseSetting):
key = "X_FEATURE_POST_UPDATE"
validators = [...]
@classmethod
def post_save_actions(cls):
return [
on_data_updated,
]
def on_data_updated(*args, **kwargs):
pass
```
### Testing Tools
#### override_settings()
You can override a setting for a test method or test class.
```python
from dj_dynamic_settings.utils import override_settings
from django.test import TestCase
@override_settings(SOME_SETTING="some_setting")
class FeatureTestCase(TestCase):
@override_settings(SOME_OTHER_SETTING="SOME_OTHER_SETTING")
def test_feature(self):
# Some stuff
pass
def test_feature_x(self):
with override_settings(SOME_OTHER_SETTING="SOME_OTHER_SETTING"):
# Some stuff
pass
```
Raw data
{
"_id": null,
"home_page": "https://bitbucket.org/akinonteam/dj-dynamic-settings/",
"name": "dj-dynamic-settings",
"maintainer": "Akinon",
"docs_url": null,
"requires_python": "",
"maintainer_email": "dev@akinon.com",
"keywords": "",
"author": "Akinon",
"author_email": "dev@akinon.com",
"download_url": "https://files.pythonhosted.org/packages/e5/06/a0216c769fdf22c36cc26e2901d00261a586fa638a681ea2a7dbde105040/dj-dynamic-settings-0.2.4.tar.gz",
"platform": "any",
"description": "# Django Dynamic Settings\n\n[![Build status](https://img.shields.io/bitbucket/pipelines/akinonteam/dj-dynamic-settings)](https://bitbucket.org/akinonteam/dj-dynamic-settings/addon/pipelines/home)\n![PyPI](https://img.shields.io/pypi/v/dj-dynamic-settings)\n![PyPI - Django version](https://img.shields.io/pypi/djversions/dj-dynamic-settings)\n![PyPI - Python version](https://img.shields.io/pypi/pyversions/dj-dynamic-settings)\n![PyPI - License](https://img.shields.io/pypi/l/dj-dynamic-settings)\n\nDjango Dynamic Settings allows you to create & use dynamic settings backed by a database.\n\n## Installation\n\nInstallation using pip:\n\n```\npip install dj-dynamic-settings\n```\n\n`dj_dynamic_settings` app has to be added to `INSTALLED_APPS` and `migrate` command has to be run.\n\n```python\nINSTALLED_APPS = (\n # other apps here...\n \"dj_dynamic_settings\",\n)\n```\n\n`dj_dynamic_settings.urls` must be included to a desired url path.\n```python\nurlpatterns = [\n ...,\n url(r\"^api/v1/\", include(\"dj_dynamic_settings.urls\")),\n]\n```\n\nSetting class must be defined & registered. Please make sure that this class' module \nruns whenever the application runs.\n```python\nfrom dj_dynamic_settings.registry import BaseSetting, registry\nfrom dj_dynamic_settings.validators import TypeValidator\n\n\n@registry.register\nclass FeatureActive(BaseSetting):\n key = \"FEATURE_ACTIVE\"\n validators = [TypeValidator(bool)]\n default = False\n description = \"Flag for Feature X\"\n```\n\nCreate `Setting` instance using view.\n\n```python\nimport requests\n\nrequests.post(\n url=\"https://your-app.com/api/v1/dynamic_settings/\",\n headers={\n \"Authorization\": \"Token <secret-login-token>\",\n },\n json={\n \"key\": \"FEATURE_ACTIVE\",\n \"value\": True,\n \"is_active\": True,\n }\n)\n```\n\nAccess this setting as in `django.conf.settings`\n\n```python\nfrom dj_dynamic_settings.conf import settings\n\n\nsettings.FEATURE_ACTIVE # True\n```\n\n### Create / Update Triggers\n\nTo fire a callback method when a specific setting value updated or created, you can implement `post_save_actions` in `BaseSetting` inherited class\n\nFollowing example shows how to implement `post_save_actions` method.\n\nThe callback method will be called with following kwargs: \n\n```\nkey=instance.key\nvalue=instance.value\ncreated=created # is create operation\n```\n\nNote: `post_save_actions` returns an array, so you can add multiple callback methods. These callback methods will be called synchronously. \n\n```python\nclass PostUpdateTestConfiguration(BaseSetting):\n key = \"X_FEATURE_POST_UPDATE\"\n validators = [...]\n\n @classmethod\n def post_save_actions(cls):\n return [\n on_data_updated,\n ]\n\ndef on_data_updated(*args, **kwargs):\n pass\n```\n\n\n### Testing Tools\n\n#### override_settings()\n\nYou can override a setting for a test method or test class.\n\n```python\nfrom dj_dynamic_settings.utils import override_settings\nfrom django.test import TestCase\n\n@override_settings(SOME_SETTING=\"some_setting\")\nclass FeatureTestCase(TestCase):\n\n @override_settings(SOME_OTHER_SETTING=\"SOME_OTHER_SETTING\")\n def test_feature(self):\n # Some stuff\n pass\n\n \n def test_feature_x(self):\n with override_settings(SOME_OTHER_SETTING=\"SOME_OTHER_SETTING\"):\n # Some stuff\n pass\n```\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Stay informed of it",
"version": "0.2.4",
"project_urls": {
"Documentation": "https://bitbucket.org/akinonteam/dj-dynamic-settings/",
"Homepage": "https://bitbucket.org/akinonteam/dj-dynamic-settings/",
"Source Code": "https://bitbucket.org/akinonteam/dj-dynamic-settings/"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "bd950a88508ef70e9f766d396004775a951632aff3acf6300bd4027038929239",
"md5": "d15b2e35ac6c53d3d10c6792488842e2",
"sha256": "2dd7c8cd020e707e10c7e2293831b6857cad719dfee40248a081dc2504396f04"
},
"downloads": -1,
"filename": "dj_dynamic_settings-0.2.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d15b2e35ac6c53d3d10c6792488842e2",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 12580,
"upload_time": "2023-11-27T11:17:57",
"upload_time_iso_8601": "2023-11-27T11:17:57.887928Z",
"url": "https://files.pythonhosted.org/packages/bd/95/0a88508ef70e9f766d396004775a951632aff3acf6300bd4027038929239/dj_dynamic_settings-0.2.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e506a0216c769fdf22c36cc26e2901d00261a586fa638a681ea2a7dbde105040",
"md5": "2082de8e65dbed266925a7cb4df5b146",
"sha256": "4374bd00e8c3b7837b76fd33dec8948b391cedc0924be85bfb1fe4f84bcc371e"
},
"downloads": -1,
"filename": "dj-dynamic-settings-0.2.4.tar.gz",
"has_sig": false,
"md5_digest": "2082de8e65dbed266925a7cb4df5b146",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 15022,
"upload_time": "2023-11-27T11:17:59",
"upload_time_iso_8601": "2023-11-27T11:17:59.432070Z",
"url": "https://files.pythonhosted.org/packages/e5/06/a0216c769fdf22c36cc26e2901d00261a586fa638a681ea2a7dbde105040/dj-dynamic-settings-0.2.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-11-27 11:17:59",
"github": false,
"gitlab": false,
"bitbucket": true,
"codeberg": false,
"bitbucket_user": "akinonteam",
"bitbucket_project": "dj-dynamic-settings",
"lcname": "dj-dynamic-settings"
}