When I start developing with Django, create a reusable APP and install it in another project, I can't change the default settings set in the APP ... So I was looking for a way to change the settings for each application from ** project / settings.py **. There was good code in ** Django Rest Framework **, so I tried it as a reference.
Let's take a simple ** Todo Task Api ** as an example.
Working sample Repository is here
project/settings.py
...
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 10
}
...
I changed it like this. Now you can change PAGE_SIZE when using Pagination.
Let's take a look at a really simple example of how it works with the Todo Task API.
** Model ** is only the following Task.
todo_api/models.py
from django.db import models
from .settings import api_settings
class Task(models.Model):
title = models.CharField(max_length=api_settings.TASK_TITLE_MAX_LENGTH)
status = models.IntegerField(choices=api_settings.TASK_STATUS_CHOICES)
** todo_api.settings.api_settings ** is the instance that can refer to the setting value of APP. You can get the value with ** api_settings.KEY **. In this example, the following two can be changed in settings.py.
For example, assume that the default setting value of ** TASK_STATUS_CHOICES ** is set as follows in todo_api / settings.py.
todo_api/settings.py
DEFAULTS = {
'TASK_TITLE_MAX_LENGTH': 30,
'TASK_STATUS_CHOICES': [
(1, 'TODO'),
(2, 'DOING'),
(3, 'DONE'),
]
}
...
If you want to change this, you can change it by changing project / settings.py.
project/settings.py
...
TODO_API = {
'TASK_STATUS_CHOICES': [
(1, 'TODO'),
(2, 'DOING'),
(3, 'DONE'),
(4, 'NEW_STATUS'),
],
}
You can add ** NEW_STATUS ** to the task status choices by adding the above code. Let's actually look at the detailed code.
I created the ** APISettings ** class in a very simplified way with reference to ** Django Rest Framework **.
utils/api_settings.py
from django.conf import settings
class APISettings:
"""
A settings object, that allows API settings to be accessed as properties.
Set default settings in your app settings.py like this:
from app_utils.setting import APISettings
api_settings = APISettings('TODO_API', DEFAULTS)
For example:
from todo_api.settings import api_settings
print(api_settings.TASK_STATUS_CHOICES)
"""
def __init__(self, setting_root_name, defaults):
self._setting_root_name = setting_root_name
self._defaults = defaults
self._user_settings = getattr(settings, self._setting_root_name, {})
def __getattr__(self, item):
if item not in self._defaults:
raise AttributeError("Invalid {} setting: {}".format(self._setting_root_name, item))
try:
return self._user_settings[item]
except KeyError:
return self._defaults[item]
It is important to use the getattr method. This will allow you to access your settings with api_settings.KEY. ** self._user_settings ** is assigned the value below ** setting_root_name ** set in project / settings.py.
Now, let's use the ** API Settings ** created earlier to ** create a configuration instance for TODO APP **.
todo_api/settings.py
from utils.app_setting import APISettings
DEFAULTS = {
'TASK_TITLE_MAX_LENGTH': 30,
'TASK_STATUS_CHOICES': [
(1, 'TODO'),
(2, 'DOING'),
(3, 'DONE'),
],
}
api_settings = APISettings('TODO_API', DEFAULTS)
Generate by passing ** the root name of the setting ** as the first argument of APISettings and ** the default setting value ** as the second argument.
This completes the settings.
To use the settings for TODO_API created earlier, just import and access.
todo_api/models.py
from .settings import api_settings
print(api_settings.TASK_TITLE_MAX_LENGTH)
# > 30
Now you can change the settings of the packaged APP from settings.py on the Project side. As a flow,
that's all.
Working sample Repository is here
Have a good Django life!