{"id":13415608,"url":"https://github.com/fabiocaccamo/django-extra-settings","last_synced_at":"2025-05-14T13:05:46.133Z","repository":{"id":37841040,"uuid":"239991252","full_name":"fabiocaccamo/django-extra-settings","owner":"fabiocaccamo","description":":gear: config and manage typed extra settings using just the django admin.","archived":false,"fork":false,"pushed_at":"2025-05-05T16:58:31.000Z","size":244,"stargazers_count":581,"open_issues_count":8,"forks_count":33,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-05T18:03:59.770Z","etag":null,"topics":["admin","conf","config","constance","custom","django","dynamic","extra","management","options","preferences","settings","typed"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fabiocaccamo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["fabiocaccamo"],"polar":"fabiocaccamo","ko_fi":"fabiocaccamo","liberapay":"fabiocaccamo","tidelift":"pypi/django-extra-settings","custom":["https://www.buymeacoffee.com/fabiocaccamo","https://www.paypal.me/fabiocaccamo"]}},"created_at":"2020-02-12T10:59:54.000Z","updated_at":"2025-05-03T11:09:33.000Z","dependencies_parsed_at":"2023-09-28T22:20:41.113Z","dependency_job_id":"a07804b7-cf0f-4764-a1d2-9de0d2c9dfbb","html_url":"https://github.com/fabiocaccamo/django-extra-settings","commit_stats":{"total_commits":315,"total_committers":12,"mean_commits":26.25,"dds":"0.30793650793650795","last_synced_commit":"a82271cde8c30cf7f6b683573b4b19610d8d1a75"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiocaccamo%2Fdjango-extra-settings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiocaccamo%2Fdjango-extra-settings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiocaccamo%2Fdjango-extra-settings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fabiocaccamo%2Fdjango-extra-settings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fabiocaccamo","download_url":"https://codeload.github.com/fabiocaccamo/django-extra-settings/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254149917,"owners_count":22022851,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","conf","config","constance","custom","django","dynamic","extra","management","options","preferences","settings","typed"],"created_at":"2024-07-30T21:00:50.710Z","updated_at":"2025-05-14T13:05:46.104Z","avatar_url":"https://github.com/fabiocaccamo.png","language":"Python","funding_links":["https://github.com/sponsors/fabiocaccamo","https://polar.sh/fabiocaccamo","https://ko-fi.com/fabiocaccamo","https://liberapay.com/fabiocaccamo","https://tidelift.com/funding/github/pypi/django-extra-settings","https://www.buymeacoffee.com/fabiocaccamo","https://www.paypal.me/fabiocaccamo"],"categories":["Third-Party Packages","Python"],"sub_categories":["Configuration"],"readme":"[![](https://img.shields.io/pypi/pyversions/django-extra-settings.svg?color=3776AB\u0026logo=python\u0026logoColor=white)](https://www.python.org/)\n[![](https://img.shields.io/pypi/djversions/django-extra-settings?color=0C4B33\u0026logo=django\u0026logoColor=white\u0026label=django)](https://www.djangoproject.com/)\n\n[![](https://img.shields.io/pypi/v/django-extra-settings.svg?color=blue\u0026logo=pypi\u0026logoColor=white)](https://pypi.org/project/django-extra-settings/)\n[![](https://static.pepy.tech/badge/django-extra-settings/month)](https://pepy.tech/project/django-extra-settings)\n[![](https://img.shields.io/github/stars/fabiocaccamo/django-extra-settings?logo=github\u0026style=flat)](https://github.com/fabiocaccamo/django-extra-settings/stargazers)\n[![](https://img.shields.io/pypi/l/django-extra-settings.svg?color=blue)](https://github.com/fabiocaccamo/django-extra-settings/blob/main/LICENSE.txt)\n\n[![](https://results.pre-commit.ci/badge/github/fabiocaccamo/django-extra-settings/main.svg)](https://results.pre-commit.ci/latest/github/fabiocaccamo/django-extra-settings/main)\n[![](https://img.shields.io/github/actions/workflow/status/fabiocaccamo/django-extra-settings/test-package.yml?branch=main\u0026label=build\u0026logo=github)](https://github.com/fabiocaccamo/django-extra-settings)\n[![](https://img.shields.io/codecov/c/gh/fabiocaccamo/django-extra-settings?logo=codecov)](https://codecov.io/gh/fabiocaccamo/django-extra-settings)\n[![](https://img.shields.io/codacy/grade/554c0505ed9844f3865bee975d1b894c?logo=codacy)](https://www.codacy.com/app/fabiocaccamo/django-extra-settings)\n[![](https://img.shields.io/codeclimate/maintainability/fabiocaccamo/django-extra-settings?logo=code-climate)](https://codeclimate.com/github/fabiocaccamo/django-extra-settings/)\n[![](https://img.shields.io/badge/code%20style-black-000000.svg?logo=python\u0026logoColor=black)](https://github.com/psf/black)\n[![](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n\n# django-extra-settings\nconfig and manage typed extra settings using just the django admin.\n\n![](https://user-images.githubusercontent.com/1035294/74425761-81325400-4e54-11ea-9095-3d64e1420bfe.gif)\n\n## Installation\n-   Run `pip install django-extra-settings`\n-   Add `extra_settings` to `settings.INSTALLED_APPS`\n-   Run `python manage.py migrate`\n-   Run `python manage.py collectstatic`\n-   Restart your application server\n-   Just go to the admin where you can `create`, `update` and `delete` your settings.\n\n## Usage\n\n### Settings\nAll these settings are optional, if not defined in `settings.py` the default values (listed below) will be used.\n\n```python\n# the name of the installed app for registering the extra settings admin.\nEXTRA_SETTINGS_ADMIN_APP = \"extra_settings\"\n```\n\n```python\n# the name of the cache to use, if not found the \"default\" cache will be used.\nEXTRA_SETTINGS_CACHE_NAME = \"extra_settings\"\n```\n\n```python\n# a list of settings that will be available by default, each item must contain \"name\", \"type\" and \"value\".\n# check the #types section to see all the supported settings types.\nEXTRA_SETTINGS_DEFAULTS = [\n    {\n        \"name\": \"SETTING_NAME\",\n        \"type\": \"string\",\n        \"value\": \"Hello World\",\n    },\n    # ...\n]\n```\n\n```python\n# if True, settings names will be forced to honor the standard django settings format\nEXTRA_SETTINGS_ENFORCE_UPPERCASE_SETTINGS = True\n```\n\n```python\n# if True, the template tag will fallback to django.conf.settings,\n# very useful to retrieve conf settings such as DEBUG.\nEXTRA_SETTINGS_FALLBACK_TO_CONF_SETTINGS = True\n```\n\n```python\n# the upload_to path value of settings of type 'file'\nEXTRA_SETTINGS_FILE_UPLOAD_TO = \"files\"\n```\n\n```python\n# the upload_to path value of settings of type 'image'\nEXTRA_SETTINGS_IMAGE_UPLOAD_TO = \"images\"\n```\n\n```python\n# if True, settings name prefix list filter will be shown in the admin changelist\nEXTRA_SETTINGS_SHOW_NAME_PREFIX_LIST_FILTER = False\n```\n\n```python\n# if True, settings type list filter will be shown in the admin changelist\nEXTRA_SETTINGS_SHOW_TYPE_LIST_FILTER = False\n```\n\n```python\n# the package name displayed in the admin\nEXTRA_SETTINGS_VERBOSE_NAME = \"Settings\"\n```\n\n### Celery\n\u003e [!WARNING]\n\u003e When using **Celery**'s `autodiscover_tasks` with `force=True`, it triggers an aggressive task discovery that accesses Django settings before they're fully initialized. This premature access prevents `django-extra-settings` from properly setting up its default configuration values. More info [here](https://github.com/fabiocaccamo/django-extra-settings/issues/177).\n\n### Admin\nYou can display the settings model admin in another installed app group by using the `EXTRA_SETTINGS_ADMIN_APP` setting.\n\nYou can also have a more advanced control, by registering the settings admin with multiple installed apps and filtering each app settings using the `queryset_processor` argument.\n\n\u003e :warning: If you do either of the above, you must run migrations for each app that will display `extra_settings` model admin in its admin *(because django creates migrations even for proxy models)*.\n\n#### Admin advanced configuration example\n\nIn your custom app `photos.admin` module:\n```python\nfrom extra_settings.admin import register_extra_settings_admin\n\nregister_extra_settings_admin(\n    app=__name__,\n    queryset_processor=lambda qs: qs.filter(name__istartswith=\"PHOTOS_\"),\n    unregister_default=True,\n)\n```\n\nIn your custom app `videos.admin` module:\n```python\nfrom extra_settings.admin import register_extra_settings_admin\n\nregister_extra_settings_admin(\n    app=__name__,\n    queryset_processor=lambda qs: qs.filter(name__istartswith=\"VIDEOS_\"),\n    unregister_default=True,\n)\n```\n\nBy default the `\"extra_settings\"` app has its own admin app group.\n\n\n\n### Caching\nYou can customise the app caching options using `settings.CACHES[\"extra_settings\"]` setting, otherwise the `\"default\"` cache will be used:\n\n```python\nCACHES = {\n    # ...\n    \"extra_settings\": {\n        \"BACKEND\": \"django.core.cache.backends.locmem.LocMemCache\",\n        \"TIMEOUT\": 60,\n    },\n    # ...\n}\n```\n\nBy default the `\"extra_settings\"` cache is used, if you want to use another cache you can set it using the `EXTRA_SETTINGS_CACHE_NAME` setting.\n\n### Python\nYou can **create**, **read**, **update** and **delete** settings programmatically:\n\n#### Types\nThis is the list of the currently supported setting types you may need to use:\n\n-   `Setting.TYPE_BOOL`\n-   `Setting.TYPE_DATE`\n-   `Setting.TYPE_DATETIME`\n-   `Setting.TYPE_DECIMAL`\n-   `Setting.TYPE_DURATION`\n-   `Setting.TYPE_EMAIL`\n-   `Setting.TYPE_FILE`\n-   `Setting.TYPE_FLOAT`\n-   `Setting.TYPE_IMAGE`\n-   `Setting.TYPE_INT`\n-   `Setting.TYPE_JSON`\n-   `Setting.TYPE_STRING`\n-   `Setting.TYPE_TEXT`\n-   `Setting.TYPE_TIME`\n-   `Setting.TYPE_URL`\n\n#### Create\n```python\nfrom extra_settings.models import Setting\n\nsetting_obj = Setting(\n    name=\"SETTING_NAME\",\n    value_type=Setting.TYPE_STRING,\n    value=\"django-extra-settings\",\n)\nsetting_obj.save()\n```\n\n#### Read\n```python\nfrom extra_settings.models import Setting\n\nvalue = Setting.get(\"SETTING_NAME\", default=\"django-extra-settings\")\n```\n\n#### Update\n```python\nfrom extra_settings.models import Setting\n\nsetting_obj = Setting(\n    name=\"SETTING_NAME\",\n    value_type=Setting.TYPE_BOOL,\n    value=True,\n)\nsetting_obj.value = False\nsetting_obj.save()\n```\n\n#### Delete\n```python\nfrom extra_settings.models import Setting\n\nSetting.objects.filter(name=\"SETTING_NAME\").delete()\n```\n\n#### Validators\nYou can define a custom validator for each setting:\n-   Validators must be defined using full python path, eg. `myapp.mymodule.my_validator`.\n-   Validators are called passing a single argument (the value of the setting) and if the value is valid, they should return `True`, otherwise returning `False` or `None` a `ValidationError` is raised.\n\n### Templates\nYou can retrieve settings in templates:\n```html\n{% load extra_settings %}\n\n{% get_setting 'SETTING_NAME' default='django-extra-settings' %}\n```\n\n### Tests\nYou can override specific settings during tests using `extra_settings.test.override_settings`.\n\nIt can be used both as decorator and as context-manager:\n```python\nfrom extra_settings.test import override_settings\n\n# decorator\n@override_settings(SETTING_NAME_1=\"value for testing 1\", SETTING_NAME_2=\"value for testing 2\")\ndef test_with_custom_settings(self):\n    pass\n\n# context manager\ndef test_with_custom_settings(self):\n    with override_settings(SETTING_NAME_1=\"value for testing 1\", SETTING_NAME_2=\"value for testing 2\"):\n        pass\n```\n\n## Testing\n```bash\n# clone repository\ngit clone https://github.com/fabiocaccamo/django-extra-settings.git \u0026\u0026 cd django-extra-settings\n\n# create virtualenv and activate it\npython -m venv venv \u0026\u0026 . venv/bin/activate\n\n# upgrade pip\npython -m pip install --upgrade pip\n\n# install requirements\npip install -r requirements.txt -r requirements-test.txt\n\n# install pre-commit to run formatters and linters\npre-commit install --install-hooks\n\n# run tests\ntox\n# or\npython runtests.py\n# or\npython -m django test --settings \"tests.settings\"\n```\n\n## License\nReleased under [MIT License](LICENSE.txt).\n\n---\n\n## Supporting\n\n- :star: Star this project on [GitHub](https://github.com/fabiocaccamo/django-extra-settings)\n- :octocat: Follow me on [GitHub](https://github.com/fabiocaccamo)\n- :blue_heart: Follow me on [Twitter](https://twitter.com/fabiocaccamo)\n- :moneybag: Sponsor me on [Github](https://github.com/sponsors/fabiocaccamo)\n\n## See also\n\n- [`django-admin-interface`](https://github.com/fabiocaccamo/django-admin-interface) - the default admin interface made customizable by the admin itself. popup windows replaced by modals. 🧙 ⚡\n\n- [`django-cache-cleaner`](https://github.com/fabiocaccamo/django-cache-cleaner) - clear the entire cache or individual caches easily using the admin panel or management command. 🧹✨\n\n- [`django-colorfield`](https://github.com/fabiocaccamo/django-colorfield) - simple color field for models with a nice color-picker in the admin. 🎨\n\n- [`django-maintenance-mode`](https://github.com/fabiocaccamo/django-maintenance-mode) - shows a 503 error page when maintenance-mode is on. 🚧 🛠️\n\n- [`django-redirects`](https://github.com/fabiocaccamo/django-redirects) - redirects with full control. ↪️\n\n- [`django-treenode`](https://github.com/fabiocaccamo/django-treenode) - probably the best abstract model / admin for your tree based stuff. 🌳\n\n- [`python-benedict`](https://github.com/fabiocaccamo/python-benedict) - dict subclass with keylist/keypath support, I/O shortcuts (base64, csv, json, pickle, plist, query-string, toml, xml, yaml) and many utilities. 📘\n\n- [`python-codicefiscale`](https://github.com/fabiocaccamo/python-codicefiscale) - encode/decode Italian fiscal codes - codifica/decodifica del Codice Fiscale. 🇮🇹 💳\n\n- [`python-fontbro`](https://github.com/fabiocaccamo/python-fontbro) - friendly font operations. 🧢\n\n- [`python-fsutil`](https://github.com/fabiocaccamo/python-fsutil) - file-system utilities for lazy devs. 🧟‍♂️\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiocaccamo%2Fdjango-extra-settings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffabiocaccamo%2Fdjango-extra-settings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffabiocaccamo%2Fdjango-extra-settings/lists"}