Django中实现动态读取配置参数

2024-02-26 21:51:11 浏览数 (2)

django-environ这种方式在启动前比较适用,在django运行起来后,就无法修改配置了。

因此我们会考虑把一些后运行的代码的配置项写到动态配置里。

常见的有:

1、基于数据库的动态配置(例如MySQL等)

2、基于配置中心的动态配置(例如consul、nacos等)

下面的例子中,演示的是第一种,基于数据库的动态配置。

假设我们这个django项目的配置信息如下:

project为 demo, app为app01

app01/models.py 添加如下

代码语言:python代码运行次数:0复制
from django.contrib.contenttypes.models import ContentType
from django.db import models

class Configuration(models.Model):
    key = models.CharField(max_length=255, null=False, unique=True, blank=False)
    value = models.CharField(max_length=255, null=False, blank=False)
    status = models.CharField(max_length=16, default="ON", null=False, blank=False)
    update_time = models.DateField(auto_now=True, null=True, blank=True)

    @classmethod
    def get(cls, key, status, default=None):
        try:
            configuration = cls.objects.get(key=key, status=status)
            return configuration.value
        except Configuration.DoesNotExist:
            return default

    @classmethod
    def set(cls, key, status, value):
        try:
            configuration = cls.objects.get(key=key, status=status)
            configuration.value = value
            configuration.save()
        except Configuration.DoesNotExist:
            configuration = cls(key=key, value=value, status=status)
            configuration.save()

    class Meta:
        db_table = "configuration"
        verbose_name = "动态配置表"
        verbose_name_plural = "动态配置表"

app01/views.py 添加如下

代码语言:python代码运行次数:0复制
import json
from django.conf import settings
import demo.settings

# 基于数据库的动态参数配置DEMO
def test_dynamic_setting(request):
    # 只关注状态为ON的配置项,出现异常抛出错误,便于排查
    try:
        json.loads(Configuration.get("es_reader_rules", status="ON"))
    except Exception as e:
        print(str(e))
        return JsonResponse({"reason": "es_reader_rules 配置项格式错误"}, status=500)

    try:
        json.loads(Configuration.get("es_writer_rules", status="ON"))
    except Exception as e:
        print(str(e))
        return JsonResponse({"reason": "es_writer_rules 配置项格式错误"}, status=500)

    return JsonResponse(
        {
            "code": 0,
            "msg": "test",
            "es_reader_rules": json.loads(
                Configuration.get("es_reader_rules", status="ON")
            ),
            "es_writer_rules": json.loads(
                Configuration.get("es_writer_rules", status="ON")
            ),
        }
    )

app01/urls.py 添加如下:

代码语言:javascript复制
urlpatterns = [
    re_path(
        "test_dynamic_setting",
        views.test_dynamic_setting,
        name="test_dynamic_setting",
    ),
    # 下面其它的原先内容省略
    ]

demo/urls.py 添加如下:

代码语言:python代码运行次数:0复制
urlpatterns = [
    path("app01/", include("app01.urls")),
    # 下面其它的原先内容省略
]

将表结构应用到数据库,并启动django程序

代码语言:python代码运行次数:0复制
python.exe manage.py makemigrations app01
python.exe manage.py migrate
python.exe manage.py runserver

访问 http://127.0.0.1:8000/app01/test_dynamic_setting

未配置或者错误配置规则示例未配置或者错误配置规则示例

然后在数据库插入2条测试数据:

代码语言:sql复制
INSERT INTO configuration 
( `key`, `value`,`status`,`update_user`,`update_time` ) 
VALUES 
( 'es_reader_rules', '{"index_1":"es01:index_1","index_2":"es01:index_22"}','ON','SYSTEM',now() );

INSERT INTO configuration 
( `key`, `value`,`status`,`update_user` ,`update_time` ) 
VALUES 
( 'es_writer_rules', '{"index_1":"es01:index_new_1","index_2":"es02:index_2"}','ON', 'SYSTEM',now()  );

再次访问 http://127.0.0.1:8000/app01/test_dynamic_setting

可以看到结果正确加载出来了

正确配置的示例正确配置的示例

更深入的用法,待实践。

参考 https://geek-docs.com/django/django-questions/86_django_dynamic_settingspy.html

0 人点赞