Django-constance实现动态设置
本文基于 django-constance==2.2.0
安装
django-constance
分为redis
存储设置的版本和使用database
存储设置的版本,对应的下载方式分别为:
如果确认相关依赖已经安装,直接使用下列命令安装:
配置
settings.py文件
:
若使用database
存储设置的版本,请使用:
声明待配置选项:
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
CONSTANCE_IGNORE_ADMIN_VERSION_CHECK = True
CONSTANCE_ADDITIONAL_FIELDS = {
'coupon_select': ['django.forms.fields.ChoiceField', {
'widget': 'django.forms.Select',
'choices': ((0, "时+分+秒"), (1, "时+分"), (2, "时"), (3, "忽略"))
}],
}
CONSTANCE_CONFIG = {
'site_name': ('南京诗远启', '网站标题'),
'site_description': ('南京诗远启', '站点描述'),
'coupon_fix_code': ('DreamGo', '电子券固定代码'),
'coupon_time_format': (0, '电子券时间格式', 'coupon_select'),
'sms_reset_date': (1, '分配短信清零时间'),
}
CONSTANCE_CONFIG_FIELDSETS = {
'站点设置': ('site_name', 'site_description'),
'电子券': ('coupon_fix_code', 'coupon_time_format', ),
'短信': ('sms_reset_date', ),
}
'site_name': ('南京诗远启', '网站标题'),
分别代表 设置变量的名称 默认值 设置变量用途描述(help_text
)
'coupon_time_format': (0, '电子券时间格式', 'coupon_select'),
前3个变量意义同上,最后的'coupon_select'
代表使用自定义选择控件来选择值。
Admin样式
使用代码获取当前设置值
from constance import config
def set_value(key, value):
"""
更新数据库设置项
:param key: 键名
:param value: 值
:return: 无返回
"""
setattr(config, key, value)
def get_value(key):
"""
获取数据库设置项值
:param key: 键名
:return: 键名对应的设置项值
"""
return getattr(config, key)
用法:
DjangoRestFramework中使用
utils.py:
from constance import config
from constance.settings import CONFIG
def get_settings(allow_settings):
"""
获取对应settings组成的list
:param allow_settings: 待转义列表
:return: 对应settings组成的list
"""
setting_list = []
for key, options in CONFIG.items():
if key in allow_settings:
default, help_text = options[0], options[1]
data = {'key': key, 'default': default, 'help_text': help_text, 'value': get_value(key)}
setting_list.append(data)
return setting_list
views.py:
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from .utils import set_value, get_value, CONFIG
class SettingViewSet(ViewSet):
permission_classes = (IsAuthenticated,)
def setting(self, request, allow_settings):
if request.method == 'GET':
return Response(data=get_settings(allow_settings), status=status.HTTP_200_OK)
else:
all_settings = CONFIG.keys()
for key in request.data:
if key in allow_settings and key in all_settings:
value = request.data[key]
set_value(key, '' if value is None else value)
return Response(data=get_settings(allow_settings), status=status.HTTP_200_OK)
def create(self, request):
"""
<p>更新设置POST:<code>{'设置Key': 新值}</code>
"""
return self.setting(request, CONFIG.keys())
def list(self, request):
"""
返回所有待选设置项
"""
return self.setting(request, CONFIG.keys())
@action(methods=['GET', 'POST'], detail=False)
def site(self, request):
"""仅允许设置 网站标题、站点描述的接口"""
allow_settings = ['site_name', 'site_description']
return self.setting(request, allow_settings)
固定设置项在Admin中的顺序
为了防止每次打开设置界面设置选项错误,需要使用OrderedDict
来保证顺序:
from collections import OrderedDict
SITE_NAME = 'site_name'
SITE_DESCRIPTION = 'site_description'
CONSTANCE_CONFIG = OrderedDict([
(SITE_NAME, ('南京诗远启', '站点名称')),
(SITE_DESCRIPTION, ('南京诗远启', '站点描述')),
])
CONSTANCE_CONFIG_FIELDSETS = OrderedDict([
('站点设置', (SITE_NAME, SITE_DESCRIPTION)),
])
QA
出现没有表的情况
执行:
在makemigrations时就提示表不存在
INSTALLED_APPS
中加constance.backends.database
,删除使用到constance
的地方,makemigrations
之后再迁移。
修改权限'constance.change_config'
的名称后报错
constance
默认提供了一个权限'constance.change_config'
,但是当修改了该权限的默认权限名称后,会出现一下错误:
django.db.utils.IntegrityError: (1062, "Duplicate entry '2-change_config' for key 'auth_permission_content_type_id_codename_01ab37
5a_uniq'")
重新浏览代码后发现是在constance/apps.py
29行,写了:
permission, created = Permission.objects.using(using).get_or_create(
name='Can change config',
content_type=content_type,
codename='change_config')
将其修改为:
permission, created = Permission.objects.using(using).get_or_create(
content_type=content_type,
codename='change_config',
defaults={'name': 'Can change config'})
即可解决这个错误,详见issue。 该PR已提交,代码合并成功,在一个正式版本该问题将被解决。
makemigrations constance
一直不创建makemigrations
文件
pip install django-constance[database]
CONSTANCE_BACKEND = 'constance.backends.database.DatabaseBackend'
INSTALLED_APPS = (
# other apps
'constance.backends.database',
)
python manage.py migrate database
频繁查询、更新的设置项 使用Cache加快访问速度
# cache配置
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
'KEY_PREFIX': 'protal',
'options': {
'MAX_ENTRIES': 1024,
}
},
'memcache': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
'KEY_PREFIX': 'protal',
'options': {
'MAX_ENTRIES': 1024,
}
},
}
# 设置缓存
CONSTANCE_DATABASE_CACHE_BACKEND = 'memcache'
Illegal mix of collations for operation ' IN '
若在升级项目中遇到mysql报错
需要删除数据库,再次创建 create database database_name character set utf8
; 再次导入数据库即可。